EE颠覆者12章,cloud项目实战,docker部署

简介

微服务: Microservice

使用定义好边界的 小的 独立组件 来做好 一件事情。

Spring Cloud 开发的程序,docker 或其他Pass(平台即是服务,如:Coud Foundry)部署。称作:原生云应用。

@EnableConfigServer

@EnableEurekaServer
@EnableEurekaClient

@EnableZuulProxy

@FeignClient RestTemplate

@EnableCircuitBreaker 断路器
@HystrixCommand 指定后备方法

@Enable Hystrix Dashboard 

实战

pom

<project>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wisely</groupId>
    <artifactId>ch12</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0-SNAPSHOT</version>
    <name>Cloud Native App</name>

    <modules> 指名子项目
        <module>config</module> 为person 和 some 提供配置
        <module>discovery</module> eureka server
        <module>ui</module> 网关, feign 消费 person。Ribbon消费 some服务
        <module>person</module> 提供保存的 rest服务
		<module>some</module> 返回一串制服馆
        <module>monitor</module> 断路器
    </modules>

    <parent> 公共的父类
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-parent</artifactId>
        <version>Angel.SR3</version>  最新是 H版本 sr3
        <relativePath/>
    </parent>

    <properties> 
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId> web支持
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId> 监控支持
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId> 测试支持
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId> 插件支持
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>com.spotify</groupId>
                    <artifactId>docker-maven-plugin</artifactId> docker支持
                    <version>0.2.9</version>
                    <configuration>
                        <skipDockerBuild>true</skipDockerBuild>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
    
</project>

eureka

<?xml version="1.0" encoding="UTF-8"?>
<project >
    <modelVersion>4.0.0</modelVersion>

    <artifactId>discovery</artifactId>
    <packaging>jar</packaging>

    <name>discovery</name>
    <description>Discovery App</description>

    <parent>
        <groupId>com.wisely</groupId>
        <artifactId>ch12</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <properties>
        <start-class>com.wisely.discovery.DiscoveryApplication</start-class>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>  啥用?
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId> server
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <configuration>
                    <imageName>${project.name}:${project.version}</imageName>
                    <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
                    <skipDockerBuild>false</skipDockerBuild>
                    <resources>
                        <resource>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
@EnableEurekaServer //1

server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false #不需要注册到其他微服务
    fetch-registry: false #不需要拉取配置

配置中心

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
    </dependencies>
@SpringBootApplication
@EnableConfigServer //1 开启配置中心
@EnableEurekaClient //2 是个客户端

bootstrap.yml

bootstrap.yml负责从外部加在属性配置,优先级更高


spring:
  application:
    name: config #1 在eureka上名字是 config
  profiles:
    active: native #2 使用本地配置,默认的是git 
    
eureka:
  instance:
    non-secure-port: ${server.port:8888} #3 非ssl端口,如果有就使用。默认8888
    metadata-map:
      instanceId: ${spring.application.name}:${random.value} #4 配置在eureka server上实例ID
  client:
    service-url:
      defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/ #5 server地址

application.yml

spring:
  cloud:
    config:
      server:
        native:
          search-locations: classpath:/config #1

server:
  port: 8888

配置其他项目

src/main/resources/config/person.yml

spring:
  jpa:
    database: HSQL 

person-docker.yml

spring:
  jpa:
    database: POSTGRESQL
  datasource:
    platform: postgres
    url: jdbc:postgresql://postgres:5432/postgres
    username: postgres
    password: postgres
    driver-class-name: org.postgresql.Driver

some.yml

my:
  message: Message from Development

some-docker.yml

my:
  message: Message from Production

应用名+profile.yml

服务模块 1

开发环境用 hsqldb,生产环境用 postgreSQL

PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS

HSQLDB(HyperSQL DataBase)是一个开放源代码的JAVA数据库,其具有标准的SQL语法和JAVA接口

xml

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId> config 客户端
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId> eureka客户端
        </dependency>
        	<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId> jsp
		</dependency>
		<dependency>
			<groupId>org.hsqldb</groupId>
			<artifactId>hsqldb</artifactId> hsqldb
		</dependency>
		<dependency>
			<groupId>postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<version>9.1-901-1.jdbc4</version>
		</dependency>
    </dependencies>

代码

@SpringBootApplication
@EnableEurekaClient

@Entity
public class Person {
	@Id
	@GeneratedValue
	private Long id;
	
	private String name;
	}


