Ribbon負載均衡(四)

1、Ribbon定義

spring cloud Ribbon是基於Netflix Ribbon實現的一套客戶端,負載均衡工具java

 

簡單的說,Ribbon是Netflix發佈的開源項目,主要功能是提供客戶端的軟件負載均衡算法mysql

,將Netflix的中間層服務層鏈接在一塊兒.Ribbon客戶端組件提供一系列完善的配置項如鏈接nginx

超時,重試等.簡單的說,就是在配置文件中列出Load Balancer(簡稱LB)後面全部的機器,git

Ribbon會自動的幫助你基於某種規則(如簡單輪詢,隨機鏈接等)去鏈接這些機器.咱們很容易使用Ribbon實現自定義的負載均衡算法github

 ribbon原理圖:算法

 

2、LB負載均衡

集中式LBspring

即在服務的消費方和提供方之間使用獨立的LB設施(能夠是硬件,好比F5,也能夠是軟件,如Nginx)由該設施負責把訪問請求經過某一種策略轉發至服務的提供者;sql

進程式LB數據庫

將LB邏輯集成到消費方,消費方從服務中心獲取知有哪些地址可用,而後本身再從這些地址中選擇出一個合適的服務器.緩存

Ribbon就屬於進程內LB,它只是一個類庫,集成於消費方進程,消費方經過他來獲取到服務提供方的地址.

3、官方地址

https://github.com/Netflix/ribbon

4、Ribbon的初始化配置

一、修改microservicecloud-consumer-dept-80工程 

修改pom文件

      <!-- 將微服務provider側註冊進eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

修改yml文件 添加

eureka:
  client:
    service-url:
      defaultZone:  http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #向服務中心註冊本身
    register-with-eureka: false 

對configBean進行新註解@LoadBalanced得到Rest時加入Ribbon的配置

@Configuration public class ConfigBean { @Bean @LoadBalanced //註解代表這個restRemplate開啓負載均衡的功能。
    public RestTemplate getRestTemplate(){ return new RestTemplate(); } }

主啓動類ConSumeAppStart_80添加@EnableEurekaClient

@SpringBootApplication @EnableEurekaClient public class ConSumeAppStart { public static void main(String[] args) { SpringApplication.run(ConSumeAppStart.class); } }

修改DeptController客戶端訪問類

@RestController
public class DeptController {

    //private static final String REST_URL_PREFIX = "http://localhost:8001";
    private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
//完成真正的經過微服務名字從eureka上找到並訪問
    /**
     * 使用 使用restTemplate訪問restful接口很是的簡單粗暴無腦。 (url, requestMap,
     * ResponseBean.class)這三個參數分別表明 REST請求地址、請求參數、HTTP響應轉換被轉換成的對象類型。
     */
    @Autowired
    private RestTemplate restTemplate;
    @RequestMapping(value = "/consumer/dept/add")
    public boolean add(Dept dept)
    {
        return restTemplate.postForObject(REST_URL_PREFIX + "/dept/addDept", dept, Boolean.class);
    }

    @RequestMapping("/findAll")
    public List<Dept> findAll() {
        return restTemplate.getForObject(REST_URL_PREFIX + "/dept/findAll",List.class);
    }
}

先啓動3個eureka集羣后,在啓動microservicecloud-config-dept-client-8001並註冊進eureka

啓動ConSumeAppStart_80

測試 訪問地址:http://localhost:80/findAll

效果

 

5、Ribbon負載均衡

一、架構說明圖

 

Ribbon在工做分紅2步

 第一步:先選擇EurekaServer,它優先選擇在同一個區域負載較少的server

第二步:再根據用戶指定策略,在從server取到的服務註冊列表中選擇一個地址.

其中Ribbon提供了多種策略:好比輪詢,隨機和根據時間響應加權

 6、建立提供者多服務

參考microservicecloud-provider-dept-8001新建2份,分別命名爲8002,8003  

