微服務(wù)間調(diào)用Retrofit在Spring?Cloud?Alibaba中的使用
前置知識
在微服務(wù)項(xiàng)目中,如果我們想實(shí)現(xiàn)服務(wù)間調(diào)用,一般會(huì)選擇Feign。之前介紹過一款HTTP客戶端工具Retrofit
,配合SpringBoot非常好用!其實(shí)Retrofit
不僅支持普通的HTTP調(diào)用,還能支持微服務(wù)間的調(diào)用,負(fù)載均衡和熔斷限流都能實(shí)現(xiàn)。今天我們來介紹下Retrofit
在Spring Cloud Alibaba下的使用,希望對大家有所幫助!
SpringBoot實(shí)戰(zhàn)電商項(xiàng)目mall(50k+star)地址:
https://github.com/macrozheng/mall
本文主要介紹Retrofit在Spring Cloud Alibaba下的使用,需要用到Nacos和Sentinel,對這些技術(shù)不太熟悉的朋友可以先參考下之前的文章。
Spring Cloud Alibaba:Nacos 作為注冊中心和配置中心使用
Spring Cloud Alibaba:Sentinel實(shí)現(xiàn)熔斷與限流
還在用HttpUtil?試試這款優(yōu)雅的HTTP客戶端工具吧,跟SpringBoot絕配!
搭建
在使用之前我們需要先搭建Nacos和Sentinel,再準(zhǔn)備一個(gè)被調(diào)用的服務(wù),使用之前的nacos-user-service
即可。
首先從官網(wǎng)下載Nacos,這里下載的是nacos-server-1.3.0.zip
文件,
下載地址:https://github.com/alibaba/nacos/releases
解壓安裝包到指定目錄,直接運(yùn)行bin
目錄下的startup.cmd
,運(yùn)行成功后訪問Nacos,賬號密碼均為nacos
,訪問地址:http://localhost:8848/nacos
接下來從官網(wǎng)下載Sentinel,這里下載的是sentinel-dashboard-1.6.3.jar
文件,
下載地址:https://github.com/alibaba/Sentinel/releases
下載完成后輸入如下命令運(yùn)行Sentinel控制臺;
java -jar sentinel-dashboard-1.6.3.jar
Sentinel控制臺默認(rèn)運(yùn)行在8080
端口上,登錄賬號密碼均為sentinel
,通過如下地址可以進(jìn)行訪問:http://localhost:8080
接下來啟動(dòng)nacos-user-service
服務(wù),該服務(wù)中包含了對User對象的CRUD操作接口,啟動(dòng)成功后它將會(huì)在Nacos中注冊。
/** * Created by macro on 2019/8/29. */ @RestController @RequestMapping("/user") public class UserController { private Logger LOGGER = LoggerFactory.getLogger(this.getClass()); @Autowired private UserService userService; @PostMapping("/create") public CommonResult create(@RequestBody User user) { userService.create(user); return new CommonResult("操作成功", 200); } @GetMapping("/{id}") public CommonResult<User> getUser(@PathVariable Long id) { User user = userService.getUser(id); LOGGER.info("根據(jù)id獲取用戶信息,用戶名稱為:{}",user.getUsername()); return new CommonResult<>(user); } @GetMapping("/getUserByIds") public CommonResult<List<User>> getUserByIds(@RequestParam List<Long> ids) { List<User> userList= userService.getUserByIds(ids); LOGGER.info("根據(jù)ids獲取用戶信息,用戶列表為:{}",userList); return new CommonResult<>(userList); } @GetMapping("/getByUsername") public CommonResult<User> getByUsername(@RequestParam String username) { User user = userService.getByUsername(username); return new CommonResult<>(user); } @PostMapping("/update") public CommonResult update(@RequestBody User user) { userService.update(user); return new CommonResult("操作成功", 200); } @PostMapping("/delete/{id}") public CommonResult delete(@PathVariable Long id) { userService.delete(id); return new CommonResult("操作成功", 200); } }
使用
接下來我們來介紹下Retrofit的基本使用,包括服務(wù)間調(diào)用、服務(wù)限流和熔斷降級。
集成與配置
首先在pom.xml
中添加Nacos、Sentinel和Retrofit相關(guān)依賴;
<dependencies> <!--Nacos注冊中心依賴--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--Sentinel依賴--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!--Retrofit依賴--> <dependency> <groupId>com.github.lianjiatech</groupId> <artifactId>retrofit-spring-boot-starter</artifactId> <version>2.2.18</version> </dependency> </dependencies>
然后在application.yml
中對Nacos、Sentinel和Retrofit進(jìn)行配置,Retrofit配置下日志和開啟熔斷降級即可;
server: port: 8402 spring: application: name: nacos-retrofit-service cloud: nacos: discovery: server-addr: localhost:8848 #配置Nacos地址 sentinel: transport: dashboard: localhost:8080 #配置sentinel dashboard地址 port: 8719 retrofit: log: # 啟用日志打印 enable: true # 日志打印攔截器 logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor # 全局日志打印級別 global-log-level: info # 全局日志打印策略 global-log-strategy: body # 熔斷降級配置 degrade: # 是否啟用熔斷降級 enable: true # 熔斷降級實(shí)現(xiàn)方式 degrade-type: sentinel # 熔斷資源名稱解析器 resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser
- 再添加一個(gè)Retrofit的Java配置,配置好選擇服務(wù)實(shí)例的Bean即可。
/** * Retrofit相關(guān)配置 * Created by macro on 2022/1/26. */ @Configuration public class RetrofitConfig { @Bean @Autowired public ServiceInstanceChooser serviceInstanceChooser(LoadBalancerClient loadBalancerClient) { return new SpringCloudServiceInstanceChooser(loadBalancerClient); } }
服務(wù)間調(diào)用
使用Retrofit實(shí)現(xiàn)微服務(wù)間調(diào)用非常簡單,直接使用@RetrofitClient
注解,通過設(shè)置serviceId
為需要調(diào)用服務(wù)的ID即可;
/** * 定義Http接口,用于調(diào)用遠(yuǎn)程的User服務(wù) * Created by macro on 2019/9/5. */ @RetrofitClient(serviceId = "nacos-user-service", fallback = UserFallbackService.class) public interface UserService { @POST("/user/create") CommonResult create(@Body User user); @GET("/user/{id}") CommonResult<User> getUser(@Path("id") Long id); @GET("/user/getByUsername") CommonResult<User> getByUsername(@Query("username") String username); @POST("/user/update") CommonResult update(@Body User user); @POST("/user/delete/{id}") CommonResult delete(@Path("id") Long id); }
我們可以啟動(dòng)2個(gè)nacos-user-service
服務(wù)和1個(gè)nacos-retrofit-service
服務(wù),此時(shí)Nacos注冊中心顯示如下;
然后通過Swagger進(jìn)行測試,調(diào)用下獲取用戶詳情的接口,發(fā)現(xiàn)可以成功返回遠(yuǎn)程數(shù)據(jù),訪問地址:http://localhost:8402/swagger-ui/
查看nacos-retrofit-service
服務(wù)打印的日志,兩個(gè)實(shí)例的請求調(diào)用交替打印,我們可以發(fā)現(xiàn)Retrofit通過配置serviceId
即可實(shí)現(xiàn)微服務(wù)間調(diào)用和負(fù)載均衡。
服務(wù)限流
Retrofit的限流功能基本依賴Sentinel,和直接使用Sentinel并無區(qū)別,我們創(chuàng)建一個(gè)測試類RateLimitController
來試下它的限流功能;
/** * 限流功能 * Created by macro on 2019/11/7. */ @Api(tags = "RateLimitController",description = "限流功能") @RestController @RequestMapping("/rateLimit") public class RateLimitController { @ApiOperation("按資源名稱限流,需要指定限流處理邏輯") @GetMapping("/byResource") @SentinelResource(value = "byResource",blockHandler = "handleException") public CommonResult byResource() { return new CommonResult("按資源名稱限流", 200); } @ApiOperation("按URL限流,有默認(rèn)的限流處理邏輯") @GetMapping("/byUrl") @SentinelResource(value = "byUrl",blockHandler = "handleException") public CommonResult byUrl() { return new CommonResult("按url限流", 200); } @ApiOperation("自定義通用的限流處理邏輯") @GetMapping("/customBlockHandler") @SentinelResource(value = "customBlockHandler", blockHandler = "handleException",blockHandlerClass = CustomBlockHandler.class) public CommonResult blockHandler() { return new CommonResult("限流成功", 200); } public CommonResult handleException(BlockException exception){ return new CommonResult(exception.getClass().getCanonicalName(),200); } }
接下來在Sentinel控制臺創(chuàng)建一個(gè)根據(jù)資源名稱
進(jìn)行限流的規(guī)則;
之后我們以較快速度訪問該接口時(shí),就會(huì)觸發(fā)限流,返回如下信息。
熔斷降級
Retrofit的熔斷降級功能也基本依賴于Sentinel,我們創(chuàng)建一個(gè)測試類CircleBreakerController
來試下它的熔斷降級功能;
/** * 熔斷降級 * Created by macro on 2019/11/7. */ @Api(tags = "CircleBreakerController",description = "熔斷降級") @RestController @RequestMapping("/breaker") public class CircleBreakerController { private Logger LOGGER = LoggerFactory.getLogger(CircleBreakerController.class); @Autowired private UserService userService; @ApiOperation("熔斷降級") @RequestMapping(value = "/fallback/{id}",method = RequestMethod.GET) @SentinelResource(value = "fallback",fallback = "handleFallback") public CommonResult fallback(@PathVariable Long id) { return userService.getUser(id); } @ApiOperation("忽略異常進(jìn)行熔斷降級") @RequestMapping(value = "/fallbackException/{id}",method = RequestMethod.GET) @SentinelResource(value = "fallbackException",fallback = "handleFallback2", exceptionsToIgnore = {NullPointerException.class}) public CommonResult fallbackException(@PathVariable Long id) { if (id == 1) { throw new IndexOutOfBoundsException(); } else if (id == 2) { throw new NullPointerException(); } return userService.getUser(id); } public CommonResult handleFallback(Long id) { User defaultUser = new User(-1L, "defaultUser", "123456"); return new CommonResult<>(defaultUser,"服務(wù)降級返回",200); } public CommonResult handleFallback2(@PathVariable Long id, Throwable e) { LOGGER.error("handleFallback2 id:{},throwable class:{}", id, e.getClass()); User defaultUser = new User(-2L, "defaultUser2", "123456"); return new CommonResult<>(defaultUser,"服務(wù)降級返回",200); } }
由于我們并沒有在nacos-user-service
中定義id為4
的用戶,調(diào)用過程中會(huì)產(chǎn)生異常,所以訪問如下接口會(huì)返回服務(wù)降級結(jié)果,返回我們默認(rèn)的用戶信息。
總結(jié)
Retrofit給了我們除Feign和Dubbo之外的第三種微服務(wù)間調(diào)用選擇,使用起來還是非常方便的。記得之前在使用Feign的過程中,實(shí)現(xiàn)方的Controller經(jīng)常要抽出一個(gè)接口來,方便調(diào)用方來實(shí)現(xiàn)調(diào)用,接口實(shí)現(xiàn)方和調(diào)用方的耦合度很高。如果當(dāng)時(shí)使用的是Retrofit的話,這種情況會(huì)大大改善??偟膩碚f,Retrofit給我們提供了更加優(yōu)雅的HTTP調(diào)用方式,不僅是在單體應(yīng)用中,在微服務(wù)應(yīng)用中也一樣!
參考資料
官方文檔:https://github.com/LianjiaTech/retrofit-spring-boot-starter
項(xiàng)目源碼地址 https://github.com/macrozheng/mall
以上就是微服務(wù)間調(diào)用Retrofit在Spring Cloud Alibaba中的使用的詳細(xì)內(nèi)容,更多關(guān)于Retrofit微服務(wù)調(diào)用Spring Cloud Alibaba的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
spring cloud 集成 ribbon負(fù)載均衡的實(shí)例代碼
spring Cloud Ribbon 是一個(gè)客戶端的負(fù)載均衡器,它提供對大量的HTTP和TCP客戶端的訪問控制。本文給大家介紹spring cloud 集成 ribbon負(fù)載均衡,感興趣的朋友跟隨小編一起看看吧2021-11-11Spring Boot web項(xiàng)目的TDD流程
TDD(Test-driven development) 測試驅(qū)動(dòng)開發(fā),簡單點(diǎn)說就是編寫測試,再編寫代碼。這是首要一條,不可動(dòng)搖的一條,先寫代碼后寫測試的都是假TDD。2021-05-05使用自定義Json注解實(shí)現(xiàn)輸出日志字段脫敏
這篇文章主要介紹了使用自定義Json注解實(shí)現(xiàn)輸出日志字段脫敏,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12java awt實(shí)現(xiàn)計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了java awt實(shí)現(xiàn)計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12Spring Boot處理全局統(tǒng)一異常的兩種方法與區(qū)別
這篇文章主要給大家介紹了關(guān)于Spring Boot處理全局統(tǒng)一異常的兩種方法與區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06Eclipse開發(fā)JavaWeb項(xiàng)目配置Tomcat的方法步驟
本文主要介紹了Eclipse開發(fā)JavaWeb項(xiàng)目配置Tomcat的方法步驟,首先介紹eclipse開發(fā)JavaWeb項(xiàng)目需要配置的相關(guān)環(huán)境,使用tomcat軟件在本地搭建服務(wù)器,然后再在eclipse環(huán)境下配置tomcat,感興趣的可以了解一下2021-08-08