文章目录
Feign
基于Feign的远程调用
声明式http客户端,其实就是一个简化http发送的客户端。
orderservice中引入
- 引入依赖:
<!--openFeign依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
- 配置类上开启Feign自动装配 @EnableFeignClients
- 编写Feign接口
@FeignClient("userservice")// 指定服务名称publicinterfaceUserClient{@GetMapping("/user/{id}")UserfindById(@PathVariable("id")Long id);}
以看到其实和写一个接口类似,这样的好处是,不仅方便程序员编写,而且让程序员使用时认为像是在本地调用一样方便。
传统的利用restTemplate方式发送:
String url ="http://userservice/user/"+ order.getUserId();User user = restTemplate.getForObject(url,User.class);
大家可以类比去记忆。
- 使用 直接像使用本地bean一样去注入和调用即可,不影响代码可读性还。
@ServicepublicclassOrderService{@AutowiredprivateOrderMapper orderMapper;@ResourceprivateRestTemplate restTemplate;@AutowiredprivateUserClient userClient;publicOrderqueryOrderById(Long orderId){// 1.查询订单Order order = orderMapper.findById(orderId);/* // 2.查询用户,远程调用
String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);*/User user = userClient.findById(order.getUserId());// 3. 封装
order.setUser(user);// 4.返回return order;}}
调用成功:
Feign本身就自带的Ribbon负载均衡。
自定义配置
正常情况下,默认自动装配的配置就足够了。
一般最多就是改改日志,其他的一般不修改。
下面介绍两种修改方式:
- 基于配置文件 针对某个服务:
feign:client:config:userservice:# 针对某个微服务的配置loggerLevel: FULL # 日志级别
针对全部服务:
feign:client:config:default:# 用default就是针对全部服务,如果写服务名称,则是针对某个微服务的配置loggerLevel: FULL # 日志级别
四种日志级别:
- NONE:不记录任何日志信息,这是默认值。
- BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
- HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
- FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
- 基于java代码修改
@ConfigurationpublicclassDefaultFeignConfiguration{@BeanpublicLogger.LevelfeignLogLevel(){returnLogger.Level.BASIC;}}
全局生效,将其放到启动类的@EnableFeignClients这个注解中:
@EnableFeignClients(defaultConfiguration =DefaultFeignConfiguration.class)
局部生效,将其放到对应服务的@FeignClient这个注解中:
@FeignClient(value ="userservice", configuration =DefaultFeignConfiguration.class)
FULL级别的日志信息:
05-3010:30:12:184DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById]--->GET http://userservice/user/1HTTP/1.105-3010:30:12:184DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById]--->ENDHTTP(0-byte body)05-3010:30:12:190DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById]<---HTTP/1.1200(5ms)05-3010:30:12:190DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById] connection: keep-alive
05-3010:30:12:190DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById] content-type: application/json
05-3010:30:12:190DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById] date:Thu,30May202402:30:12GMT05-3010:30:12:190DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById] keep-alive: timeout=6005-3010:30:12:190DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById] transfer-encoding: chunked
05-3010:30:12:190DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById]05-3010:30:12:190DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById]{"id":1,"username":"柳岩","address":"湖南省衡阳市"}05-3010:30:12:190DEBUG6836---[nio-8080-exec-3]cn.itcast.order.web.UserClient:[UserClient#findById]<---ENDHTTP(59-byte body)
性能优化
Feign底层发起http请求,依赖于其它的框架。
其底层客户端实现包括:
- URLConnection:默认,不支持连接池
- Apache HttpClient:支持连接池
- OKHttp:支持连接池
优化方法:
- 使用连接池代替默认的URLConnection
- 日志级别最好使用basic 和 none
引入依赖:
<!--httpClient的依赖 --><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId></dependency>
配置连接池:
feign:client:config:default:# default全局的配置loggerLevel: BASIC # 日志级别httpclient:enabled:true# 开启feign使用HttpClientmax-connections:100# 最大的连接数max-connections-per-route:20# 每个路径的最大连接数
Feign 常用使用方式
- 继承
本身就是微服务为了解耦,这样反而让服务端和客户端耦合了。
而且springMVC对应方法参数,比如@PathVariable继承不下来的,因此Controller中必须再次声明方法、参数列表、注解。
- 抽取
将FeignClient 抽取为独立模块,并且把接口有关的POJO、Feign配置都放到这个模块中,提供给所有消费者使用。
如果不抽取,那么每个服务调用相同的接口都需要重写写相同的代码。
抽取之后,只要引入依赖,即可像在本地一样去使用即可。
现在来实践一下吧。
创建feign-api子模块,并导入依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
将order-service中的UserClient、实体类User、DefaultFeignConfigurationy移动到feign-api项目中。
order-service中引入api模块:
<!--feign-api模块--><dependency><groupId>cn.itcast.demo</groupId><artifactId>feign-api</artifactId><version>1.0</version></dependency>
orderservice上启动类的EnableFeignClients注解上加上此服务需要使用的Client接口,可以引入多个。
@EnableFeignClients(clients ={UserClient.class})
也可以
@EnableFeignClients(basePackage ="feignClient位置")
将爆红的地方导包(因为位置变了,现在我们用的feign模块中的)。
重启,调用一下:
版权归原作者 Cosmoshhhyyy 所有, 如有侵权,请联系我们删除。