public interface PersonRepository extends JpaRepository<Person, Long>{
}


@RestController
public class PersonController {
    @Autowired
    PersonRepository personRepository;

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public List<Person> savePerson(@RequestBody String  personName) {
    	Person p = new Person(personName);
    	personRepository.save(p);
    	List<Person> people = personRepository.findAll(new PageRequest(0, 10)).getContent();
        return people;
    }
}


bootstrap.yml

spring:
  application:
    name: person
  cloud:
    config:
      enabled: true
      discovery:
        enabled: true
        service-id: CONFIG #1
eureka:
  instance:
    non-secure-port: ${server.port:8082}
  client:
    service-url:
      defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/

开发环境下 使用 配置中心的 person.yml

docker 环境 使用 person-docker.yml

application.yml

server:
  port: 8082
 

spring:
  jpa:
    hibernate:
      ddl-auto: update

服务模块 2

pom.xml

<dependencies>
            <artifactId>spring-cloud-starter</artifactId> 
            <artifactId>spring-cloud-config-client</artifactId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
</dependencies>
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class SomeApplication {
	 @Value("${my.message}") //1
	 private String message; 
	
	 @RequestMapping(value = "/getsome")
	 public String getsome(){
		 return message;
	 }
	 }

配置文件

application.yml
server:
  port: 8083
  
bootstrap.yml
spring:
  application:
    name: some
eureka:
  instance:
    non-secure-port: ${server.port:8083}
    其他都和 模块1 一致
    

开发读取 some.yml,docker读取 some-docker.yml

UI (Ribbon Feign)

pom.xml

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId> start
        </dependency>

    
        <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-zuul</artifactId> zuul
		</dependency>
    
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId> config
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId> eureka
        </dependency>
    
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId> feign
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId> ribbon
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId> hystrix
        </dependency>
      
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId> bootstrap
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>angularjs</artifactId> angularjs
            <version>1.3.15</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>angular-ui-router</artifactId> angular-ui
            <version>0.2.13</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId> jquery
        </dependency>
    </dependencies>

代码

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //1 feign
@EnableCircuitBreaker //2 断路器
@EnableZuulProxy //3 网关
public class UiApplication {}
public class Person {
	private Long id;
	private String name;
}

@FeignClient("person") //指名请求的是 person 服务
public interface PersonService {
	 @RequestMapping(method = RequestMethod.POST, value = "/save",
	            produces = MediaType.APPLICATION_JSON_VALUE,
			 	consumes = MediaType.APPLICATION_JSON_VALUE)
	    @ResponseBody List<Person> save(@RequestBody String  name);
} # 提供者 和 消费者 都是 json 。 对象服务模块1

使用:

@Service
public class PersonHystrixService {

	@Autowired
	PersonService personService; 

	@HystrixCommand(fallbackMethod = "fallbackSave") //1 指定断路器
	public List<Person> save(String name) {
		return personService.save(name);
	}
	
	public List<Person> fallbackSave(String name){ 
		List<Person> list = new ArrayList<>();
		Person p = new Person(name+"没有保存成功,Person Service 故障");
		list.add(p);
		return list;
	}
}

服务模块2,直接用 restTemplate请求了。 不需要service

@Service
public class SomeHystrixService {

	@Autowired
	RestTemplate restTemplate; //1 注入 restTemplate即是 ribbon

	@HystrixCommand(fallbackMethod = "fallbackSome") //2 指定回退
	public String getSome() {
		return restTemplate.getForObject("http://some/getsome", String.class); //发请求
	}
	
	public String fallbackSome(){ 
		return "some service模块故障";
	}
}
application.yml
server:
  port: 80
  
bootstrap.yml  
spring:
  application:
    name: ui
eureka:
  instance:
    non-secure-port: ${server.port:80}
  client:
    service-url:
      defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/

@RestController
public class UiController {
	@Autowired
	private SomeHystrixService someHystrixService;
	
	@Autowired
	private PersonHystrixService personHystrixService;

	@RequestMapping("/dispatch")
	public List<Person> sendMessage(@RequestBody String personName) {
		return personHystrixService.save(personName);
	}
	
	@RequestMapping(value = "/getsome",produces={MediaType.TEXT_PLAIN_VALUE})
	public String getSome(){
		return someHystrixService.getSome();
	}
}

断路器监控 Monitor (DashBoard)

pom

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-turbine</artifactId>
        </dependency>
    </dependencies>

代码:

