feign的restful调用
1、说明:
Spring Cloud的子项目之一,提供了springboot下微服务远程调用的解决方案,目前在SpringCloud技术栈中,调用服务用得最多的就是OpenFeign,OpenFeign支持申明式调用和继承式调用,这里调用采取申明式;
2、FeignClient
@FeignClient用于创建声明是API接口,该接口是RESTful风格的。Feign被设计成插拔式的,可注入其他组件和Feign一起使用。最典型的是如果Ribbon可用,Feign会和Ribbon相结合进行负载均衡。
@FeignClient (name = "providerService" , url = "${provider.host:}" , configuration = ABCConfiguration. class , path= "test" ) public interface ProviderService { @GetMapping ( "/provider/list" ) String list(); } |
name(value): 服务发现的服务名,获取nacos等服务的注册中心找到服务,按照负载策略找到一个服务的ip和端口
url:当url不为空的时候,优先使用url的服务地址调用接口,可以用于测试或者调用第三方非注册中心注册的服务调用,可以使用参数注入如${provider.host:}
configuration:增加的FeignClient的配置Encoder、Decoder、LogLevel、Contract或者实现apply的拦截器等等
path:本feignClient下的接口地址的统一前缀
3、超时配置
feign.client.config. default .connect-timeout= 2000 feign.client.config. default .read-timeout= 10000 |
上面的配置中配置了连接超时和读取超时,其中的default是默认配置,要配置某一个服务可以 feign.client.config.providerService.connect-timeout=2000
注意:如果使用了ribbon等,此处的配置和ribbon都会生效,谁的时间短谁生效
4、openFeign + ribbon
feign 默认已启用了 ribbon 负载均衡和重试机制,
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用
#连接超时 此处的时间和feign的时间比较,按照小的生效 ribbon.ConnectTimeout= 60000 #请求处理的超时时间, 5 分钟 ribbon.ReadTimeout= 60000 #所有操作都重试 ribbon.OkToRetryOnAllOperations= true #重试发生,更换节点数最大值 ribbon.MaxAutoRetriesNextServer= 1 #单个节点重试最大值 ribbon.MaxAutoRetries= 1 |
5、调用第三方接口加密的示例
在2中的代码中@FeignClient( configuration = FeignClientConfigurationSms.class ...),
FeignClientConfigurationSms在此处非feignClient的配置,而是一个拦截器,我们在此处可以加密调用消息平台的接口
如下:
@Component public class ABCConfiguration implements RequestInterceptor { @Override public void apply(RequestTemplate template) { String appId = SpringContext.getProperty( "selected.sms.appId" ); long ts = DateUtil.currentSeconds(); String sign = ApiSecuritySHA.sha256(SpringContext.getProperty( "selected.sms.secretKey" ), appId + ts); template.header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType()); template.header(HttpHeaders.ACCEPT_CHARSET, ContentType.APPLICATION_JSON.getCharset().name()); template.header(HttpHeaders.CONNECTION, ContentType.APPLICATION_JSON.getCharset().name()); template.header( "ts" ,ts+ "" ); template.header( "appId" , appId); template.header( "sign" ,sign); } } |