在分布式环境中,需要充分考虑发生故障的情况,在生产环境中必须要高可用的部署。
上一篇文章中,eureka server是单一的服务,所以不需要注册自己,但在集群环境中,需要eureka server相互注册,所以下面2项要注意了
# 关闭自己注册自己
eureka.client.register-with-eureka=false
# 不需要检索服务
eureka.client.fetch-registry=false
在eureka server里增加2个配置文件:application-peer1,application-peer2如下
application-peer1.properties 建议使用域名,就要先修改hosts文件。
spring.application.name=eureka-server
server.port=1111
eureka.instance.hostname=peer1
eureka.client.serviceUrl.defaultZone=http://peer2:1112/eureka/
application-peer2.properties
spring.application.name=eureka-server
server.port=1112
eureka.instance.hostname=peer2
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/
请注意了,这2个配置文件是相互注册的,你中有我,我中有你。
下面启动2个eureka server:
java -jar eureka-server.jar --spring.profiles.active=peer1
java -jar eureka-server.jar --spring.profiles.active=peer2
启动服务,可以查看控台:http://peer1:1111/和http://peer2:1112/
可以在
registered-replicas
看到都相互注册了,available-replicas
可用分片中可以看到相应的节点,停止一个另一个还可以工作,如下图:
关闭一个server后,如上图有一个DOWN,若关闭保护模式,一会这个服务将会被清除掉。
若available-replicas没有相应节点,则是因为eureka.client.register-with-eureka/eureka.client.fetch-registry为false,可以把application.properties中改为true,或在peer配置文件中改为true,默认就为true。
上面即实现了注册中心的高可用,下面提供服务给注册中心。
跟上一章中构建服务一样,创建一个服务后打包生成jar,然后启动服务并注册到所有注册中心上。
# 高可用
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer1:1111/eureka/
启动多个服务
java -jar eureka-client.jar --server.port=8081
java -jar eureka-client.jar --server.port=8082
启动后,刷新peer1/peer2控制台,可以看到2个服务,也可以调用服务测试接口http://desktop-7brumlo:8081/hello
有了高可用注册中心,也提供了服务,接下来是消费服务了。
下面通过ribbon消费服务提供者,可通过日志查看ribbon的负载均衡状态。
创建一个gradle工程,配置文件如下:
dependencyManagement {
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Edgware.SR4'
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-actuator')
compile 'org.slf4j:slf4j-api:1.7.14'
compile('org.springframework.cloud:spring-cloud-starter-hystrix')
compile('org.springframework.cloud:spring-cloud-starter-eureka')
compile('org.springframework.cloud:spring-cloud-starter-ribbon')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
application.properties文件如下:
spring.application.name=ribbon-consumer
server.port=9000
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer1:1111/eureka/
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000
上面配置了熔断的时间间隔为2000毫秒。
在启动类上添加超时熔断标签,如下:
@EnableCircuitBreaker //超时熔断
@EnableDiscoveryClient
@SpringBootApplication
public class CloudApplication {
@Bean
@LoadBalanced //请求时拥有客户端负载均衡的能力
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(CloudApplication.class, args);
}
}
创建消费controller,如下:
@RestController
public class ConsumerController {
@Autowired
HelloService helloService;
@GetMapping(value = "/ribbon-consumer")
public String helloConsumer() {
return helloService.hello();
}
}
最后创建service,调用要消费的服务,如下:
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "helloFallback", commandKey = "helloKey")
public String hello() {
StringBuilder result = new StringBuilder();
// GET
result.append(restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody()).append("
");
result.append(restTemplate.getForEntity("http://HELLO-SERVICE/hello1?name={1}", String.class, "didi").getBody()).append("
");
return result.toString();
启动消费服务后,消费服务http://localhost:9000/ribbon-consumer
,可以看到以下日志
DynamicServerListLoadBalancer for client HELLO-SERVICE initialized: DynamicServerListLoadBalancer:
{NFLoadBalancer:name=HELLO-SERVICE,current list of Servers=[DESKTOP-7BRUMLO:8082, DESKTOP-7BRUMLO:8081],
Load balancer stats=Zone stats: {
defaultzone=[Zone:defaultzone; Instance count:2;
Active connections count: 0; Circuit breaker tripped count: 0;
Active connections per server: 0.0;]
日志上可以看到ribbon客户端维护的SERVICE的服务列表,就按此信息轮询访问,以实现基于客户端的负载均衡。
若停掉一个服务,可以看到ribbon会启动熔断机制,过一会后就可以正常访问了,所有请求落到另一个服务上;若2个服务都正常,可以观察服务输出日志是按轮询方式输出的。
学习交流,请加群:64691032