@SpringBootApplication  
@EnableEurekaClient 客户端
@EnableHystrixDashboard 断路器
@EnableTurbine 
public class MonitorApplication {}
server:
  port: 8989

bootstrap.yml
spring:
  application:
    name: monitor

eureka:
  instance:
    nonSecurePort: ${server.port:8989}
http://localhost:8098/
http://localhost:8098/#/some 
访问:
http://localhost:8989/hystrix.stream
输入:
http://localhost:8098/hystrix.stream 请求地址

Docker 部署

文件编写

src/main/docker/runboot.sh #新建目录

sleep 10
java -Djava.security.egd=file:/dev/./urandom -jar /app/app.jar

src/main/docker/Dockerfile

FROM java:8 #使用 java:8 运行
VOLUME /tmp #挂载点
RUN mkdir /app #创建目录
ADD config-1.0.0-SNAPSHOT.jar /app/app.jar #把项目,添加到 app目录
ADD runboot.sh /app/ #运行这个sh文件
RUN bash -c 'touch /app/app.jar' #创建这个文件
WORKDIR /app
RUN chmod a+x runboot.sh #给这个文件加上执行权限
EXPOSE 8888 #不同的服务需要修改成不同的端口
CMD /app/runboot.sh #执行

docker 的 maven插件

所有的程序都要增加这个

<build>
        <plugins>
            <plugin>
                <groupId>com.spotify</groupId> #公司
                <artifactId>docker-maven-plugin</artifactId> #插件名
                <configuration>
                    <imageName>${project.name}:${project.version}</imageName> #项目名 版本
                    <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
                    <skipDockerBuild>false</skipDockerBuild> #docker文件位置。不保持
                    <resources>
                        <resource>
                            <directory>${project.build.directory}</directory> #在项目构建目录
                            <include>${project.build.finalName}.jar</include> #项目构建的最终名字
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        </plugins>
    </build>

默认把镜像编译到本地,如果远程服务器。

在本地配置 环境变量 DOCKER_HOST 值为:tcp://localhost:2375

#编译 并且放入docker镜像

mvn clean package docker:build -DshkipTests

Docker Compose

curl -L https://get.daocloud.io/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose
其他链接不可用
postgresdb:
  image: busybox
  volumes:
    - /var/lib/postgresql/data
    
postgres:
  name: postgres
  image: postgres
  hostname: postgres
  volumes_from:
    - postgresdb
#  ports: 
#   - "5432:5432"
  environment:
    - POSTGRES_USER=postgres  #给容器使用的变量,在容器中使用 ${}使用
    - POSTGRES_PASSWORD=postgres

discovery:
  image: "discovery:1.0.0-SNAPSHOT"
  hostname: discovery
  name: discovery
  ports:
   - "8761:8761" #将我门需要的端口,映射出来

config:
  image: "config:1.0.0-SNAPSHOT"
  hostname: config
  name: config
  links:
    - discovery  #当前容器链接的依赖
  environment:
     EUREKA_HOST: discovery
     EUREKA_PORT: 8761
#  ports:
#    - "8888:8888"

person:
  image: person:1.0.0-SNAPSHOT
  hostname: person
  links:
    - discovery
    - config
    - postgres
  environment:
     EUREKA_HOST: discovery
     EUREKA_PORT: 8761
     SPRING_PROFILES_ACTIVE: docker
#  ports:
#    - "8082:8082"
    
some:
  image: some:1.0.0-SNAPSHOT
  hostname: some
  links:
    - discovery
    - config
  environment:
     EUREKA_HOST: discovery
     EUREKA_PORT: 8761
     SPRING_PROFILES_ACTIVE: docker
#  ports:
#    - "8083:8083"

ui:
  image: ui:1.0.0-SNAPSHOT
  hostname: ui
  links:
    - discovery
    - config
    - person
    - some
  environment:
     EUREKA_HOST: discovery
     EUREKA_PORT: 8761
     SPRING_PROFILES_ACTIVE: docker
  ports:
    - "80:80"

monitor:
  image: monitor:1.0.0-SNAPSHOT
  hostname: monitor
  links:
    - discovery
    - config
    - person
    - some
    - ui
  environment:
     EUREKA_HOST: discovery
     EUREKA_PORT: 8761
     SPRING_PROFILES_ACTIVE: docker
#  ports:
#    - "8989:8989"

docker-compose up -d 哎,我忘记应该放在那里了

JHipster 代码生成器,用来生成基于 spring boot 和 angularJs项目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值