一、场景再现
假设我们有这样一个场景:
用户付款成功后,扣除用户金额,还要减少仓库数量。按照微服务的设计理念,用户具有至少以下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看看服务名称