spring cloud服務(wù)之間的調(diào)用之ribbon詳解
前言
昨天,我們通過(guò)一個(gè)實(shí)例演示了,spring-cloud
服務(wù)注冊(cè)組件——Eureka
的基本配置和簡(jiǎn)單用法,但是服務(wù)注冊(cè)就是為了方便后期的發(fā)現(xiàn)和調(diào)用,所以今天我們趁熱打鐵,分享下spring-cloud
服務(wù)之間的調(diào)用。
服務(wù)間的調(diào)用
關(guān)于spring-cloud
的服務(wù)調(diào)用,我們首先需要了解它的兩個(gè)核心組件Ribbon
和Feign
。
我們都知道,spring boot
的接口都是基于REST
實(shí)現(xiàn)的,但是在實(shí)際線上運(yùn)行的時(shí)候,考慮到用戶規(guī)模、服務(wù)可用性等方面的因素,我們一般很少是單節(jié)點(diǎn)運(yùn)行的,通常都是以集群模式部署的,但是在集群部署中,又有一個(gè)核心的問(wèn)題必須解決——負(fù)載均衡。關(guān)于負(fù)載均衡,各位小伙伴應(yīng)該不陌生,最常用的組件之一nginx
其中一個(gè)很核心的用途就是做負(fù)載均衡,但是nginx
在實(shí)際做負(fù)載均衡的時(shí)候,確實(shí)不夠方便,需要手動(dòng)配置服務(wù)地址,如果服務(wù)地址發(fā)生變化,相關(guān)配置也需要修改,所以不夠靈活。
當(dāng)然spring cloud
作為一款微服務(wù)綜合框架,它自然也提供了自己的一套負(fù)載均衡解決方案,所以接下來(lái)我們就來(lái)看下spring cloud
的負(fù)載均衡組件——Ribbon
。
Ribbon
Ribbon
中文的意思是絲帶、帶狀物,正如它的含義,它就是連接調(diào)用方和服務(wù)之間的紐帶。
依賴
我們先通過(guò)一個(gè)簡(jiǎn)單實(shí)例,來(lái)演示下,然后在示例的過(guò)程中來(lái)解釋,首先是它的核心依賴:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <version>2.2.9.RELEASE</version> </dependency>
配置
這個(gè)組件你需要添加到服務(wù)調(diào)用方的依賴中。同時(shí),還需要增加它的配置:
@Configuration public class RibbonConfig { // 多節(jié)點(diǎn)負(fù)載 @LoadBalanced @Bean(name = "restTemplate") public RestTemplate restTemplate() { return new RestTemplate(); } }
@LoadBalanced
注解的作用是啟用多節(jié)點(diǎn)負(fù)載,這樣后期我們?cè)谡{(diào)用的時(shí)候,RestTemplate
客戶端其實(shí)就是通過(guò)負(fù)載均衡的方式在調(diào)用服務(wù)提供者。
服務(wù)調(diào)用方
然后,在服務(wù)調(diào)用方,我們通過(guò)RestTemplate
去調(diào)用我們的服務(wù)提供者:
@Autowired private RestTemplate restTemplate; @GetMapping("/ribbon") public Object queryUserByProductId() { List<JSONObject> jsonObjectList = Lists.newArrayList(); for (int i = 0; i < 10; i++) { JSONObject forObject = restTemplate.getForObject("http://user-center/user/" + (i + 1), JSONObject.class); jsonObjectList.add(forObject); } return jsonObjectList; }
這里我們通過(guò)前面配置的restTemplate
來(lái)調(diào)用我們的用戶服務(wù),接口的地址就是我們eureka
注冊(cè)中心顯示的地址:
這里的地址不區(qū)分大小寫,都可以正常訪問(wèn)。調(diào)用十次,主要是為了測(cè)試負(fù)載均衡的效果。
服務(wù)提供者
首先我們看下服務(wù)提供者配置:
server.port=8776 eureka.client.service-url.defaultZone=http://localhost:8999/eureka, http://localhost:9000/eureka
第一個(gè)配置是指定服務(wù)的端口,如果在本地啟動(dòng)的話,需要每啟動(dòng)一次改一個(gè)端口,否則會(huì)提示端口沖突,如果你用的是IDEA
的話,要先運(yùn)行多應(yīng)用啟動(dòng):
第二個(gè)配置就是設(shè)定我們的注冊(cè)中心,我們有兩個(gè)注冊(cè)中心,所以指定了兩個(gè)地址。
服務(wù)提供者就是一個(gè)簡(jiǎn)單的controller
,在controller
內(nèi)部,我們通過(guò)DiscoveryClient
打印出被調(diào)用者的信息,方便我們查看。
@RestController public class UserController { private Logger logger = LoggerFactory.getLogger(UserController.class); @Autowired private DiscoveryClient discoveryClient; @GetMapping("/user/{id}") public JSONObject getUserById(@PathVariable(name = "id") Long id) { List<ServiceInstance> instances = discoveryClient.getInstances("user-center"); logger.info("instances = {}", instances); JSONObject user = new JSONObject(); user.put("id", id); user.put("name", "syske"); return user; } }
這里需要注意的是,我們導(dǎo)入的DiscoveryClient
是org.springframework.cloud.client.discovery
包下的,如果不是同這個(gè)類,啟動(dòng)的時(shí)候會(huì)報(bào)錯(cuò):
Consider defining a bean of type 'com.netflix.discovery.DiscoveryClient' in your configuration.
測(cè)試
我們分別啟動(dòng)服務(wù)調(diào)用發(fā)和被調(diào)用方,這里我啟動(dòng)了5
個(gè)user-center
,同時(shí)eureka
服務(wù)也啟動(dòng)了兩個(gè),這個(gè)兩個(gè)注冊(cè)中心互相注冊(cè)監(jiān)控,在實(shí)際應(yīng)用中也可以確保服務(wù)穩(wěn)定性。5
個(gè)user-center
有2
個(gè)注冊(cè)在8999
的注冊(cè)中心上,有3
個(gè)注冊(cè)在9000
的注冊(cè)中心上:
然后,我們?cè)L問(wèn)product
的ribbon
接口:
瀏覽器返回結(jié)果如下:
同時(shí),在user-center
端口為8771
和8775
的控制臺(tái),會(huì)看到如下信息:
為什么只有8771
和8775
收到了請(qǐng)求,因?yàn)?code>8771和8775
都注冊(cè)到了8999
的注冊(cè)中心,而且我們的product-service
也注冊(cè)在該服務(wù)中心,所以就只調(diào)用了8771
和8775
這兩個(gè)服務(wù):
根據(jù)運(yùn)行結(jié)果,我們還發(fā)現(xiàn)在10
次請(qǐng)求中,8771
和8775
各處理五次,這里面還有一個(gè)潛藏的知識(shí)點(diǎn):Ribbon
默認(rèn)的負(fù)載策略是輪詢策略,這樣可以確保同一個(gè)注冊(cè)中心下的所有服務(wù)節(jié)點(diǎn)接收到同樣的請(qǐng)求頻次。
如果你把user-center
(5
個(gè)服務(wù))、product-serive
都注冊(cè)在同一個(gè)注冊(cè)中心,那么你會(huì)發(fā)現(xiàn)每個(gè)服務(wù)都會(huì)被調(diào)用2
次。
總結(jié)
總體來(lái)說(shuō),Ribbon
對(duì)用戶來(lái)說(shuō)感知確實(shí)不夠強(qiáng),而且經(jīng)過(guò)我的測(cè)試,我發(fā)現(xiàn)就算拿掉ribbon
的依賴,依然可以正常負(fù)載均衡,這是因?yàn)?code>eureka-client的依賴,已經(jīng)添加過(guò)ribbon
的依賴了:
好了,今天的Ribbon
分享就先到這里吧,我們明天分享基于Feign
的聲明式調(diào)用。
到此這篇關(guān)于spring-cloud服務(wù)之間的調(diào)用之ribbon的文章就介紹到這了,更多相關(guān)spring cloud服務(wù)調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis-Plus中公共字段的統(tǒng)一處理的實(shí)現(xiàn)
在開(kāi)發(fā)中經(jīng)常遇到多個(gè)實(shí)體類有共同的屬性字段,這些字段屬于公共字段,本文主要介紹了MyBatis-Plus中公共字段的統(tǒng)一處理的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08Java超詳細(xì)教你寫一個(gè)學(xué)籍管理系統(tǒng)案例
這篇文章主要介紹了怎么用Java來(lái)寫一個(gè)學(xué)籍管理系統(tǒng),學(xué)籍管理主要涉及到學(xué)生信息的增刪查改,本篇將詳細(xì)的實(shí)現(xiàn),感興趣的朋友跟隨文章往下看看吧2022-03-03Java?對(duì)象在?JVM?中的內(nèi)存布局超詳細(xì)解說(shuō)
這篇文章主要介紹了Java?對(duì)象在?JVM?中的內(nèi)存布局超詳細(xì)解說(shuō),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09JDK8時(shí)間相關(guān)類超詳細(xì)總結(jié)(含多個(gè)實(shí)例)
jdk1.8的一些新特性簡(jiǎn)化了代碼的寫法,減少了部分開(kāi)發(fā)量,下面這篇文章主要給大家介紹了關(guān)于JDK8時(shí)間相關(guān)類超詳細(xì)總結(jié),文中包含了多個(gè)實(shí)例代碼,需要的朋友可以參考下2023-01-01Java正則表達(dá)式判斷是否包含數(shù)字、字母、特殊字符及中文的多種方法
這篇文章主要給大家介紹了關(guān)于Java正則表達(dá)式判斷是否包含數(shù)字、字母、特殊字符及中文的多種方法,Java正則表達(dá)式在字符串處理和模式匹配中扮演著重要角色,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08springboot 使用ThreadLocal的實(shí)例代碼
這篇文章主要介紹了springboot 使用ThreadLocal的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12java設(shè)計(jì)模式之策略模式在促銷活動(dòng)場(chǎng)景中的使用案例
這篇文章主要為大家介紹了java設(shè)計(jì)模式之策略模式在促銷活動(dòng)場(chǎng)景中案例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05