【SpringCloud】SpringCloud Ribbon详解

前言

微服务中比如用户服务部署多台服务器,怎么调用其中某一服务呢?
Spring Cloud最新面试题
Spring Cloud Nacos详解之注册中心
Spring Cloud Nacos详解之配置中心
Spring Cloud Nacos详解之集群配置
Spring Cloud Eureka详解
Spring Cloud Frign详解
Spring Cloud Gateway详解
Spring Cloud Hystrix详解

SpringCloud Ribbon 负载均衡

SpringCloud Feign 远程调用实战

一.逻辑图

假设现在用户服务部署在两台或者多台服务器上,订单用户怎么去访问某一个?
注意: 因为负载均衡都是服务消费者调用服务提供者然后进行负载均衡,所以配置和业务编写,都在服务消费者里面。
在这里插入图片描述

二.RestTemplate远程调用配置负载均衡

1.修改远程调用用户的代码

	@Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
    
    
        // 根据订单id查询订单
        Order order = orderMapper.findById(orderId);
        // 利用RestTemplate发起http请求,根据用户id查询用户
        // 把localhost改为服务名称
 这里这里  String url = "http://userservice/user/" + order.getUserId();
        //String url = "http://localhost:8081/user/" + order.getUserId();
        // 发送http请求,实现远程调用,现在是get请求类型
        User user = restTemplate.getForObject(url, User.class);
        // 封装user到Order
        order.setUser(user);
        // 返回值
        return order;
    }

注意: Feign集成了Ribbon,不用去特别配置负载均衡。
2.RestTemplate配置类加上注解

	 /**
     * 创建RestTemplate并注入Spring容器
     */
    @Bean
    @LoadBalanced //负载均衡注解
    public RestTemplate restTemplate() {
    
    
        return new RestTemplate();
    }

三.Ribbon实现负载均衡的原理

Ctrl + N 快速查找类:原理是 LoadBalancerInterceptor 实现了 ClientHttpRequestInterceptor 接口。


客户端http请求拦截器

@FunctionalInterface
public interface ClientHttpRequestInterceptor {
    
    
    ClientHttpResponse intercept(HttpRequest var1, byte[] var2, ClientHttpRequestExecution var3) throws IOException;
}
 
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
    
    

	重写ClientHttpRequestInterceptor接口的方法
	@Override
	public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,final ClientHttpRequestExecution execution) throws IOException {
    
    
		// 1.获取http的请求地址
		final URI originalUri = request.getURI();
		
		// 2.获取服务的名称
		String serviceName = originalUri.getHost();
		
		Assert.state(serviceName != null,"Request URI does not contain a valid hostname: " + originalUri);
		
		//3.我们进去execute方法:就是为了从Eureka-Server拉取信息
		return this.loadBalancer.execute(serviceName,this.requestFactory.createRequest(request, body, execution));
	}
}
public class RibbonLoadBalancerClient implements LoadBalancerClient {
    
    
	//4.进入此方法
	public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {
    
    
		//调用下面的execute方法
        return this.execute(serviceId, (LoadBalancerRequest)request, (Object)null);
    }

	public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {
    
    
		
		//5.根据服务名称获取对应的服务列表,loadBalancer里面有List存有服务的地址
        ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);
       
        //6.根据算法选择要使用的服务,会进入IRule接口里面,默认是轮询算法
        Server server = this.getServer(loadBalancer, hint);
       
        if (server == null) {
    
    
            throw new IllegalStateException("No instances available for " + serviceId);
        } else {
    
    
            RibbonLoadBalancerClient.RibbonServer ribbonServer = new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));
            return this.execute(serviceId, (ServiceInstance)ribbonServer, (LoadBalancerRequest)request);
        }
    }
}

在这里插入图片描述

四.Ribbon负载均衡策略

Ribbon负载均衡策略是 IRule接口定义的,每一个子接口都是一种策略。下面是常见负载均衡算法

1.负载均衡种类

负载均衡类 规则
RoundRobinRule 轮询选择服务器。Ribbon默认负载均衡算法。
AvailabilitvFilteringRule (1) 默认情况,服务器连接3次失败,服务器设置为短路状态。短路状态持续30秒,如果再连接失败,短路状态持续时间就会几何级增长。      (2)并发数高的服务器。可配置该规则会忽略并发数高的服务器。并发数上限可以配置。
WeightedResponseTimeRule 给服务器赋予权重。响应时间越长,权重越小。权重影响服务器的选择。
ZoneAvoidanceRule 使用Zone对服务器进行分类。Zone可以是一个机房、一个机架等。然后对Zone内的服务进行轮询。例如:配置Zone是曹县机房,然后服务提供者会优先选择曹县机房的服务器。
BestAvailableRule 忽略短路的服务器并选择并发数低的服务器。
RandomRule 随机选择一个可用服务器。
RetryRule 重试机制的选择逻辑。

2.配置负载均衡

(1) 代码类型

	注意:这种配置是全局的,订单服务不光调用用户服务是随机的,调用其他的服务也是随机的
	//注入新的负载均衡算法 在启动类内注入也可以自定义配置类
  	@Bean
    public IRule randomRule() {
    
    
    	//随机选取一个可用服务器
        return new RandomRule();
    }

(2) yml中配置

注意:这种局部配置,只针对用户服务去选择负载均衡的算法
userservice:  # 服务名称
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.RandomRule  # 负载均衡规则

五.Ribbon的饥饿加载配置

Ribbon默认是懒加载: 第一次加载才会创建 LoadBalancerClient ,请求时间会很长。
饥饿加载: 在项目启动时创建,降低第一次访问的耗时。

(1) 单个服务配置饥饿加载(在yml文件配置)

ribbon:
  eager-load:
    enabled: true # 开启饥饿加载
    clients: userservice # 指定饥饿加载的服务名称

(1) 多个服务配置饥饿加载(在yml文件配置)

ribbon:
  eager-load:
    enabled: true # 开启饥饿加载
    clients: # 指定饥饿加载的服务名称
      - userservice   # 用户服务
      - cangkuservice # 仓库服务
      - zhifuservice  # 支付服务

猜你喜欢

转载自blog.csdn.net/twotwo22222/article/details/129337821