新建8002/8003 數據庫,各自微服務分別連各自的數據庫clouddb02/clouddb03

修改8002/8003各自的yml

8002 yml

server: port: 8002 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路徑 type-aliases-package: com.yehui.entity # 全部Entity別名類所在包 mapper-locations: classpath:mybatis/mapper/**/*.xml # mapper映射文件 #應用名稱 spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource # 當前數據源操做類型 driver-class-name: org.gjt.mm.mysql.Driver # mysql驅動包 url: jdbc:mysql://localhost:3306/clouddb02 # 數據庫名稱 username: root password: root dbcp2: min-idle: 5 # 數據庫鏈接池的最小維持鏈接數 initial-size: 5 # 初始化鏈接數 max-total: 5 # 最大鏈接數 max-wait-millis: 200 # 等待鏈接獲取的最大超時時間 eureka: client: #客戶端註冊進eureka服務列表內 service-url: defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/ ###是否向註冊中心註冊本身 register-with-eureka: true ###是否須要從eureka上獲取註冊信息 fetch-registry: true instance: instance-id: providerdept_8001 #自定義服務名稱 prefer-ip-address: true #訪問路徑能夠顯示IP地址 #信息的描述 info: app.name: atguigu-microservicecloud company.name: www.atguigu.com build.artifactId: $project.artifactId$ build.version: $project.version$

 8003yml

server: port: 8003 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路徑 type-aliases-package: com.yehui.entity # 全部Entity別名類所在包 mapper-locations: classpath:mybatis/mapper/**/*.xml # mapper映射文件 spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource # 當前數據源操做類型 driver-class-name: org.gjt.mm.mysql.Driver # mysql驅動包 url: jdbc:mysql://localhost:3306/clouddb03 # 數據庫名稱 username: root password: root dbcp2: min-idle: 5 # 數據庫鏈接池的最小維持鏈接數 initial-size: 5 # 初始化鏈接數 max-total: 5 # 最大鏈接數 max-wait-millis: 200 # 等待鏈接獲取的最大超時時間 eureka: client: #客戶端註冊進eureka服務列表內 service-url: defaultZone: http://localhost:7002/eureka/,http://localhost:7003/eureka/,http://localhost:7001/eureka/ instance: instance-id: providerdept_8003 #自定義服務名稱 prefer-ip-address: true #訪問路徑能夠顯示IP地址 #信息的描述 info: app.name: atguigu-microservicecloud company.name: www.atguigu.com build.artifactId: $project.artifactId$ build.version: $project.version$

備註  

   端口

數據庫連接  jdbc:mysql://localhost:3306/clouddb01

對外暴露的統一的服務實例名

 

啓動3個eureka集羣配置區

啓動3個Dept微服務並各自測試經過

 

http://localhost:8003/dept/findAll

http://localhost:8001/dept/findAll

http://localhost:8002/dept/findAll

 

啓動ConSumeAppStart_80

客戶端經過Ribbon完成負載均衡並訪問上一步的Dept微服務

 

上圖有三個消費者

 

http://localhost/findAll

注意觀察看到返回的數據的數據庫的不一樣

 

從上面能夠獲得:Ribbon其實就是一個軟負載均衡的客戶端組件,他能夠和其餘所需求請求的客戶端結合使用,eureka結合只是其中的一個實例

7、Ribbon核心組件IRule

一、IRule算法

IRule:根據特色算法中從服務列表中選取一個要訪問的服務

RoundRobinRule:輪詢算法

RandomRule隨機算法

AvailabilityFilteringRule:會先過濾因爲屢次訪問故障而處於斷路器跳閘狀態的服務,還有併發的鏈接數量超過閾值的服務,而後對剩餘的服務列表按照輪詢策略進行訪問

WeightedResponseTimeRule:根據平均響應的時間計算全部服務的權重,響應時間越快服務權重越大被選中的機率越高,剛啓動時若是統計信息不足,則使用RoundRobinRule策略,等統計信息足夠會切換到WeightedResponseTimeRule

RetryRule:先按照RoundRobinRule的策略獲取服務,若是獲取失敗則在制定時間內進行重試,獲取可用的服務。

BestAviableRule:會先過濾掉因爲屢次訪問故障而處於斷路器跳閘狀態的服務,而後選擇一個併發量最小的服務

ZoneAvoidanceRule:默認規則,符合判斷server所在區域的性能和server的可用性選擇服務器

RetryRule:先根據RoundRonbinRule的策略獲取服務,若是獲取服務失敗則在指定時間內會進行重試,獲取可用的服務

訪問地址:https://github.com/Netflix/ribbon

 

 config類

@Bean
public IRule getRule(){
    return new RandomRule(); //使用隨機的算法替換默認的輪詢算法
}

測試訪問:http://localhost:80/findAll

 二、Ribbon自定義

修改microservicecloud-consumer-dept-80

 

主啓動類添加@RibbonClient

在啓動該微服務的時候就能去加載咱們自定義Ribbon配置類,從而使配置生效,形如:

@RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MyRule.class)

注意細節

步驟:

  新建一個MyRule類

@Configuration public class MyRule { @Bean public IRule getRule(){ return new RoundRobinRule(); //使用使用輪詢算法
 } }

  修改主啓動類新增@RibbonClient註解

@SpringBootApplication @EnableEurekaClient //代表本身是一個eurekaclient.
@RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MyRule.class) public class ConSumeAppStart_80 { public static void main(String[] args) { SpringApplication.run(ConSumeAppStart_80.class); } }

 測試http://localhost:80/findAll

三、自定義規則深度解析

問題:依舊輪詢策略,可是加上新需求,每一個服務要求被調用5次.也即

之前是每臺機器一次,如今是每臺機器5次

解析源碼:https://github.com/Netflix/ribbon/blob/master/ribbon-

loadbalancer/src/main/java/com/netflix/loadbalancer/RandomRule.java

參考源碼修改成咱們的需求需的MyRole_YH.java

 更新中

四、使用DiscoveryClient實現本地負載均衡

編寫controller

@RestController public class DeptController { //獲取服務註冊信息
 @Autowired private DiscoveryClient discoveryClient; @Autowired private RestTemplate restTemplate; @RequestMapping("/find") public List<Dept> find(){ List<ServiceInstance> instances = discoveryClient.getInstances("microservicecloud-dept"); int instacesSize = instances.size(); int index = num%instacesSize; num++; String url = instances.get(index).getUri().toString(); return restTemplate.getForObject(url + "/dept/findAll",List.class); } } 

congig類

@Configuration public class ConfigBean { @Bean //@LoadBalanced 這個註解不須要了
    public RestTemplate getRestTemplate(){ return new RestTemplate(); } }

測試

五、Ribbon與Nginx區別

客戶端負載均衡器

 在SpringCloud中Ribbon負載均衡客戶端,會從eureka註冊中心服務器端上獲取服務註冊信息列表,緩存到本地。

讓後在本地實現輪訓負載均衡策略。

服務器端負載均衡Nginx

 nginx是客戶端全部請求統一交給nginx,由nginx進行實現負載均衡請求轉發,屬於服務器端負載均衡。

 既請求有nginx服務器端進行轉發。

客戶端負載均衡Ribbon

 Ribbon是從eureka註冊中心服務器端上獲取服務註冊信息列表,緩存到本地,讓後在本地實現輪訓負載均衡策略。

 既在客戶端實現負載均衡。

 應用場景的區別:

Nginx適合於服務器端實現負載均衡 好比Tomcat ,Ribbon適合與在微服務中RPC遠程調用實現本地服務負載均衡,好比Dubbo、SpringCloud中都是採用本地負載均衡。

相關文章
相關標籤/搜索