将要搭建的负载均衡架构图如下
工程说明
spring-cloud-02-ribbon-retry 模拟客服端,请求服务 ,RestTemplate+LoadBalanced 实现负载均衡
spring-cloud-02-ribbon-eureka 作为服务发现,管理所有服务
spring-cloud-02-ribbon-client-01 / spring-cloud-ribbon-client-02 作为集群服务,协调处理请求
负载均衡策略常用的几种
简单轮询负载均衡(RoundRobin)
随机负载均衡 (Random)
加权响应时间负载均衡 (WeightedResponseTime)
区域感知轮询负载均衡(ZoneAware)
选择一个最小的并发请求BestAvailableRule
工程spring-cloud-02-ribbon-eureka 同上一篇,不做解释
spring-cloud-02-ribbon-client-01 配置如下
spring: application: name: client-service server: port: 7002 context-path: / eureka: client: service-url: defaultZone: http://localhost:8001/eureka/
@RestController public class IndexController { @RequestMapping(value = "/retry") public String retry() throws InterruptedException { System.err.println("------- client 01--- "); return "------- client 01--- " ; } }
/ spring-cloud-ribbon-client-02配置如下
spring: application: name: client-service server: port: 7001 context-path: / eureka: client: service-url: defaultZone: http://localhost:8001/eureka/
@RestController public class IndexController { @RequestMapping(value = "/retry") public String retry() throws InterruptedException { System.err.println("------- client 02--- "); Thread.sleep(5000); return "------- client 02--- " ; } }
注意:client2服务睡眠了5秒后才有相应
并且全部启动服务
@SpringBootApplication @EnableDiscoveryClient public class ClientApplication { public static void main(String[] args) { SpringApplication.run(ClientApplication.class, args); } }
工程spring-cloud-02-ribbon-retry pom导入ribbon Jar包
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> </dependencies>
配置类
spring: application: name: retry-service cloud: loadbalancer: retry: enabled: true #启动重试机制 server: port: 7004 context-path: / eureka: client: service-url: defaultZone: http://localhost:8001/eureka/ #启动断路器 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 10000 custom: rest: connect-timeout: 1000 connection-request-timeout: 1000 read-timeout: 3000 client-service: ribbon: OkToRetryOnAllOperations: true # 是否对所有请求都进行重试 MaxAutoRetriesNextServer: 2 #重试切换实例次数 MaxAutoRetries: 1 #重试次数
配置负载均衡RestTemplate
@SpringBootApplication @EnableRetry @EnableDiscoveryClient public class RetryApplication { @Bean @ConfigurationProperties(prefix = "custom.rest") public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory(){ HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory=new HttpComponentsClientHttpRequestFactory(); return httpComponentsClientHttpRequestFactory; } @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(httpComponentsClientHttpRequestFactory()); } public static void main(String[] args) { SpringApplication.run(RetryApplication.class, args); } }
RetryController
@RestController public class RetryController { @Autowired private RestTemplate restTemplate; @RequestMapping(value = "retry") public String retry() throws InterruptedException { ResponseEntity<String> result=restTemplate.getForEntity("http://client-service/retry",String.class); System.err.println("------------ "+ result + "--------------------"); return "------- result"+result+"--- " ; } }
代码解释:
1:访问 retryController/retry ,通过服务发现找到对应的服务client1/client 的retry服务
2:retry 配置 read-timeout: 3000 ,如果调用服务超过3秒,会进行服务重试,重试次数1次,如果还是失败,服务进行切换实例,重新重试
3:通过resstTemplate 负载均衡轮询调用
4:调用client1 ,没有睡眠,立马返回,服务不超时
5:调用client2,服务睡眠5秒,查过超时时间3秒,会进行重试,重试一次,还是失败,会进行实例切换,调用服务1,正常返回
截图一:服务发现中心
截图二 访问服务返回结果 为client01
截图三:重试服务client2两次
截图四: 切换实例到client1,并返回最终结果