您的位置:首页 > 编程语言 > Java开发

四、SpringCloud Ribbon负载均衡

2019-06-30 21:45 555 查看

一、Ribbon负载均衡策略

在服务消费者(user-consumer)的启动类中的

RestTemplate
类加上
@LoadBalanced
注解

@SpringBootApplication
@EnableDiscoveryClient
public class UserConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(UserConsumerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
}

修改dao,通过服务名称来获取服务提供者的ip和端口

@Component
public class UserDao {

@Autowired
private RestTemplate restTemplate;

public User findUserById(Integer id) {
String url = "http://user-service/user/findUser/" + id;
return this.restTemplate.getForObject(url, User.class);
}
}

复制当前服务提供者,修改端口号为8083,同时启动两个服务提供者:

源码跟踪:发送请求http://localhost:8082/user/findUsers?ids=1,2,3,4,在

LoadBalancerInterceptor
类中打断点



进入
getServer()
方法:

进入
chooseServer
方法,在下面调用了父类的
chooseServer()
方法


进入父类:
BaseLoadBalancer
,其
chooseServer()
方法如下


在该类中定义的

rule
,可以看出使用的是一个
new RoundRobinRule();
的对象

RoundRobinRule
该类里面就定义的负载均衡的策略,可以看出默认使用的就是轮询的策略

通过测试类测试:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = UserConsumerApplication.class)
public class LoadBalanceTest {

@Autowired
private RibbonLoadBalancerClient client;

@Test
public void testLoadBalance(){
for (int i = 0; i < 15; i++) {
4000

ServiceInstance instance = this.client.choose("user-service");
System.out.println(instance.getHost() + ":" +instance.getPort());
}
}
}

查看打印:

从打印结果中可以看出确实是使用轮询的策略,服务消费者交替从两个服务提供者获取数据
修改负载均衡的策略为随机选取

server:
port: 8082
spring:
application:
name: user-consumer
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka
fetch-registry: true #拉取Eureka Server服务的列表只读备份,然后缓存在本地
registry-fetch-interval-seconds: 5 #每隔5秒重新拉取并更新数据,生产环境30
user-service:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

再次执行测试方法,获取20次,打印如下:

二、Ribbon的重试机制

添加依赖

<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>

添加配置

server:
port: 8082
spring:
application:
name: user-consumer
cloud:
loadbalancer:
retry:
enabled: true # 开启重试
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka
fetch-registry: true #拉取Eureka Server服务的列表只读备份,然后缓存在本地
registry-fetch-interval-seconds: 5 #每隔5秒重新拉取并更新数据,生产环境30
user-service:
ribbon:
ConnectTimeout: 250 # Ribbon的连接超时时间 ms
ReadTimeout: 1000 # Ribbon的数据读取超时时间
OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
MaxAutoRetries: 1 # 对当前实例的重试次数
logging:
level:
org.springframework: debug
com.liaoxiang: debug

同时开启两个服务提供者,然后停掉一个之后通过服务消费者访问查看日志:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: