Spring Cloud學(xué)習(xí)筆記-負(fù)載均衡

Netflix Ribbon

調(diào)度算法

1庞瘸、First Come First Served  先來先服務(wù)
2、Earliest deadline first 最早截止時(shí)間優(yōu)先
3拿诸、Shortest remaining time first 最短保留時(shí)間優(yōu)先
4、Fixed Priority 固定優(yōu)先級(jí)
5塞茅、Round-Robin 輪訓(xùn)
6亩码、Multilevel Queue 多級(jí)別隊(duì)列列

引入Maven 依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>

激活 Ribbon 客戶端

package com.segumentfault.springcloudlesson6;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
// 多個(gè) Ribbon 定義
@RibbonClients({
        @RibbonClient(name = "spring-cloud-service-provider")
})
public class SpringCloudLesson6Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudLesson6Application.class, args);
    }

    //聲明 RestTemplate  開啟負(fù)載均衡的注解
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

配置 Ribbon 客戶端

application.properties

### 配置ribbon 服務(wù)地提供方
spring-cloud-service-provider.ribbon.listOfServers = \
  http://${serivce-provider.host}:${serivce-provider.port}

調(diào)整 RestTemplate

//聲明 RestTemplate
@LoadBalanced // RestTemplate 的行為變化
@Bean
public RestTemplate restTemplate(){
    return new RestTemplate();
}

Neflix Ribbon 整合 Eureka

激活服務(wù)發(fā)現(xiàn)的客戶端

package com.segumentfault.springcloudlesson6;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
// 多個(gè) Ribbon 定義
@RibbonClients({
        @RibbonClient(name = "spring-cloud-service-provider")
})
@EnableDiscoveryClient // 激活服務(wù)發(fā)現(xiàn)客戶端
public class SpringCloudLesson6Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudLesson6Application.class, args);
    }

    //聲明 RestTemplate
    @LoadBalanced // RestTemplate 的行為變化 開啟負(fù)載均衡的注解
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

創(chuàng)建并且啟動(dòng) Eureka Server

spring-cloud-lesson6-eureka-server 為例

激活 Eureka Server

package com.segumentfault.springcloudlesson6eurekaserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class SpringCloudLesson6EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudLesson6EurekaServerApplication.class, args);
    }
}

配置 Eureka 服務(wù)器

## Eureka Serer
spring.application.name = spring-cloud-eureka-server

## 服務(wù)端口
server.port = 10000

## Spring Cloud Eureka 服務(wù)器作為注冊(cè)中心
## 通常情況下,不需要再注冊(cè)到其他注冊(cè)中心去
## 同時(shí)野瘦,它也不需要獲取客戶端信息
### 取消向注冊(cè)中心注冊(cè)
eureka.client.register-with-eureka = false
### 取消向注冊(cè)中心獲取注冊(cè)信息(服務(wù)描沟、實(shí)例信息)
eureka.client.fetch-registry = false
## 解決 Peer / 集群 連接問題
eureka.instance.hostname = localhost
eureka.client.serviceUrl.defaultZone = http://${eureka.instance.hostname}:${server.port}/eureka

啟動(dòng) Eureka Server

調(diào)整 Ribbon 客戶端連接 Eureka Server

applicaiont.properties

## 服務(wù)提供方
spring.application.name = spring-cloud-ribbon-client

### 服務(wù)端口
server.port = 8080

### 管理安全失效
management.security.enabled = false

### 暫時(shí)性關(guān)閉 Eureka 注冊(cè)
## 當(dāng)使用 Eureka 服務(wù)發(fā)現(xiàn)時(shí),請(qǐng)注釋掉一下配置
# eureka.client.enabled = false

## 連接 Eureka Sever
eureka.client.serviceUrl.defaultZone = http://localhost:10000/eureka/

### 服務(wù)提供方主機(jī)
serivce-provider.host = localhost
### 服務(wù)提供方端口
serivce-provider.port = 9090

serivce-provider.name = spring-cloud-service-provider

### 配置ribbon 服務(wù)地提供方
## 當(dāng)使用 Eureka 服務(wù)發(fā)現(xiàn)時(shí)鞭光,請(qǐng)注釋掉一下配置
# spring-cloud-service-provider.ribbon.listOfServers = \
  http://${serivce-provider.host}:${serivce-provider.port}

調(diào)整服務(wù)提供方并且連接 Eureka Server

## 服務(wù)提供方
spring.application.name = spring-cloud-service-provider

### 服務(wù)端口
server.port = 9090

### 管理安全失效
management.security.enabled = false

### 暫時(shí)性關(guān)閉 Eureka 注冊(cè)
## 當(dāng)使用 Eureka 服務(wù)發(fā)現(xiàn)時(shí)吏廉,請(qǐng)注釋掉一下配置
# eureka.client.enabled = false

## 連接 Eureka Sever
eureka.client.serviceUrl.defaultZone = http://localhost:10000/eureka/

再啟動(dòng)兩臺(tái)服務(wù)提供方實(shí)例

--server.port=9091

--server.port=9092

實(shí)際請(qǐng)求客戶端

  • LoadBalancerClient
    • RibbonLoadBalancerClient

負(fù)載均衡上下文

  • LoadBalancerContext
    • RibbonLoadBalancerContext

