引言
Ribbon提供软负载均衡的能力,此外还具有容错,多传输协议,缓存及批处理能力
Ribbon是一个负载均衡组件,可以让服务消费者具有负载均衡的能力,去选择与哪个服务提供者进行通讯。
上图中,user和order分别是服务消费者和服务提供者,user集成了Ribbon组件,具有被负载均衡能力,可以按规则去请求order的某个实例。
不使用Ribbon实现简单的随机负载均衡算法(节选代码片段)
List<ServiceInstance> instances = discoveryClient.getInstances("hrsp-order");
List<String> targetURLs = instances.stream()
.map(instance -> instance.getUri().toString() + "/orders/{id}")
.collect(Collectors.toList());
int i = ThreadLocalRandom.current().nextInt(targetURLs.size());
String targetURL = targetURLs.get(i);
log.info("请求的目标地址: [{}]", targetURL);
VendorDTO vendorDTO = restTemplate.getForObject(targetURL, VendorDTO.class, vendId);
先从注册中心获取某服务的实例列表,然后从列表中随机选中一个url访问。
上面这段代码比较累赘,使用了Ribbon之后,代码会变得非常简洁。
使用Ribbon
-
引入Ribbon依赖
如果已经使用nacos作为注册中心,在引入nacos-discovery的同时就已经引入了ribbon,那这步操作可以忽略。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <version>2.2.1.RELEASE</version> </dependency>
-
添加注解
在RestTemplate类上加入@LoadBalanced注解
-
编辑代码
VendorDTO vendorDTO = restTemplate.getForObject( "http://hrsp-order/orders/{id}", VendorDTO.class, vendId);
这段代码可直接等价于之前不使用Ribbon时实现的代码。
自定义Ribbon配置(Java代码配置方式)
注意:自定义的配置类不能被@ComponentScan扫描到,即不要放在@SpringBootApplication应用主类的包或其子包之内,类似Spring和SpringMVC父子上下文不要被重复扫描到(会引起事务问题)。
下面这段代码保存在应用主类可以扫描到的包中,例如configuration包。其中的RibbonConfiguration
类不应该被主类扫描到,设置其IRule
规则为随机。
@Configuration
@RibbonClient(name = "hrsp-order", configuration = RibbonConfiguration.class)
public class BastoneRibbonConfiguration {
}
@Configuration
public class RibbonConfiguration {
@Bean
public IRule ribbonRule() {
return new RandomRule();
}
}
自定义Ribbon配置(属性配置方式)
hrsp-order.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
Ribbon全局配置
调用所有微服务都采用这种负载均衡方式
@Configuration
@RibbonClients(defaultConfiguration = RibbonConfiguration.class)
public class OrderRibbonConfiguration {
}
饥饿加载
Ribbon默认使用懒加载,第一次调用的时间比较长。可以在配置文件中加入以下配置取消懒加载。
# 开启ribbon的饥饿加载
ribbon.eager-load.enabled=true
# 指定饥饿加载的调用服务
ribbon.eager-load.clients=hrsp-order
支持nacos权重
nacos client内置了基于权重的负载均衡算法,可自定义类继承或实现Ribon的负载均衡规则类,并引入nacosDiscoveryProperties,在nacos控制台界面上配置服务提供者的权重值。