admin管理员组文章数量:1794759
【SpringCloud】SpringCloud Feign详解
目录
- 前言
- SpringCloud Feign远程服务调用
- 一.远程调用逻辑图
- 二.两个服务的yml配置和访问路径
- 三.使用RestTemplate远程调用
- 四.构建Feign
- 五.自定义Feign配置
- 六.Feign配置日志
- 七.Feign调优
- 八.抽离Feign
微服务分解成多个不同的服务,那么多个服务之间怎么调用呢? Spring Cloud最新面试题 Spring Cloud Nacos详解之注册中心 Spring Cloud Nacos详解之配置中心 Spring Cloud Nacos详解之集群配置 Spring Cloud Eureka详解 Spring Cloud Ribbon详解 Spring Cloud Gateway详解 Spring Cloud Hystrix详解
SpringCloud Feign远程服务调用 一.远程调用逻辑图现在有两个服务,订单服务(服务消费者)和用户服务(服务提供者),分别对应不同的数据库。 注意: 因为远程调用都是服务消费者调用服务提供者,所以配置和业务编写,都在服务消费者里面。
二.两个服务的yml配置和访问路径 用两个不同的数据库,模拟部署在两台服务器的数据库 订单yml配置 访问路径:@GetMapping("order/{orderId}") server: port: 8082 spring: datasource: url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver application: name: orderservice //订单服务的名称 用户yml配置 访问路径:@GetMapping("user/{id}") server: port: 8081 spring: datasource: url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver application: name: userservice //用户服务的名称 三.使用RestTemplate远程调用1.注入RestTemplate
/** * 因为启动类本身也是一个配置了,所以我们在启动类进行注入,你自己自定义配置类注入也行 * 创建RestTemplate并注入Spring容器 */ @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }2.编写远程调用
@Autowired private RestTemplate restTemplate; public Order queryOrderById(Long orderId) { // 根据订单id查询订单 Order order = orderMapper.findById(orderId); // 利用RestTemplate发起http请求,根据用户id查询用户 // url路径 服务名称(上面配置了)/请求路径/参数 String url = "localhost:8081/user/" + order.getUserId(); // 发送http请求,实现远程调用,现在是get请求类型 User user = restTemplate.getForObject(url, User.class); // 封装user到Order order.setUser(user); // 返回值 return order; }3.RestTemplate的缺点
- 参数复杂URL难以维护。
- 不符合正常接口调用的格式。
1.引入依赖
<!--feign客户端依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>2.在启动类使用注解开启Feign功能
@SpringBootApplication @EnableFeignClients public class OrderApplication { }3.编写远程调用
//服务名称 @FeignClient(value = "userservice") public interface UserClient { @GetMapping("/user/{id}") User findById(@PathVariable("id") Long id); }4.调用接口
@Autowired private UserClient userClient; public Order queryOrderById(Long orderId) { // 根据订单id查询订单 Order order = orderMapper.findById(orderId); // 用Feign远程调用 User user = userClient.findById(order.getUserId()); // 封装user到Order order.setUser(user); // 返回 return order; }5.Feign还集成了Ribbon,所以我们不用考虑负载均衡问题
五.自定义Feign配置feign.Logger.Level | 修改日志级别 | 四种不同的级别:NONE(没有任何日志)、BASIC(发起请求的开始结束时间)、HEADERS(会记录请求头请求体)、FULL(请求和响应信) |
feign.codec.Decoder | 响应结果的解析器 | http远程调用的结果做解析,例如解析json字符串为java对象 |
feign.codec.Encoder | 请求参数编码 | 将请求参数编码,便于通过http请求发送 |
feign. Contract | 支持的注解格式 | 默认是SpringMVC的注解 |
feign. Retryer | 失败重试机制 | 请求失败的重试机制,默认是没有,不过会使用Ribbon的重试 |
一般我们自定义配置的是日志
六.Feign配置日志1.配置文件配置日志
//全局配置 feign: client: config: default://default全局配置,远程调用的服务的接口也会打印。 loggerLevel:FULL //日志级别 //局部配置 feign: client: config: orderservice://只打印服务名为orderservice的日志。 loggerLevel:FULL //日志级别2.代码方式配置日志
//第一步:注入对象 public class DefaultFeignConfiguration { @Bean public Logger.Level logLevel(){ //日志级别 return Logger.Level.BASIC; } } //第二步:注解配置 //全局配置 @EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class) //局部配置 @FeignClient(value = "userservice",confiquration = FeignClientConfiguration.class) 七.Feign调优Feign底层客户端实现:
- URLConnection:默认实现,不支持连接池。
- Apache HttpClient: 支持连接池。
- OKHttp:支持连接池。
1.使用连接池替代默认的URL Connection(使用HttpClient支持)
①pom文件引入依赖
<!--引入HttpClient依赖--> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>②yml文件进行配置
feign: httpclient: enabled: true # 支持HttpClient的开关 max-connections: 100 # 最大连接数 max-connections-per-route: 25 # 单个路径的最大连接数2.日志级别最好是basic或none
八.抽离Feign如果A、B、C服务都要调用D服务,那我们要在A、B、C里面都使用Feign调用D吗,如果写就造成了很多代码冗余,所以我们要把Feign抽离出来放在一个公共的服务里面。我们新建一个Feign-api服务,然后谁用谁就在pom文件引入一下。
注意: 需要把调用的接口(加上@FeignClient(vaule=服务名)注解)和实体类写在公共的服务里面。
Feign-api结构目录
<!--谁用谁引入,引入feign的统一api--> <dependency> <groupId>cn.xinxin.demo</groupId> <artifactId>feign-api</artifactId> <version>1.0</version> </dependency>但是这样做会导致SpringBootApplication在扫描包时找不到定义FeignClient对象,那么怎么解决呢?
解决
方式一:指定FeignClient所在包 @EnableFeignClients(basePackages = "cn.xinxin.feign.clients") 方式二:指定FeignClient字节码 EnableFeignClients(clients = {UserClient.class})Feign的pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="maven.apache/POM/4.0.0" xmlns:xsi="www.w3/2001/XMLSchema-instance" xsi:schemaLocation="maven.apache/POM/4.0.0 maven.apache/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud-demo</artifactId> <groupId>cn.xinxin.demo</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>feign-api</artifactId> <properties> <mavenpiler.source>8</mavenpiler.source> <mavenpiler.target>8</mavenpiler.target> </properties> <dependencies> <!--feign客户端依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> </project>示例: 订单服务远程调用用户服务
本文标签: 详解SpringCloudFeign
版权声明:本文标题:【SpringCloud】SpringCloud Feign详解 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686856068a110782.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论