一、場景再現
假設我們有這樣一個場景:
用戶付款成功后,扣除用戶金額,還要減少倉庫數量。按照微服務的設計理念,用戶具有至少以下3個服務(項目):
1、訂單
2、賬戶
3、倉庫
微服務之間都是相互獨立的服務,獨立的項目,獨立的數據庫。每個服務都對外暴露的接口用於調用。按照傳統的設計,我們
跨服務調用,可以用到tcp或者http,服務調用方,通過tcp_client或http_client通過url調用,將數據以流的方式傳遞就可以實現。
這種思想我們要能想到,但在現今時代,這樣做未免不太優雅。重復造輪子不是一件高效的做法。因此我們可以秉承”開箱即用,避
免重復造輪子“的理念通過以下方式實現:
多個服務注冊統一中心(nacos)
服務之間調用通過(feign)
負載均衡利用(feign自帶的ribben)
顧名思義需要滿足以下3點:
1、服務提供者與消費者都注冊到同一nacos中心的同一group
2、服務提供者暴露接口
3、服務消費者集成服務器提供者暴露的接口,然后加上feign注解,並配置相關feign信息
二、實戰
2.1、nacos注冊
此處不做贅述,見我其他nacos注冊文章
2.2、feign注冊
2.2.1、pom.xml
<!--服務之間接口調用--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
<!-服務提供者暴露的接口-->
<dependency>
<groupId>com.cbi.workflow</groupId>
<artifactId>cbi-workflow-api</artifactId>
<version>${cbi.workflow.version}</version>
</dependency>
2.2.2、application.yml
feign:
httpclient:
connection-timeout: 30000
enabled: false
okhttp:
enabled: true
#同一個服務實例的重試次數(MaxAutoRetries)、不同服務實例(MaxAutoRetriesNextServer)的重試次數都設置為0,即可達到不重試的目的。
ribbon:
#http讀取響應的超時時間
ReadTimeout: 30000
#http建立socket的超時時間
ConnectTimeout: 30000
#重試相同實例,同一台實例最大重試次數,包括首次調用
MaxAutoRetries: 0
#重試負載均衡其他的實例,最大重試2次,不包括首次的server
MaxAutoRetriesNextServer: 0
#重試所有操作,無論是請求超時或者socket read timeout都進行重試。一般都設置成false,慎用true,有冪等性隱患存在
OkToRetryOnAllOperations: false
management:
endpoints:
web:
exposure:
include: '*'
2.2.3、controller
//value就是nacos注冊的服務名稱,會被解析http://ip:port
//path就是服務提供者的統一全局攔截路徑,也就是spplication中配置的"context-path: /workflow",如果沒有就配置 "/"
@FeignClient(value = "workflow", path = "/workflow") public interface ICommonOperateFlowable extends IWorkflowHandler { }
解釋:
1、IWorkflowHandler 為服務提供方暴露的接口
2、通過install 服務提供者
3、pom引入服務提供者
4、
2.2.4、IWorkflowHandler
public interface IWorkflowHandler { /** * 發起流程 * * @param wfProcessExecBean * @return */ @PostMapping("/startProcess") ResponseBean startProcess(@RequestBody WfProcessExecBean wfProcessExecBean); }
2.2.5、常見錯誤
無法識別的feign_client
此時檢查配置,@FeignClient注解的名稱是否和服務提供方一致,可以打開nacos看看服務名稱