91人参与 • 2024-08-06 • 微服务
声明式http客户端,其实就是一个简化http发送的客户端。
orderservice中引入
<!--openfeign依赖-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-openfeign</artifactid>
</dependency>
配置类上开启feign自动装配 @enablefeignclients
编写feign接口
@feignclient("userservice") // 指定服务名称
public interface userclient {
@getmapping("/user/{id}")
user findbyid(@pathvariable("id") long id);
}
以看到其实和写一个接口类似,这样的好处是,不仅方便程序员编写,而且让程序员使用时认为像是在本地调用一样方便。
传统的利用resttemplate方式发送:
string url = "http://userservice/user/" + order.getuserid();
user user = resttemplate.getforobject(url, user.class);
大家可以类比去记忆。
@service
public class orderservice {
@autowired
private ordermapper ordermapper;
@resource
private resttemplate resttemplate;
@autowired
private userclient userclient;
public order queryorderbyid(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 # 日志级别
四种日志级别:
@configuration
public class defaultfeignconfiguration {
@bean
public logger.level feignloglevel() {
return logger.level.basic;
}
}
全局生效,将其放到启动类的@enablefeignclients这个注解中:
@enablefeignclients(defaultconfiguration = defaultfeignconfiguration.class)
局部生效,将其放到对应服务的@feignclient这个注解中:
@feignclient(value = "userservice", configuration = defaultfeignconfiguration.class)
full级别的日志信息:
05-30 10:30:12:184 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid] ---> get http://userservice/user/1 http/1.1
05-30 10:30:12:184 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid] ---> end http (0-byte body)
05-30 10:30:12:190 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid] <--- http/1.1 200 (5ms)
05-30 10:30:12:190 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid] connection: keep-alive
05-30 10:30:12:190 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid] content-type: application/json
05-30 10:30:12:190 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid] date: thu, 30 may 2024 02:30:12 gmt
05-30 10:30:12:190 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid] keep-alive: timeout=60
05-30 10:30:12:190 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid] transfer-encoding: chunked
05-30 10:30:12:190 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid]
05-30 10:30:12:190 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid] {"id":1,"username":"柳岩","address":"湖南省衡阳市"}
05-30 10:30:12:190 debug 6836 --- [nio-8080-exec-3] cn.itcast.order.web.userclient : [userclient#findbyid] <--- end http (59-byte body)
feign底层发起http请求,依赖于其它的框架。
其底层客户端实现包括:
urlconnection:默认,不支持连接池
apache httpclient:支持连接池
okhttp:支持连接池
优化方法:
引入依赖:
<!--httpclient的依赖 -->
<dependency>
<groupid>io.github.openfeign</groupid>
<artifactid>feign-httpclient</artifactid>
</dependency>
配置连接池:
feign:
client:
config:
default: # default全局的配置
loggerlevel: basic # 日志级别
httpclient:
enabled: true # 开启feign使用httpclient
max-connections: 100 # 最大的连接数
max-connections-per-route: 20 # 每个路径的最大连接数
本身就是微服务为了解耦,这样反而让服务端和客户端耦合了。
而且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模块中的)。
重启,调用一下:
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论