SpringCloud Netflix Ribbon超詳細(xì)講解
一、Ribbon簡介
1、什么是Ribbon
Spring Cloud Ribbon 是基于Netflix Ribbon 實(shí)現(xiàn)的一套客戶端負(fù)載均衡的工具,它可以很好地控制HTTP和TCP客戶端的行為。
簡單的說,Ribbon 是 Netflix 發(fā)布的開源項(xiàng)目,主要功能是提供客戶端的軟件負(fù)載均衡算法,將 Netflix 的中間層服務(wù)連接在一起。Ribbon 的客戶端組件提供一系列完整的配置項(xiàng),如:連接超時、重試等。簡單的說,就是在配置文件中列出 LoadBalancer (簡稱LB:負(fù)載均衡) 后面所有的及其,Ribbon 會自動的幫助你基于某種規(guī)則 (如簡單輪詢,隨機(jī)連接等等) 去連接這些機(jī)器。我們也容易使用 Ribbon 實(shí)現(xiàn)自定義的負(fù)載均衡算法!
2、Ribbon能干什么
- LB,即負(fù)載均衡 (LoadBalancer) ,在微服務(wù)或分布式集群中經(jīng)常用的一種應(yīng)用。
- 負(fù)載均衡簡單的說就是將用戶的請求平攤的分配到多個服務(wù)上,從而達(dá)到系統(tǒng)的HA (高用)。
- 常見的負(fù)載均衡軟件有 Nginx、Lvs(中國人研發(fā)的) 等等。
其中l(wèi)vs是中國技術(shù)專家章文嵩發(fā)明的
- Dubbo、SpringCloud 中均給我們提供了負(fù)載均衡,SpringCloud 的負(fù)載均衡算法可以自定義。
負(fù)載均衡簡單分類:
- 集中式LB
即在服務(wù)的提供方和消費(fèi)方之間使用獨(dú)立的LB設(shè)施,如Nginx(反向代理服務(wù)器),由該設(shè)施負(fù)責(zé)把訪問請求通過某種策略轉(zhuǎn)發(fā)至服務(wù)的提供方!
- 進(jìn)程式 LB
將LB邏輯集成到消費(fèi)方,消費(fèi)方從服務(wù)注冊中心獲知有哪些地址可用,然后自己再從這些地址中選出一個合適的服務(wù)器。 Ribbon就屬于進(jìn)程內(nèi)LB,它只是一個類庫,集成于消費(fèi)方進(jìn)程,消費(fèi)方通過它來獲取到服務(wù)提供方的地址!
二、使用Ribbon
1、客戶端導(dǎo)入依賴
<!--引入Eureka的依賴--> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.4.6.RELEASE</version> </dependency> <!--引入ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.4.6.RELEASE</version> </dependency> </dependencies>
2、application.yml配置
server:
port: 801eureka:
client:
register-with-eureka: false #不向eureka注冊自己
service-url:
defaultZone: http://localhost:7001/eureka/ #去哪個地方獲取
3、Controller配置
和前面兩節(jié)不一樣的是,用Ribbon做負(fù)載均衡,地址不能寫死,也就是不能和前面的一樣寫成一個具體的值如:localhost:8001,而是這個微服務(wù)的名字,也就是這個名字,如下。
package com.you.controller; import com.you.pojo.Dept; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; import java.util.List; @RestController @ResponseBody public class DeptComsumerController { @Autowired RestTemplate restTemplate; // public static final String REST_URL_PREFIX = "http://localhost:8001"; public static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT"; @GetMapping("/consumer/dept/getDept/{id}") public Dept getDeptOfId(@PathVariable("id") Long id) { System.out.println(REST_URL_PREFIX+"/dept"+"/aDept/"+id); return restTemplate.getForObject(REST_URL_PREFIX + "/dept" + "/aDept/"+id, Dept.class); } }
4、Config的配置
在此文件里,增加了@LoadBalanced注解,該注解的作用是讓RestTemplate有了負(fù)載均衡的能力,而且默認(rèn)的負(fù)載均衡算法是輪詢(也就是一個一個的嘗試),可以使用系統(tǒng)配備的負(fù)載均衡算法,也可以自己寫自己的負(fù)載均衡算法。
package com.you.config; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class ConfigBean { @Bean @LoadBalanced //ribbon /*配置負(fù)載均衡實(shí)現(xiàn)RestTemplate*/ /*IRule*/ /*RoundRobinRule 輪詢 */ /*RandomRule 隨機(jī)*/ /*AvailabilityFilteringRule 優(yōu)先過濾掉跳閘、訪問故障的服務(wù),對剩下的進(jìn)行輪詢 */ public RestTemplate getRestTemplate() { return new RestTemplate(); } }
5、啟動類的配置
package com.you; import com.tan.tanRule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; @SpringBootApplication @EnableEurekaClient /*下面是處理負(fù)載均衡算法*/ @RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = tanRule.class) public class DeptConsumer_80 { public static void main(String[] args) { SpringApplication.run(DeptConsumer_80.class,args); } }
三、Ribbon實(shí)現(xiàn)負(fù)載均衡
為了實(shí)現(xiàn)負(fù)載均衡,擴(kuò)充一下服務(wù)提供者,將原來的一個服務(wù)提供者,改為三個。
- 新建三個module,springboot-provider-8002、springboot-provider-8003。
- 參考springboot-provider-8001,修改application.xml(主要是端口號,數(shù)據(jù)庫名,instance-id),其中application-name要保持一致。和微服務(wù)的名字一樣。
- 啟動Eureka_7001,啟動這個三個提供者,根據(jù)自己的情況,如果電腦性能比較差,可以少啟動一個。啟動consumer_80。
訪問consumer_80配置的Getmapping地址,然后不斷的刷新,會看到依次訪問三個數(shù)據(jù)庫,并且一直重復(fù),這就是默認(rèn)的負(fù)載均衡算法:輪詢
四、設(shè)計負(fù)載均衡算法
1、80啟動類的改動
@RibbonClient()注釋的應(yīng)用,在psvm上面添加該注釋,其具體內(nèi)容為@RibbonClient(name = “SPRINGCLOUD-PROVIDER-DEPT”,configuration = tanRule.class),其中name的值即為微服務(wù)的名字,configuration的值對應(yīng)的就是自己寫的路由類
2、自定義路由類
需要注意,自定義的路由類,不可以用啟動類放在同一目錄,一般要比啟動類高一級目錄,放在同一目錄下,需要配置CompentScan。
package com.tan; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import org.springframework.context.annotation.Bean; public class tanRule { @Bean public IRule myRule() { return new tanRandomRule(); } }
3、負(fù)載均衡算法的實(shí)現(xiàn)
可以模仿系統(tǒng)中的負(fù)載均衡算法,撰寫自己的負(fù)載均衡算法,如下面的例子即為:每個端口的提供者訪問5次,然后切換下一個端口,全部訪問完成后則重新開始,代碼如下:
package com.tan; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; import java.util.List; import java.util.concurrent.ThreadLocalRandom; public class tanRandomRule extends AbstractLoadBalancerRule { int total = 0; int currentIndex = 0; public tanRandomRule() { } @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"}) public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } else { Server server = null; while(server == null) { if (Thread.interrupted()) { return null; } List<Server> upList = lb.getReachableServers(); List<Server> allList = lb.getAllServers(); if(total<5) { server = (Server)upList.get(currentIndex); total++; }else{ total = 0; currentIndex++; if(currentIndex>2) { currentIndex = 0; } server = (Server)upList.get(currentIndex); } System.out.println("CurrentIndex:"+currentIndex); System.out.println("Total:"+total); System.out.println("sever 的值是:"+server); if (server == null) { Thread.yield(); } else { if (server.isAlive()) { return server; } server = null; Thread.yield(); } } return server; } } protected int chooseRandomInt(int serverCount) { return ThreadLocalRandom.current().nextInt(serverCount); } public Server choose(Object key) { return this.choose(this.getLoadBalancer(), key); } public void initWithNiwsConfig(IClientConfig clientConfig) { } }
到此這篇關(guān)于SpringCloud Netflix Ribbon超詳細(xì)講解的文章就介紹到這了,更多相關(guān)SpringCloud Netflix Ribbon內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
線程池之newCachedThreadPool可緩存線程池的實(shí)例
這篇文章主要介紹了線程池之newCachedThreadPool可緩存線程池的實(shí)例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06spring security認(rèn)證異常后返回中文提示的問題
這篇文章主要介紹了spring security認(rèn)證異常后返回中文提示的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02Java實(shí)現(xiàn)的權(quán)重算法(按權(quán)重展現(xiàn)廣告)
這篇文章主要介紹了Java實(shí)現(xiàn)的權(quán)重算法(按權(quán)重展現(xiàn)廣告),本文講解了算法實(shí)現(xiàn)原理和實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-04-04JAVA OutputStreamWriter流的實(shí)現(xiàn)
OutputStreamWriter是從字符流到字節(jié)流的橋接,它使用的字符集可以通過名稱指定,也可以明確指定,或者可以接受平臺的默認(rèn)字符集,本文詳細(xì)的介紹了JAVA OutputStreamWriter流的使用,感興趣的可以了解一下2021-06-06Spring實(shí)戰(zhàn)之協(xié)調(diào)作用域不同步的Bean操作示例
這篇文章主要介紹了Spring實(shí)戰(zhàn)之協(xié)調(diào)作用域不同步的Bean操作,結(jié)合實(shí)例形式分析了Spring協(xié)調(diào)作用域不同步的Bean相關(guān)配置及使用技巧,需要的朋友可以參考下2019-11-11JNI實(shí)現(xiàn)最簡單的JAVA調(diào)用C/C++代碼
這篇文章主要介紹了JNI實(shí)現(xiàn)最簡單的JAVA調(diào)用C/C++代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08springboot+redis自定義注解實(shí)現(xiàn)發(fā)布訂閱的實(shí)現(xiàn)代碼
在Redis中客戶端可以通過訂閱特定的頻道來接收發(fā)送至該頻道的消息,本文主要介紹了springboot+redis自定義注解實(shí)現(xiàn)發(fā)布訂閱,具有一定的參考價值,感興趣的可以了解一下2023-08-08