为了提高服务稳定性和服务能力,相同的微服务可能会配置运行多个副本,这些微服务同时提供同等服务,这里要解决的是如何实现负载均衡,随机地访问其中某个微服务,再就是某个微服务宕机时,需要熔断,就是不再分配任务到这个服务器,但恢复服务后又给它分配任务,spring的方案是 ribbon(负载均衡)+ hystrix(熔断)配合使用。
这里要测试这个功能,需要至少四台服务器,一个是eureka 注册中心,reibbon需要它来发现备选服务器列表,二是有两台相同功能的微服务提供者,这两台可以分布在两个ip上,或一个ip的两个端口上,但注册到eureka的应用名要相同,三是一台ribbon+ hystrix功能的服务消费者。
下面介绍这个ribbon+hystrix的配置,主要参考https://blog.csdn.net/wcblog/article/details/80251226 及其他文章,再抄集理解测试通过。
1. pom.xml 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
2. application.properties
server.port: 8803
spring.application.name=MicroserviceRibbonHystrix8803
spring.cloud.discovery.enabled=true
eureka.client.serviceUrl.defaultZone=http://admin:123@centos7.linbsoft.com:8101/eureka/,http://admin:123@microservice1.linbsoft.com:8102/eureka/
3. 启动类 MicroserviceRibbonHystrix8803Application
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class MicroserviceRibbonHystrix8803Application {
public static void main(String[] args) {
SpringApplication.run(MicroserviceRibbonHystrix8803Application.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
}
在这里定义restTemplate为具有LoadBalanced负载均衡注解。restTemplate是一个发起rest访问请求功能的模板。
4.发起ribbon访问的类
@RestController
public class UserManagementRibbonClient {
@Autowired
RestTemplate restTemplate;
@Value("${server.port}")
String port;
@GetMapping("/listUsersByRibbon")
@HystrixCommand(fallbackMethod="listUsersByRibbonFallback")
public String listUsersByRibbon(){
// MicroserviceServerA8801 是提供同类服务的多个应用的同名eureka注册名称
String result = this.restTemplate.getForObject("http://MicroserviceServerA8801/listusers", String.class);
return result;
}
public String listUsersByRibbonFallback(){
return "listUsersByRibbon异常,端口:" + port;
}
}
其中 @HystrixCommand(fallbackMethod="listUsersByRibbonFallback") 指定访问超时(时间可在配置文件设置),执行listUsersByRibbonFallback并发起熔断,ribbon不再指向这个熔断的服务器,但服务恢复一段时间后,会自动再加入服务列表。
上图显示两个同名的服务提供者MicroserviceServerA8801,启动一个8801端口副本后修改端口为8802,再启动。
5.访问测试,分别测试两个服务提供者都启动,停止其中一个,停止两个,再启动一个,看访问8803端口的不同响应。
其中服务提供者简单返回字符串
@RestController
public class listUsers {
@Value("${server.port}")
String port;
@RequestMapping("/listusers")
public String listusersmain() {
return "服务器端口:" + port + " | users[{'id':'1',name':'张三'},{'id':'2',name':'李四'},{'id':'3',name':'王五'}]";
}
}
结果:轮询两个服务器,并识别宕机。