一:Ribbon是什么?

Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

二:LB方案分类

目前主流的LB方案可分成两类:一种是集中式LB, 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;另一种是进程内LB,将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于后者,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

三:Ribbon的主要组件与工作流程

Ribbon的核心组件(均为接口类型)有以下几个:

ServerList

用于获取地址列表。它既可以是静态的(提供一组固定的地址),也可以是动态的(从注册中心中定期查询地址列表)。

ServerListFilter

仅当使用动态ServerList时使用,用于在原始的服务列表中使用一定策略过虑掉一部分地址。

IRule

选择一个最终的服务地址作为LB结果。选择策略有轮询、根据响应时间加权、断路器(当Hystrix可用时)等。

Ribbon在工作时首选会通过ServerList来获取所有可用的服务列表,然后通过ServerListFilter过虑掉一部分地址,最后在剩下的地址中通过IRule选择出一台服务器作为最终结果。

四:Ribbon提供的主要负载均衡策略介绍

1:简单轮询负载均衡(RoundRobin)

以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。

2:随机负载均衡 (Random)

随机选择状态为UP的Server

3:加权响应时间负载均衡 (WeightedResponseTime)

根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。

4:区域感知轮询负载均衡(ZoneAvoidanceRule)

复合判断server所在区域的性能和server的可用性选择server

Ribbon自带负载均衡策略比较

策略名 策略声明 策略描述 实现说明
BestAvailableRule public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule 选择一个最小的并发请求的server 逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
AvailabilityFilteringRule public class AvailabilityFilteringRule extends PredicateBasedRule 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值) 使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态
WeightedResponseTimeRule public class WeightedResponseTimeRule extends RoundRobinRule 根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。 一 个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas时,使用roubine策略选择 server。
RetryRule public class RetryRule extends AbstractLoadBalancerRule 对选定的负载均衡策略机上重试机制。 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
RoundRobinRule public class RoundRobinRule extends AbstractLoadBalancerRule roundRobin方式轮询选择server 轮询index,选择index对应位置的server
RandomRule public class RandomRule extends AbstractLoadBalancerRule 随机选择一个server 在index上随机,选择index对应位置的server
ZoneAvoidanceRule public class ZoneAvoidanceRule extends PredicateBasedRule 复合判断server所在区域的性能和server的可用性选择server 使 用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个 zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的 Server。

五:Ribbon单独使用

创建一个maven工程 名称 ribbon_client

pom内容

1
2
3
4
5
6
7
8
9
10
11
12
        <dependencies>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-core</artifactId>
            <version>2.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-httpclient</artifactId>
            <version>2.2.0</version>
        </dependency>
    </dependencies>

sample-client.properties配置文件

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Max number of retries   
sample-client.ribbon.MaxAutoRetries=1
   
# Max number of next servers to retry (excluding the first server)  
sample-client.ribbon.MaxAutoRetriesNextServer=1
   
# Whether all operations can be retried for this client  
sample-client.ribbon.OkToRetryOnAllOperations=true
   
# Interval to refresh the server list from the source  
sample-client.ribbon.ServerListRefreshInterval=2000
   
# Connect timeout used by Apache HttpClient  
sample-client.ribbon.ConnectTimeout=3000
   
# Read timeout used by Apache HttpClient  
sample-client.ribbon.ReadTimeout=3000
   
# Initial list of servers, can be changed via Archaius dynamic property at runtime  
sample-client.ribbon.listOfServers=www.sohu.com:80,www.163.com:80,www.sina.com.cn:80
   
sample-client.ribbon.EnablePrimeConnections=true

RibbonMain代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.net.URI;
import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import com.netflix.niws.client.http.RestClient;
 
public class RibbonMain {
    public static void main( String[] args ) throws Exception {  
        ConfigurationManager.loadPropertiesFromResources("sample-client.properties");  
        System.out.println(ConfigurationManager.getConfigInstance().getProperty("sample-client.ribbon.listOfServers"));  
           
        RestClient client = (RestClient)ClientFactory.getNamedClient("sample-client");  
        HttpRequest request = HttpRequest.newBuilder().uri(new URI("/")).build();  
           
        for(int i = 0; i < 4; i ++) {  
            HttpResponse response = client.executeWithLoadBalancer(request);  
            System.out.println("Status for URI:" + response.getRequestedURI() + " is :" + response.getStatus());  
        }  
           
        ZoneAwareLoadBalancer lb = (ZoneAwareLoadBalancer) client.getLoadBalancer();  
        System.out.println(lb.getLoadBalancerStats());  
           
        ConfigurationManager.getConfigInstance().setProperty("sample-client.ribbon.listOfServers""ccblog.cn:80,www.linkedin.com:80");  
           
        System.out.println("changing servers ...");  
        Thread.sleep(3000);  
           
        for(int i = 0; i < 3; i ++) {  
            HttpResponse response = client.executeWithLoadBalancer(request);  
            System.out.println("Status for URI:" + response.getRequestedURI() + " is :" + response.getStatus());  
        }  
        System.out.println(lb.getLoadBalancerStats());  
    }  
}

代码解析

使用 Archaius ConfigurationManager 加载属性;

使用 ClientFactory 创建客户端和负载均衡器;

