前言
微服务的服务提供者和服务消费者解耦合之后,我们可以借助restTemplate这样的HTTP客户端,向微服务的服务提供者发起远程调用;
但是这样的代码有2大缺陷:
//使用RestTemplate发起远程调用 @Autowired private RestTemplate restTemplate; public Order findById(Long orderId) { // 1.查询订单 Order order = orderMapper.selectById(orderId); //2.调用user-service服务查询当前订单的用户信息 //String url = \"http://127.0.0.1:8081/user/\" + order.getUserId(); //使用RestTemplate发起远程调用 String url = \"http://user-service/user/\" + order.getUserId(); User user = restTemplate.getForObject(url, User.class); //3.user封装到order对象 order.setUser(user); // 4.返回 return order; }
其作用就是帮助我们优雅的实现HTTP请求的发送,解决上面提到的问题。
<!--feign的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
@EnableFeignClients
@MapperScan(\"com.zhanggen.order.mapper\") @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients //开启Feign public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); }
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
com.zhanggen.order.mapper
//FeignClient必须和@EnableFeignClients标注的类在同一个包下 //该接口用于向user-service微服务发起远程调用 //Feign底层默认使用HTTP协议发起远程调用 //@FeignClient(\"user-service\")+@GetMapping(\"/user/{id}\")确定服务提供者的URL(http://user-service/user/{id}) @FeignClient(\"user-service\") public interface UserClient { //根据userId查询用户信息 @GetMapping(\"/user/{id}\") User findById(@PathVariable Long id); }
这样,Feign就可以帮助我们发送http请求,无需自己使用RestTemplate来发送了。
//使用Feign发起远程调用 @Autowired private UserClient userClient; public Order findById(Long orderId) { // 1.查询订单 Order order = orderMapper.selectById(orderId); //2.调用user-service服务查询当前订单的用户信息 //String url = \"http://127.0.0.1:8081/user/\" + order.getUserId(); //使用RestTemplate发起远程调用 //String url = \"http://user-service/user/\" + order.getUserId(); //User user = restTemplate.getForObject(url, User.class); User user = userClient.findById(order.getUserId()); //3.user封装到order对象 order.setUser(user); // 4.返回 return order; }
三、
作用 | 说明 | |
---|---|---|
feign.Logger.Level | 修改日志级别 | 包含四种不同的级别:NONE(默认)、BASIC、HEADERS、FULL NONE ,不记录。默认选项 BASIC ,仅记录请求方法和URL以及响应状态代码和执行时间。 HEADERS ,记录基本信息以及请求和响应标头。 FULL ,记录请求和响应的标题,正文和元数据。 |
feign.codec.Decoder | 响应结果的解析器 | http远程调用的结果做解析,例如解析json字符串为java对象 |
feign.codec.Encoder | 请求参数编码 | 将请求参数编码,便于通过http请求发送,例如POST请求,将请求参数编码到请求体中 |
feign.Contract | 支持的注解格式 | 默认是SpringMVC的注解 |
feign.Retryer | 失败重试机制 |
feign: client: config: user-service: # 针对某个微服务的配置,也可以针对所有服务,这个位置换成default loggerLevel: FULL # 日志级别
package com.zhanggen.order.config; import feign.Logger; import org.springframework.context.annotation.Bean; public class FeignDefaultConfiguration { @Bean public Logger.Level feignLogLevel(){ return Logger.Level.FULL; // 日志级别为FULL } }
2.1.配置局部
如果我想让以上日志配置在调用某1个服务提供者时生效,在FeigClien接口中修改如下;
@FeignClient(value = \"user-service\",configuration = FeignDefaultConfiguration.class) public interface UserClient { //根据userId查询用户信息 @GetMapping(\"/user/{id}\") User findById(@PathVariable Long id); }
2.2.配置全局
@EnableFeignClients(defaultConfiguration = FeignDefaultConfiguration.class) public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); }
四、Feign连接池
-
URLConnection:默认实现,不支持连接池,每次请求都是新建连接
-
Apache HttpClient :支持连接池
-
OKHttp:支持连接池
因此提高Feign的性能主要手段就是使用连接池
<!--httpClient的依赖内置连接池 --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
max-connections-per-route:再调用某1个服务提供者时,最多从连接池中拿出50个连接发起远程调用,避免服务雪崩;
feign:
httpclient:
enabled: true # 开启feign对HttpClient的支持
max-connections: 200 # 设置最大的连接数
max-connections-per-route: 50 # 并行接收一个服务的请求数量
1.创建fein-api模块
把之前在order-service中编写的UserClient、User、FeignDefaultConfiguration剪切到feign-api项目中
2.pom依赖依赖
在fein-api模块中添加以下依赖
<dependencies> <!--openfeign依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--mybatis-plus 实体类注解要用到--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-core</artifactId> <version>3.4.0</version> </dependency> <!--httpclient基于连接池的调用--> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency> </dependencies>
3.服务消费者
服务消费者依赖fei-api公共模块;
<dependency> <groupId>com.zhanggen</groupId> <artifactId>fein-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
服务消费者启动类
@EnableFeignClients(defaultConfiguration = FeignDefaultConfiguration.class, basePackages = \"com.zhanggen.feign\") public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } //SpringBoot启动是,在Spring容器中放入1个restTemplate对象 @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
来源:https://www.cnblogs.com/sss4/p/16414981.html
本站部分图文来源于网络,如有侵权请联系删除。