在微服務(wù)架構(gòu)中,業(yè)務(wù)都會(huì)被拆分成一個(gè)獨(dú)立的服務(wù),服務(wù)與服務(wù)的通訊是基于httprestful的。Springcloud有兩種服務(wù)調(diào)用方式,一種是ribbon+restTemplate模式,另一種是feign模式:
Ribbon+RestTemplate
Ribbon是一個(gè)基于HTTP和TCP客戶端的負(fù)載均衡的工具。它可以 在客戶端 配置RibbonServerList(服務(wù)端列表),使用HttpClient或RestTemplate模擬http請(qǐng)求,步驟比較繁瑣。
Feign
Feign是在Ribbon的基礎(chǔ)上進(jìn)行了一次改進(jìn),是一個(gè)使用起來(lái)更加方便的HTTP客戶端。采用接口的方式,只需要?jiǎng)?chuàng)建一個(gè)接口,然后在上面添加注解即可,將需要調(diào)用的其他服務(wù)的方法定義成抽象方法即可,不需要自己構(gòu)建 http請(qǐng)求。然后就像是調(diào)用自身工程的方法調(diào)用,而感覺(jué)不到是調(diào)用遠(yuǎn)程方法,使得編寫(xiě)客戶端變得非常容易。
Feign和RestTemplate都內(nèi)置了Ribbon
在SpringCloud中,有多個(gè)組件可以起到服務(wù)發(fā)現(xiàn)代理的作用,但一般比較常用、較專(zhuān)業(yè)、可用性較高的是Eureka,Eureka分為Server和Client,Server是注冊(cè)中心,Client是注冊(cè)/調(diào)用方,接下來(lái)我們構(gòu)建EurekaServer來(lái)啟動(dòng)一個(gè)服務(wù)發(fā)現(xiàn)代理。
1.創(chuàng)建一個(gè)maven項(xiàng)目,在pom.xml添加依賴(lài)jar文件
2.創(chuàng)建application.yml文件
接下來(lái),需要?jiǎng)?chuàng)建src/main/resources/application.yml文件(或application.properties,兩者作用是一樣的,但.yml文件為樹(shù)形結(jié)構(gòu),更容易理解)。添加如下配置:
###服務(wù)端口號(hào)
server:
port:1011
###服務(wù)名稱(chēng)
spring:
application:
name:app-eureka-center
eureka:
instance:
#注冊(cè)中心地址
hostname:192.168.199.101
###客戶端調(diào)用地址
client:
serviceUrl:
defaultZone:http://192.168.199.101:1011/eureka/
###是否將自己注冊(cè)到Eureka服務(wù)中,因?yàn)樵搼?yīng)用本身就是注冊(cè)中心,不需要再注冊(cè)自己(集群的時(shí)候?yàn)閠rue)
register-with-eureka:false
###是否從Eureka中獲取注冊(cè)信息,因?yàn)樽约簽樽?cè)中心,不會(huì)在該應(yīng)用中的檢索服務(wù)信息
fetch-registry:false
server:
enable-self-preservation:true
3.創(chuàng)建服務(wù)啟動(dòng)類(lèi)
這一步是在啟動(dòng)類(lèi)中添加@EnableEurekaServer注解,就可以讓此應(yīng)用程序成為一個(gè)Eureka服務(wù)。
@SpringBootApplication
@EnableEurekaServer//申明這是一個(gè)Eureka服務(wù)
publicclass SncApplication {
publicstatic void main(String[] args) {
SpringApplication.run(SncApplication.class,args);
}
}
4.項(xiàng)目結(jié)構(gòu)圖
5.測(cè)試訪問(wèn)Eureka注冊(cè)中心
如上圖顯示,注冊(cè)中心已搭建成功
1.創(chuàng)建一個(gè)maven項(xiàng)目,在pom.xml中導(dǎo)入依賴(lài)jar
上面的pom文件為非完整版,只把其中的重要配置貼出來(lái)了
2.創(chuàng)建application.properties文件
在src/main/java/resources/application.yml創(chuàng)建如下配置:
spring.application.name=base-user-center
server.port=10011
eureka.client.serviceUrl.defaultZone=http://192.168.199.101:1011/eureka/
3.創(chuàng)建UserController接口
@RestController
@RequestMapping("/user")
publicclass UserController {
@RequestMapping("/getUserList")
@ResponseBody
publicModelMap getUserList() {
ModelMapmodelMap = new ModelMap();
List
userList.add("用戶1");
userList.add("用戶2");
userList.add("用戶3");
modelMap.put("data",userList);
returnmodelMap;
}
}
4.創(chuàng)建啟動(dòng)類(lèi)
@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
publicclass SncApplication {
publicstatic void main(String[] args) {
SpringApplication.run(SncApplication.class,args);
}
}
5.測(cè)試服務(wù)是否正常
如上圖顯示,接口服務(wù)正常
6.在eureka注冊(cè)中心上的效果
在這個(gè)demo中,我創(chuàng)建了一個(gè)名叫base-user-center的服務(wù),在啟動(dòng)后,可以在Eureka管理界面看到該服務(wù)。
可以看到本地啟動(dòng)的base-user-center服務(wù)已經(jīng)注冊(cè)成功
服務(wù)注冊(cè)成功后,我們可以使用另外的服務(wù)客戶端來(lái)查找和調(diào)用該服務(wù)base-user-center,而不用知道該服務(wù)的位置。現(xiàn)在我們創(chuàng)建另一個(gè)服務(wù),讓這兩個(gè)服務(wù)互相調(diào)用。
為了實(shí)現(xiàn)這個(gè)目的,我們需要引入客戶端庫(kù)。能夠?qū)崿F(xiàn)服務(wù)查找和調(diào)用功能的在SpringCloud中有三個(gè)客戶端,分別為:
Spring DiscoveryClient.
RestTemplate
Netflix Feign
下面我們使用Feign來(lái)實(shí)現(xiàn)服務(wù)調(diào)用。
1.創(chuàng)建一個(gè)maven項(xiàng)目,在pom.xml中導(dǎo)入依賴(lài)jar文件
2.創(chuàng)建application.properties文件
spring.application.name=snc-kanban-service
server.port=30006
eureka.client.serviceUrl.defaultZone=http://192.168.199.101:1011/eureka/
3.創(chuàng)建feign客戶端接口
我們通過(guò)@FeignClient注解來(lái)標(biāo)志服務(wù),其中的name為在Eureka中注冊(cè)的應(yīng)用ID。在這個(gè)接口中的send方法中,我們加上@RequestMapping注解來(lái)將此方法的實(shí)現(xiàn)映射到url。參數(shù)的傳遞通過(guò)@PathVariable注解將接口參數(shù)映射到url參數(shù)。遠(yuǎn)程接口的返回值將自動(dòng)映射到接口返回值。
@FeignClient(name= "BASE-USER-CENTER")
publicinterface UserService {
@RequestMapping(value= "/user/getUserList")
publicModelMap getUserList();
}
4.創(chuàng)建消費(fèi)者接口
@RestController
@RequestMapping("/order")
publicclass OrderController {
@Autowired
UserServiceuserService;
@RequestMapping("/getUserList")
publicModelMap getUserList() {
returnuserService.getUserList();
}
5.創(chuàng)建啟動(dòng)類(lèi)
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
publicclass SncApplication {
publicstatic void main(String[] args) {
SpringApplication.run(SncApplication.class,args);
}
}
6.測(cè)試消費(fèi)者調(diào)用服務(wù)提供者接口
如上圖所示,消費(fèi)者成功調(diào)用了服務(wù)者提供的接口
在上面的過(guò)程中,我們構(gòu)建了一整個(gè)服務(wù)注冊(cè)發(fā)現(xiàn)調(diào)用流程,在其中可以發(fā)現(xiàn)很多問(wèn)題,比如Eureka掛掉怎么辦,客戶端聯(lián)系不上Eureka怎么辦,似乎這樣的架構(gòu)是非常脆弱的,但SpringCloud提供了一系列的機(jī)制來(lái)保證可用性,下面來(lái)進(jìn)行分析。
1.服務(wù)發(fā)現(xiàn)集群
每個(gè)服務(wù)實(shí)例啟動(dòng)時(shí)會(huì)通過(guò)一個(gè)或多個(gè)服務(wù)發(fā)現(xiàn)代理進(jìn)行注冊(cè)它們的IP等信息,但即使只在一個(gè)服務(wù)發(fā)現(xiàn)節(jié)點(diǎn)注冊(cè)。由于服務(wù)發(fā)現(xiàn)代理間使用了數(shù)據(jù)傳播的點(diǎn)對(duì)點(diǎn)模型,每個(gè)節(jié)點(diǎn)的數(shù)據(jù)都會(huì)同步到服務(wù)發(fā)現(xiàn)集群中的所有節(jié)點(diǎn)。
在注冊(cè)成功后,每個(gè)服務(wù)實(shí)例會(huì)按時(shí)間間隔發(fā)送心跳包,來(lái)推送自身的狀態(tài),一段時(shí)間沒(méi)有發(fā)送心跳包時(shí),會(huì)被從服務(wù)實(shí)例池中移除。
通過(guò)這樣的方式,即使單個(gè)服務(wù)發(fā)現(xiàn)代理節(jié)點(diǎn)宕機(jī),其他節(jié)點(diǎn)也能繼續(xù)提供同樣的服務(wù)。
2.客戶端負(fù)載均衡
上圖是加入了客戶端緩存和負(fù)載均衡,和直接請(qǐng)求服務(wù)發(fā)現(xiàn)代理相比,進(jìn)行了如下優(yōu)化:
首先請(qǐng)求服務(wù)發(fā)現(xiàn)代理,獲取它請(qǐng)求的服務(wù)的所有實(shí)例,并在本地進(jìn)行緩存。
當(dāng)需要調(diào)用該服務(wù)時(shí),首先從緩存中查找所有實(shí)例信息,再使用負(fù)載均衡算法,選擇一個(gè)實(shí)例進(jìn)行調(diào)用。
客戶端將定期請(qǐng)求服務(wù)發(fā)現(xiàn)代理,刷新緩存數(shù)據(jù)。
如果本地緩存數(shù)據(jù)錯(cuò)誤,請(qǐng)求到了錯(cuò)誤的實(shí)例,本地緩存將會(huì)失效,并重新請(qǐng)求服務(wù)發(fā)現(xiàn)代理的數(shù)據(jù)。
通過(guò)以上的機(jī)制,能最大程度地保證客戶端能夠正確地查找到所需服務(wù)的實(shí)例信息。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/130165.html
摘要:下一代服務(wù)端開(kāi)發(fā)下一代服務(wù)端開(kāi)發(fā)第部門(mén)快速開(kāi)始第章快速開(kāi)始環(huán)境準(zhǔn)備,,快速上手實(shí)現(xiàn)一個(gè)第章企業(yè)級(jí)服務(wù)開(kāi)發(fā)從到語(yǔ)言的缺點(diǎn)發(fā)展歷程的缺點(diǎn)為什么是產(chǎn)生的背景解決了哪些問(wèn)題為什么是的發(fā)展歷程容器的配置地獄是什么從到下一代企業(yè)級(jí)服務(wù)開(kāi)發(fā)在移動(dòng)開(kāi)發(fā)領(lǐng)域 《 Kotlin + Spring Boot : 下一代 Java 服務(wù)端開(kāi)發(fā) 》 Kotlin + Spring Boot : 下一代 Java...
摘要:既然要組集群那就涉及諸如的資源調(diào)度管理等等一系列問(wèn)題。目前涉及集群的三個(gè)主要的技術(shù)無(wú)外乎三種。從本文開(kāi)始作者將會(huì)一一實(shí)踐這幾種主要的集群技術(shù),話不多說(shuō),現(xiàn)在開(kāi)始。完全運(yùn)行于內(nèi)存中,體積小,啟動(dòng)快。 showImg(https://segmentfault.com/img/remote/1460000015723680); 前言 相信Docker技術(shù)大家都有所了解,單個(gè)Docker能發(fā)...
摘要:本文章的源碼再文章末尾什么是查詢緩存有一級(jí)緩存和二級(jí)緩存。默認(rèn)開(kāi)啟一級(jí)緩存。證明了一級(jí)緩存只是在數(shù)據(jù)庫(kù)會(huì)話內(nèi)部共享的。但是,整合到中后,一級(jí)緩存就會(huì)被關(guān)閉。根據(jù)時(shí)間表比如沒(méi)有刷新間隔緩存不會(huì)以任何時(shí)間順序來(lái)刷新。 倉(cāng)庫(kù)地址:spring-boot-learning歡迎star、fork,給作者一些鼓勵(lì) 學(xué)習(xí)SpringBoot集成Mybatis的第二章,了解到Mybatis自帶的緩存機(jī)...
摘要:本文章的源碼再文章末尾什么是查詢緩存有一級(jí)緩存和二級(jí)緩存。默認(rèn)開(kāi)啟一級(jí)緩存。證明了一級(jí)緩存只是在數(shù)據(jù)庫(kù)會(huì)話內(nèi)部共享的。但是,整合到中后,一級(jí)緩存就會(huì)被關(guān)閉。根據(jù)時(shí)間表比如沒(méi)有刷新間隔緩存不會(huì)以任何時(shí)間順序來(lái)刷新。 倉(cāng)庫(kù)地址:spring-boot-learning歡迎star、fork,給作者一些鼓勵(lì) 學(xué)習(xí)SpringBoot集成Mybatis的第二章,了解到Mybatis自帶的緩存機(jī)...
摘要:本文章的源碼再文章末尾什么是查詢緩存有一級(jí)緩存和二級(jí)緩存。默認(rèn)開(kāi)啟一級(jí)緩存。證明了一級(jí)緩存只是在數(shù)據(jù)庫(kù)會(huì)話內(nèi)部共享的。但是,整合到中后,一級(jí)緩存就會(huì)被關(guān)閉。根據(jù)時(shí)間表比如沒(méi)有刷新間隔緩存不會(huì)以任何時(shí)間順序來(lái)刷新。 學(xué)習(xí)SpringBoot集成Mybatis的第二章,了解到Mybatis自帶的緩存機(jī)制,在部署的時(shí)候踩過(guò)了一些坑。在此記錄和分享一下Mybatis的緩存作用。 本文章的源碼再...
閱讀 1346·2023-01-11 13:20
閱讀 1684·2023-01-11 13:20
閱讀 1132·2023-01-11 13:20
閱讀 1858·2023-01-11 13:20
閱讀 4100·2023-01-11 13:20
閱讀 2704·2023-01-11 13:20
閱讀 1385·2023-01-11 13:20
閱讀 3597·2023-01-11 13:20