負(fù)載均衡器

  • ILoadBalancer
    • BaseLoadBalancer
    • DynamicServerListLoadBalancer
    • ZoneAwareLoadBalancer
    • NoOpLoadBalancer
總結(jié)一下:
  ILoadBalancer接口實(shí)現(xiàn)類做了以下的一些事情:
    1.維護(hù)了存儲(chǔ)服務(wù)實(shí)例Server對(duì)象的二個(gè)列表。一個(gè)用于存儲(chǔ)所有服務(wù)實(shí)例的清單惰许,一個(gè)用于存儲(chǔ)正常服務(wù)的實(shí)例清單
    2.初始化得到可用的服務(wù)列表席覆,啟動(dòng)定時(shí)任務(wù)去實(shí)時(shí)的檢測(cè)服務(wù)列表中的服務(wù)的可用性,并且間斷性的去更新服務(wù)列表汹买,結(jié)合注冊(cè)中心佩伤。
    3.選擇可用的服務(wù)進(jìn)行調(diào)用(這個(gè)一般交給IRule去實(shí)現(xiàn),不同的輪詢策略)

三個(gè)很重要的概念

  ServerList接口:定義用于獲取服務(wù)器列表的方法的接口,主要實(shí)現(xiàn)DomainExtractingServerList接口晦毙,每隔30s種執(zhí)行g(shù)etUpdatedListOfServers方法進(jìn)行服務(wù)列表的更新畦戒。
  ServerListUpdater接口:主要實(shí)現(xiàn)類EurekaNotificationServerListUpdater和PollingServerListUpdater(默認(rèn)使用的是PollingServerListUpdater,結(jié)合Eureka注冊(cè)中心结序,定時(shí)任務(wù)的方式進(jìn)行服務(wù)列表的更新)
  ServerListFilter接口:根據(jù)LoadBalancerStats然后根據(jù)一些規(guī)則去過濾部分服務(wù)障斋,比如根據(jù)zone(區(qū)域感知)去過濾。(主要實(shí)現(xiàn)類ZonePreferenceServerListFilter的getFilteredListOfServers會(huì)在更新服務(wù)列表的時(shí)候去執(zhí)行)。

負(fù)載均衡規(guī)則

核心規(guī)則接口

  • IRule
    • 隨機(jī)規(guī)則:RandomRule 隨機(jī)選擇一個(gè)server
    • 最可用規(guī)則:BestAvailableRule 選擇一個(gè)最小的并發(fā)請(qǐng)求的server
    • 輪訓(xùn)規(guī)則:RoundRobinRule 默認(rèn)策略 輪詢選擇server
    • 重試實(shí)現(xiàn):RetryRule 對(duì)選定的負(fù)載均衡策略機(jī)上重試機(jī)制
    • 客戶端配置:ClientConfigEnabledRoundRobinRule
    • 可用性過濾規(guī)則:AvailabilityFilteringRule 過濾掉那些因?yàn)橐恢边B接失敗的被標(biāo)記為circuittripped的后端server垃环,并過濾掉那些高并發(fā)的的后端server(active connections 超過配置的閾值)
    • RT權(quán)重規(guī)則:WeightedResponseTimeRule 根據(jù)相應(yīng)時(shí)間分配一個(gè)weight邀层,相應(yīng)時(shí)間越長,weight越小遂庄,被選中的可能性越低寥院。
    • 規(guī)避區(qū)域規(guī)則:ZoneAvoidanceRule 復(fù)合判斷server所在區(qū)域的性能和server的可用性選擇server

PING 策略

核心策略接口

  • IPingStrategy

PING 接口

  • IPing
    • NoOpPing
    • DummyPing
    • PingConstant
    • PingUrl

Discovery Client 實(shí)現(xiàn)

  • NIWSDiscoveryPing
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市涛目,隨后出現(xiàn)的幾起案子秸谢,更是在濱河造成了極大的恐慌,老刑警劉巖霹肝,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件估蹄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡沫换,警方通過查閱死者的電腦和手機(jī)臭蚁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讯赏,“玉大人垮兑,你說我怎么就攤上這事∈妫” “怎么了系枪?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長磕谅。 經(jīng)常有香客問我嗤无,道長,這世上最難降的妖魔是什么怜庸? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任当犯,我火速辦了婚禮,結(jié)果婚禮上割疾,老公的妹妹穿的比我還像新娘嚎卫。我一直安慰自己,他們只是感情好宏榕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布拓诸。 她就那樣靜靜地躺著,像睡著了一般麻昼。 火紅的嫁衣襯著肌膚如雪奠支。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天抚芦,我揣著相機(jī)與錄音倍谜,去河邊找鬼迈螟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛尔崔,可吹牛的內(nèi)容都是我干的答毫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼季春,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼洗搂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起载弄,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤耘拇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后宇攻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惫叛,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年尺碰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片译隘。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡亲桥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出固耘,到底是詐尸還是另有隱情题篷,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布厅目,位于F島的核電站番枚,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏损敷。R本人自食惡果不足惜葫笼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拗馒。 院中可真熱鬧路星,春花似錦、人聲如沸诱桂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挥等。三九已至友绝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肝劲,已是汗流浹背迁客。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工郭宝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哲泊。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓剩蟀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親切威。 傳聞我的和親對(duì)象是個(gè)殘疾皇子育特,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353