《重新定义Spring Cloud实战》
Feign是一个声明式的WebService客户端。它的出现使开发WebService客户端变得很简单。使用Feign只需要创建一个接口加上对应的注解,比如:FeignClient注解。Feign有可插拔的注解,包括Feign注解和JAXRS注解。Feign也支持编码器和解码器,SpringCloudOpenFeign对Feign进行增强支持SpringMVC注解,可以像SpringWeb一样使用HttpMessageConverters等。
环境配置
在Demo服务中,调用 github openAPI 的接口
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
@Configuration
@EnableFeignClients
public class HelloFeignServiceConfig {
/**
*
* Logger.Level 的具体级别如下:
NONE:不记录任何信息
BASIC:仅记录请求方法、URL以及响应状态码和执行时间
HEADERS:除了记录 BASIC级别的信息外,还会记录请求和响应的头信息
FULL:记录所有请求与响应的明细,包括头信息、请求体、元数据
* @return
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
@FeignClient(name = "github-client", url = "https://api.github.com", configuration = HelloFeignServiceConfig.class)
public interface HelloFeignService {
@RequestMapping(value = "/search/repositories", method = RequestMethod.GET)
String searchRepo(@RequestParam("q") String queryStr);
}
@RestController
public class HelloFeignController {
@Autowired
private HelloFeignService helloFeignService;
@GetMapping(value = "/search/github")
public String searchGithubRepoByStr(@RequestParam("str") String queryStr) {
return helloFeignService.searchRepo(queryStr);
}
}
Feign在默认情况下使用的是JDK原生的URLConnection发送HTTP请求,没有连接池,但是对每个地址会保持一个长连接,即利用HTTP的persistenceconnection。我们可以用Apache的HTTPClient替换Feign原始的HTTPClient,通过设置连接池、超时时间等对服务之间的调用调优。SpringCloud从Brixtion.SR5版本开始支持这种替换,接下来介绍一下如何用HTTPClient和okhttp去替换Feign默认的Client。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>8.17.0</version>
</dependency>
feign:
httpclient:
enabled: true
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
feign:
httpclient:
enabled: false
okhttp:
enabled: true
@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignOkHttpConfig {
@Bean
public okhttp3.OkHttpClient okHttpClient(){
return new okhttp3.OkHttpClient.Builder()
//设置连接超时
.connectTimeout(60, TimeUnit.SECONDS)
//设置读超时
.readTimeout(60, TimeUnit.SECONDS)
//设置写超时
.writeTimeout(60,TimeUnit.SECONDS)
//是否自动重连
.retryOnConnectionFailure(true)
.connectionPool(new ConnectionPool())
//构建OkHttpClient对象
.build();
}
}
在进行认证鉴权的时候,不管是jwt,还是security,当使用Feign时就会发现外部请求到A服务的时候,A服务是可以拿到Token的,然而当服务使用Feign调用B服务时,Token就会丢失,从而认证失败。解决方法相对比较简单,需要做的就是在Feign调用的时候,向请求头里面添加需要传递的Token。
@Component
public class FeignTokenInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("oauthToken", "请求token");
}
}
Feign默认使用 Jackson 进行请求参数和响应数据的JSON序列化。
@Configuration
public class FeignConfig {
@Bean
public Encoder feignEncoder() {
return new SpringEncoder(feignHttpMessageConverter());
}
private ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
final HttpMessageConverters httpMessageConverters =
new HttpMessageConverters(getFastJsonConverter());
return () -> httpMessageConverters;
}
private FastJsonHttpMessageConverter getFastJsonConverter() {
FastJsonHttpMessageConverter converter =
new FastJsonHttpMessageConverter();
List<MediaType> supportedMediaTypes = new ArrayList<>();
MediaType mediaTypeJson =
MediaType.valueOf(MediaType.APPLICATION_JSON_UTF8_VALUE);
supportedMediaTypes.add(mediaTypeJson);
converter.setSupportedMediaTypes(supportedMediaTypes);
FastJsonConfig config = new FastJsonConfig();
config.getSerializeConfig()
.put(Json.class, new SwaggerJsonSerializer());
config.setSerializerFeatures(
SerializerFeature.DisableCircularReferenceDetect);
converter.setFastJsonConfig(config);
return converter;
}
}
当Feign和Ribbon整合了Hystrix之后,可能会出现首次调用失败的问题,造成该问题出现的原因分析如下:Hystrix默认的超时时间是1秒,如果超过这个时间尚未做出响应,将会进入fallback代码。由于Bean的装配以及懒加载机制等,Feign首次请求都会比较慢。如果这个响应时间大于1秒,就会出现请求失败的问题。
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
hystrix.command.default.execution.timeout.enabled=false
feign.hystrix.enabled=false
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。