使用 builder 构建 http 请求。注意我们只支持 URI 的 "/" 部分的路径,一旦服务器被负载均衡器选中,会由客户端计算出完整的 URI;

调用 API client.executeWithLoadBalancer(),不是 exeucte() API;

动态修正配置中的服务器池;

等待服务器列表刷新(配置文件中定义的刷新间隔是为 3 秒钟);

打印出负载均衡器记录的服务器统计信息。

六:Ribbon结合eureka使用

先要启动eureka_register_service工程(注册中心)和biz-service-0工程(服务生产者)

创建maven工程 eureka_ribbon_client 该工程启动和相关配置依赖eureka_register_service和biz-service-0

pom加入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Brixton.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    </dependencies>
</dependencyManagement>

在应用主类中,通过@EnableDiscoveryClient注解来添加发现服务能力。创建RestTemplate实例,并通过@LoadBalanced注解开启均衡负载能力。

1
2
3
4
5
6
7
8
9
10
11
12
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonApplication {
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(RibbonApplication.class, args);
    }
}

创建ConsumerController来消费biz-service-0的getuser服务。通过直接RestTemplate来调用服务

1
2
3
4
5
6
7
8
9
10
11
@RestController
public class ConsumerController {
 
    @Autowired
    RestTemplate restTemplate;
 
    @RequestMapping(value = "/getuserinfo", method = RequestMethod.GET)
    public String add() {
        return restTemplate.getForEntity("http://biz-service-0/getuser", String.class).getBody();
    }
}

application.properties中配置eureka服务注册中心

spring.application.name=ribbon-consumer

server.port=8003

eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

完成后可以打开http://localhost:8003/getuserinfo 可以看到结果

总结:Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例。

SpringCloud之Ribbon(四)的更多相关文章

  1. 【微服务架构】SpringCloud之Ribbon(四)

    一:Ribbon是什么? Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起.Ribbon客户端组件提供一系列完善的配置项如连接 ...

  2. SpringCloud(4)---Ribbon服务调用,源码分析

    SpringCloud(4)---Ribbon 本篇模拟订单服务调用商品服务,同时商品服务采用集群部署. 注册中心服务端口号7001,订单服务端口号9001,商品集群端口号:8001.8002.800 ...

  3. spring-cloud配置ribbon负载均衡

    spring-cloud配置ribbon负载均衡 ribbon提供的负载均衡就是开箱即用的,简单的不能再简单了 为了顺利演示此demo,你需要如下 需要提前配置eureka服务端,具体看 https: ...

  4. 浅谈SpringCloud (三) Ribbon负载均衡

    什么是负载均衡 当一台服务器的单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能力时,服务器就会崩溃.为了避免服务器崩溃,让用户有更好的体验,我们通过负载均衡的方式来分担服务器压力. 我们 ...

  5. SpringCloud学习笔记(四、SpringCloud Netflix Ribbon)

    目录: Ribbon简介 Ribbon的应用 RestTemplate简介 Ribbon负载均衡源码分析 Ribbon简介: 1.负载均衡是什么 负载均衡,根据其字面意思来说就是让集群服务具有共同完成 ...

  6. 四(2)、springcloud之Ribbon负载均衡

    2.Ribbon负载均衡 ​ Ribbon在工作时分成两步第一步先选择 EurekaServer ,它优先选择在同一个区域内负载较少的server. 第二步再根据用户指定的策略,在从server取到的 ...

  7. 四(1)、springcloud之Ribbon初步配置

    1.概述 ​ Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 -负载均衡的工具.Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡 ...

  8. SpringCloud教程 | 第四篇:断路器(Hystrix)

    在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用.为了保证其高可用,单个服务 ...

  9. 史上最简单的SpringCloud教程 | 第四篇:断路器(Hystrix)

    在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用.为了保证其高可用,单个服务 ...

随机推荐

  1. Python--day43--增删改查补充和limit以及order by

    增删改查补充: 增: 删和改: 查: 其他: limit:(具有分页的功能) 分页:

  2. H3C 出站包过滤工作流程

  3. H3C 寻找邻居

  4. Can you find it?——[二分查找]

    Description Give you three sequences of numbers A, B, C, then we give you a number X. Now you need t ...

  5. vue-learning:2 - template - directive

    指令 directive 在上一节我们知道,VUE的template模板通过VUE指令API实现与页面的视图层联系.所以本节将聚集在实现视图层交互的VUE指令系统directive的基础使用. 我们先 ...

  6. 微软软件开发技术二十年回顾-Windows DNA篇

    五. Windows DNA篇 微软的Windows分布式因特网应用体系(简称Windows DNA)是微软创建新一代高适应性商业解 决方案的框架,它使公司能够充分地挖掘数字神经系统的优点.Windo ...

  7. 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)

    2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...

  8. 2018 CCPC 吉林站 H Lovers

    2018 CCPC 吉林站 H Lovers 传送门:https://www.spoj.com/problems/LIS2/en/ 题意: q次操作 1.将第l~r个数的左边和和右边都加上一个数d, ...

  9. kube-batch 解析

    kube-batch https://github.com/kubernetes-sigs/kube-batch 一. 做什么的? 官方介绍: A batch scheduler of kuberne ...

  10. .Net Core 3.0 发布为单独的可执行文件

    dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true