其他分享
首页 > 其他分享> > 【SpringCloud】<微服务>Ribbon负载均衡

【SpringCloud】<微服务>Ribbon负载均衡

作者:互联网

 目录

一、负载均衡原理:

负载均衡流程:

LoadBalancerInterceptor:

LoadBalancerClient: 

负载均衡策略IRule :

完整流程: 

二、负载均衡策略:

三、自定义负载均衡策略:

1.方式一:Bean组件

2.方式二:配置文件

四、饥饿加载:


一、负载均衡原理:

负载均衡流程:

        为什么我们只输入了service名称就可以访问了呢?

        之前还要获取ip和端口。

        显然有人帮我们根据service名称,获取到了服务实例的ip和端口。它就是LoadBalancerInterceptor,这个类会在对RestTemplate的请求进行拦截,然后从Eureka根据服务id获取服务列表,随后利用负载均衡算法得到真实的服务地址信息,替换服务id。

        进行源码跟踪!

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) {
        this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
    }

    public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
        URI originalUri = request.getURI();
        String serviceName = originalUri.getHost();
        Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
        return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
    }
}

可以看到这里的intercept方法,拦截了用户的HttpRequest请求,然后做了几件事:

这里的this.loadBalancerLoadBalancerClient类型,我们继续跟入。  

        LoadBalancerInterceptor实现了ClientHttpRequestInterceptor,ClientHttpRequestInterceptor是一个客户端的HTTP拦截器,他会拦截由客户端发起的HTTP请求。

        LoadBalancerInterceptor重写了intercept方法:

    public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
        URI originalUri = request.getURI();
        String serviceName = originalUri.getHost();
        Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
        return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
    }

        intercept方法中,拿到了客户端的请求url,解析url获得了模块的服务名称,通过把服务名称交给Eureka拉取服务!这里intercept方法把serviceName(模块的服务名称)交给了loadBalancer进行执行!

LoadBalancerClient: 

        进入execute方法,找到具体实现:

    public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {
        ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);
        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);
        }
    }

        execute方法中,先拉取到了Eureka上的服务列表:

负载均衡策略IRule :

根据负载均衡的方式,选取对应的服务节点: 

Server server = this.getServer(loadBalancer, hint);

进入chooseServer方法:

我们看看这个rule是谁:

这里的rule默认值是一个RoundRobinRule,看类的介绍:

这不就是轮询的意思嘛。

完整流程: 

基本流程如下:


二、负载均衡策略:

Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则:

默认的实现就是ZoneAvoidanceRule,是一种轮询方案。


三、自定义负载均衡策略:

1.方式一:Bean组件

在order-service中的OrderApplication类中,定义一个新的IRule:

@Bean
public IRule randomRule(){
    return new RandomRule();
}

2.方式二:配置文件

在order-service的application.yml文件中,添加新的配置也可以修改规则:

userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则 

注意:一般用默认的负载均衡规则,不做修改。


四、饥饿加载:

        Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

ribbon:
  eager-load:
    enabled: true
    clients: userservice #服务名称

标签:负载,服务,SpringCloud,request,LoadBalancerInterceptor,Ribbon,均衡,loadBalancer
来源: https://blog.csdn.net/weixin_52058417/article/details/122847635