参考SpringCloud整合Feign(三)
搭建provider、consumer、api接口模块。
spring.application.name=feign-service
server.servlet.context-path=/feign-test
定义对外接口
@RequestMapping("/api/v1/group")
@FeignClient(value = "feign-service", path = "feign-test")
public interface TestApi {
@ApiOperation("添加素材")
@PostMapping("add")
String add(@RequestBody @Validated String req);
}
@FeignClient(value = "service-provider", contextId="OpenApi")
@FeignClient(value = "service-provider", contextId="OpenApi", url = "http://192.168.176.1:8080")
使用@RequestHeader注解参数。
使用@PathVariable注解(路径变量)或者@RequestParam注解(问号后面的键值对参数)接收请求参数。
使用@RequestParam注解(请求body中表单格式参数)、@RequestBody注解(请求体中raw类型json等格式的参数)接收请求参数。
只配置Consumer通过Feign到Provider的请求于响应的Gzip压缩。
消费者application.properties的配置
# Feign gzip压缩
# 请求开启gzip压缩
feign.compression.request.enabled=true
# 配置压缩支持的MIME TYPE
feign.compression.request.mime-types=text/xml,application/xml,application/json
# 配置压缩数据大小的最小阈值,默认2048
feign.compression.request.min-request-size=512
# 响应开启gzip压缩
feign.compression.response.enabled=true
对客户浏览器的请求已经Consumer对Provider的请求与响应都是些Gzip压缩。
消费者application.properties配置
# 全局gzip压缩
# 开启压缩
server.compression.enabled=true
# 配置压缩支持的MIME TYPE
server.compression.mime-types=application/json,application/xml,text/xml,text/plain
为什么HTTP连接池能提升性能?
采用http连接池,可以节约大量的3次握手4次挥手,这样能大大提升吞吐量。
Feign的HTTP客户端支持3中框架:HttpURLConnection、HttpClient、OkHttp;默认是HttpURLConnection。可以通过查看源码org.springframework.cloud.openfeign.ribbo.FeignRibbonClientAutoConfiguration.java得知。
将Feign的Http客户端工具修改为HttpClient。
修改Consumer项目,添加两个依赖,我们使用的SpringCloud版本已经默认集成了apache httpclient依赖,所以只需要添加一个依赖即可。
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
dependency>
<dependency>
<groupId>io.github.openfeigngroupId>
<artifactId>feign-httpclientartifactId>
dependency>
# 使用apache httpclient作为默认的http请求工具
feign.httpclient.enabled=true
PS:如果使用HttpClient作为Feign的客户端工具,那么在定义接口上的注解需要注意的是:如果传递的参数是一个自定义的对象(对象会使用JSON的格式来传递),需要配置参数类型,例如:@GetMapping(value="/single/pojo", consumes=MediaType.APPLICATION_JSON_VALUE)。本文中使用的Spring Cloud版本(版本较新),已无需手动配置,并且使用了HttpClient客户端以后,我们还可以通过GET请求传递对象参数。
浏览器发起的请求我们借助F12 Devtools中的Network来查看请求和响应信息。对于微服务中每个接口(多个微服务之间调用)我们又该如何查看URL,状态码和耗时信息?我们可以使用配置日志的方式进行查看。
Consumer项目添加logback.xml日志文件,内容如下(logback日志的输出解绑需要是DEBUG级别):
<configuration scan="true">
<property name="CATALINA_BASE" value="E:\logs">property>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%npattern>
encoder>
appender>
<appender name="FILE1" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${CATALINA_BASE}/aa.%d{yyyyMMdd}.logfileNamePattern>
<maxHistory>30maxHistory>
rollingPolicy>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%npattern>
encoder>
appender>
<appender name="FILE2" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${CATALINA_BASE}/bb.logfile>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${CATALINA_BASE}/bb.%d{yyyyMMdd}.logfileNamePattern>
<maxHistory>30maxHistory>
rollingPolicy>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%npattern>
encoder>
appender>
<appender name="CUSTOM" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${CATALINA_BASE}/custom.logfile>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${CATALINA_BASE}/custom.%d{yyyy-MM-dd}.logfileNamePattern>
<maxHistory>30maxHistory>
rollingPolicy>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%npattern>
encoder>
appender>
<logger name="file1" level="DEBUG">
<appender-ref ref="FILE1" />
logger>
<logger name="file1" level="INFO">
<appender-ref ref="FILE2" />
logger>
<logger name="custom" level="INFO">
<appender-ref ref="CUSTOM" />
logger>
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
root>
configuration>
consumer项目启动类中注入Feign的Logger对象。
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.springcloud.feign.api"})
public class SpringcloudFeignConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudFeignConsumerApplication.class, args);
}
/**
* Logger是Feign中的Logger类。
* NONE:不记录任何信息,默认值。
* BASIC:记录请求方法、请求URL、状态码和用时
* HEADERS:在BASIC基础上再记录一些常用信息
* FULL:记录请求和响应的所有信息
*
*/
@Bean
public Logger.Level getLog() {
return Logger.Level.FULL;
}
}
consumer项目application.properties中指定服务开启状态查看
# 局部指定服务进行状态查看
# service-provider为请求的服务名称
feign.client.config.service-provider.logger-level=FULL
2021-06-20 15:54:24.215 [http-nio-8081-exec-1] DEBUG o.s.web.servlet.DispatcherServlet - GET "/consumer/hello?like=booksjf", parameters={masked}
2021-06-20 15:54:24.219 [http-nio-8081-exec-1] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to com.springcloud.feign.springcloudfeignconsumer.controller.ConsumerTest#helloTest(String)
2021-06-20 15:54:24.259 [http-nio-8081-exec-1] DEBUG o.a.h.c.protocol.RequestAuthCache - Auth cache not set in the context
2021-06-20 15:54:24.262 [http-nio-8081-exec-1] DEBUG o.a.h.i.c.PoolingHttpClientConnectionManager - Connection request: [route: {}->http://192.168.195.1:8080][total available: 0; route allocated: 0 of 50; total allocated: 0 of 200]
2021-06-20 15:54:24.273 [http-nio-8081-exec-1] DEBUG o.a.h.i.c.PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {}->http://192.168.195.1:8080][total available: 0; route allocated: 1 of 50; total allocated: 1 of 200]
2021-06-20 15:54:24.274 [http-nio-8081-exec-1] DEBUG o.a.h.impl.execchain.MainClientExec - Opening connection {}->http://192.168.195.1:8080
2021-06-20 15:54:24.276 [http-nio-8081-exec-1] DEBUG o.a.h.i.c.DefaultHttpClientConnectionOperator - Connecting to /192.168.195.1:8080
2021-06-20 15:54:24.277 [http-nio-8081-exec-1] DEBUG o.a.h.i.c.DefaultHttpClientConnectionOperator - Connection established 192.168.195.1:65242<->192.168.195.1:8080
2021-06-20 15:54:24.277 [http-nio-8081-exec-1] DEBUG o.a.h.i.c.DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 60000
2021-06-20 15:54:24.277 [http-nio-8081-exec-1] DEBUG o.a.h.impl.execchain.MainClientExec - Executing request GET /echo/booksjf HTTP/1.1
2021-06-20 15:54:24.277 [http-nio-8081-exec-1] DEBUG o.a.h.impl.execchain.MainClientExec - Target auth state: UNCHALLENGED
2021-06-20 15:54:24.278 [http-nio-8081-exec-1] DEBUG o.a.h.impl.execchain.MainClientExec - Proxy auth state: UNCHALLENGED
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 >> GET /echo/booksjf HTTP/1.1
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 >> Accept-Encoding: gzip
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 >> Accept-Encoding: deflate
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 >> Accept: */*
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 >> Content-Length: 0
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 >> Host: 192.168.195.1:8080
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 >> Connection: Keep-Alive
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.13 (Java/1.8.0_181)
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 >> "GET /echo/booksjf HTTP/1.1[\r][\n]"
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 >> "Accept-Encoding: gzip[\r][\n]"
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 >> "Accept-Encoding: deflate[\r][\n]"
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 >> "Accept: */*[\r][\n]"
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 >> "Content-Length: 0[\r][\n]"
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 >> "Host: 192.168.195.1:8080[\r][\n]"
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.13 (Java/1.8.0_181)[\r][\n]"
2021-06-20 15:54:24.280 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 >> "[\r][\n]"
2021-06-20 15:54:24.283 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 << "HTTP/1.1 200 [\r][\n]"
2021-06-20 15:54:24.284 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 << "Content-Type: text/plain;charset=UTF-8[\r][\n]"
2021-06-20 15:54:24.284 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 << "Content-Length: 29[\r][\n]"
2021-06-20 15:54:24.284 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 << "Date: Sun, 20 Jun 2021 07:54:24 GMT[\r][\n]"
2021-06-20 15:54:24.284 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 << "Keep-Alive: timeout=60[\r][\n]"
2021-06-20 15:54:24.284 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 << "Connection: keep-alive[\r][\n]"
2021-06-20 15:54:24.284 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
2021-06-20 15:54:24.284 [http-nio-8081-exec-1] DEBUG org.apache.http.wire - http-outgoing-0 << "Hello Nacos Discovery booksjf"
2021-06-20 15:54:24.286 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 << HTTP/1.1 200
2021-06-20 15:54:24.286 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 << Content-Type: text/plain;charset=UTF-8
2021-06-20 15:54:24.286 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 << Content-Length: 29
2021-06-20 15:54:24.286 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 << Date: Sun, 20 Jun 2021 07:54:24 GMT
2021-06-20 15:54:24.286 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 << Keep-Alive: timeout=60
2021-06-20 15:54:24.286 [http-nio-8081-exec-1] DEBUG org.apache.http.headers - http-outgoing-0 << Connection: keep-alive
2021-06-20 15:54:24.290 [http-nio-8081-exec-1] DEBUG o.a.h.impl.execchain.MainClientExec - Connection can be kept alive for 60000 MILLISECONDS
2021-06-20 15:54:24.305 [http-nio-8081-exec-1] DEBUG o.s.w.c.HttpMessageConverterExtractor - Reading to [java.lang.String] as "text/plain;charset=UTF-8"
2021-06-20 15:54:24.306 [http-nio-8081-exec-1] DEBUG o.a.h.i.c.PoolingHttpClientConnectionManager - Connection [id: 0][route: {}->http://192.168.195.1:8080] can be kept alive for 60.0 seconds
2021-06-20 15:54:24.306 [http-nio-8081-exec-1] DEBUG o.a.h.i.c.DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 0
2021-06-20 15:54:24.306 [http-nio-8081-exec-1] DEBUG o.a.h.i.c.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {}->http://192.168.195.1:8080][total available: 1; route allocated: 1 of 50; total allocated: 1 of 200]
2021-06-20 15:54:24.315 [http-nio-8081-exec-1] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Using 'text/html', given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8] and supported [text/plain, */*, text/plain, */*, application/json, application/*+json, application/json, application/*+json]
2021-06-20 15:54:24.316 [http-nio-8081-exec-1] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Writing ["Hello Nacos Discovery booksjf"]
2021-06-20 15:54:24.324 [http-nio-8081-exec-1] DEBUG o.s.web.servlet.DispatcherServlet - Completed 200 OK
分布式项目中,服务压力比较大的情况下,可能处理服务的过程需要花费一定的时间,而默认情况下请求超时的配置是1s,所以我们需要调整该配置延长请求超时时间。
# feign客户端请求超时设置
# 请求连接的超时时间,默认为2s
feign.httpclient.connection-timeout=1000
feign.client.config.service-provider.connect-timeout=1000
# 请求处理的超时时间
feign.client.config.service-provider.read-timeout=1000