ribbon负责实现服务的负载均衡。
Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign
ribbon简单使用如下:
1、引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
2、在springboot中注入一个RestTemplate,增加@LoadBalanced注解
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
3、调用方式
在需要调用服务的地方注入一个RestTemplate。在url处写服务ID就可以,ribbon会帮我们解析成IP与端口地址。
@RequestMapping("{userId}")
public String getAll2(@PathVariable("userId") String id) {
String url = "http://search-service/"+id;
System.out.println(url);
return restTemplate.getForObject(url, String.class);;
}
4、@LoadBalanced注解会自动实现负载均衡和服务的IP端口解析源码追踪如下:
ribbon之所以能实现这些功能主要依靠的是LoadBalancer的拦截器。查看LoadBalancerInterceptor类
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
private LoadBalancerClient loadBalancer;
private LoadBalancerRequestFactory requestFactory;
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) {
this.loadBalancer = loadBalancer;
this.requestFactory = requestFactory;
}
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
// for backwards compatibility
this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
}
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
final URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));
}
}
进入execute方法,在originalUri.getHost();之后会负载均衡选择出对应的服务和端口IP。默认ribbon的负载均衡策略是
IRule DEFAULT_RULE = new RoundRobinRule();是一种线性负载均衡策略,是一种轮询的方式,通过计数器与模的计算选择服务。
当然可以更改成其他的策略
在配置文件中配置即可
service-name: #服务name
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #更改为随机的策略