赞
踩
Feign [feɪn] 译文 伪装。Feign是一个轻量级的Http封装工具对象,大大简化了Http请求,它的使用方法 是定义一个接口,然后在上面添加注解。不需要拼接URL、参数等操作。项目主页:GitHub - OpenFeign/feign: Feign makes writing java http clients easier
按照上图所示,我们就要实现打车用户打车下单,打车下单的时候需要匹配指定司机并更改司机状态,由之 前空闲状态改成接单状态。这时候就涉到 hailtaxi-order服务调用 hailtaxi-driver服务了,此时 如果使用HttpClient工具,操作起来非常麻烦,我们可以使用 SpringCloud OpenFeign实现调用。
使用OpenFeign实现服务之间调用,可以按照如下步骤实现:
1)导入依赖
在 hailtaxi-api 中导入如下依赖:
- <!--配置feign-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- </dependency>
2)创建Feign客户端接口
代码如下:
- @FeignClient(value = "hailtaxi-driver")//value = "hailtaxi-driver"指定服务的名字
- public interface DriverFeign {
-
- /****
- * 更新司机信息,该方法和hailtaxi-driver服务中的方法保持一致
- */
- @PutMapping(value = "/driver/status/{id}/{status}")
- Driver status(@PathVariable(value = "id")String id, @PathVariable(value = "status")Integer status);
- }
参数说明:Feign启动的时候会扫描所有带有@FeignClient的注解,最后会通过动态代理,帮我们生成实现类,注解@FeignClient声明Feign的客户端,注解value指明的是服务的名称,接口定义的方法,采用SpringMVC的注解。Feign会根据注解帮我们生成URL地址。
3)Controller调用
修改 hailtaix-order 的下单方法,在下单方法中调用 DriverFeign修改司机状态,代码如下:
- /****
- * 更新司机信息
- */
- @PutMapping(value = "/status/{id}/{status}")
- public Driver status(@PathVariable(value = "id")String id,@PathVariable(value = "status")Integer status){
- Driver driver = new Driver(id,"张司机(18081)",5.0f,null,status);
- System.out.println("司机状态变更(18081):"+driver);
- return driver;
- }
4)启动OpenFeign
以上的准备工作做完之后,此时我们就要启动OpenFeign,此时我们就要启动类上加上注解,代码如下:
- @SpringBootApplication
- @EnableDiscoveryClient
- @EnableFeignClients(basePackages = "com.itheima.driver.feign")
- public class DriverApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(DriverApplication.class,args);
- }
- }
用户在网络请求的过程中,如果网络不佳、传输数据过大,会造成体验差的问题,我们需要将传输的数据进行压缩来提升体验。SpringCloud OpenFeign支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。
通过配置开启请求与响应的压缩功能:
- server:
- port: 18084
- spring:
- application:
- name: hailtaxi-driver
- cloud:
- #Consul配置
- consul:
- host: localhost
- port: 8500
- discovery:
- #注册到Consul中的服务名字
- service-name: ${spring.application.name}
- feign:
- compression:
- request:
- enabled: true # 开启请求压缩
- response:
- enabled: true # 开启响应压缩
也可以对请求的数据类型,以及触发压缩的大小下限进行设置:
server: port: 18084 spring: application: name: hailtaxi-driver cloud: #Consul配置 consul: host: localhost port: 8500 discovery: #注册到Consul中的服务名字 service-name: ${spring.application.name} feign: compression: request: enabled: true # 开启请求压缩 mime-types: text/html,application/xml,application/json # 设置压缩的数据类型 min-request-size: 2048 # 设置触发压缩的大小下限 #以上数据类型,压缩大小下限均为默认值 response: enabled: true # 开启响应压缩
我们知道可以通过loggin.level.xx=debug来设置日志级别,但是这个对Feign客户端不会生效,@FeignClient注解修饰的客户端在被代理时,都会创建一个新的Feign.Logger实例。我们需要额外通过 配置类的方式指定这个日志的级别才可以。
1)普通日志级别设置
在 hailtaxi-order 的配置文件中设置com.itheima包下的日志级别都为debug :
- # com.jokerMqc包下的日志级别都为Debug
- logging:
- level:
- com.jokerMqc: debug
2) Feign日志等级配置
在 hailtaxi-order 启动类 OrderApplication 中创建 Logger.Level ,定义日志级别:
- /***
- * 日志级别
- * @return
- */
- @Bean
- public Logger.Level feignLoggerLevel(){
- return Logger.Level.FULL;
- }
feign支持4种级别,如下:
重启之后,访问打印如下:
Ribbon是NetFlix发布的负载均衡器,有助于控制HTTP客户端行为。为Ribbon配置服务提供者地址列表后,Ribbon就可以基于负载均衡算法,自动帮助服务消费者发送请求。
Ribbon默认提供的负载均衡算法:轮询,随机,重试法,加权,当然我们也可以实现自己的负载均衡算法。
有人会有一个疑问,Nginx也可以实现负载均衡,那他跟Ribbon有什么区别,其实Nginx是在服务器端在负载均衡,而Ribbon是发生在客户端的负载均衡。
1)业务分析
如上图, 当用户下单调用 hailtaxi-order服务的时候,该服务会调用 hailtaxi-driver ,此时如果是 抢单过程,查询压力也会很大,我们可以为 hailtaxi-driver做集群,做集群只需要把工程复制多分 即可,多个工程如下图:
2)调用测试
此时我们执行 http://localhost:8001/order?token=zhangsan调用,可以发现已经实现负载均衡 了, 18081 和 18084 服务会轮询着调用。
上面我们没有做任何操作,只是把服务做成集群就实现了负载均衡,这是因为OpenFeign默认使用了Ribbon的轮询算法,如下图:
我们如果想改变相关算法,可以直接在 application.yml 中配置算法即可。
- #修改负载均衡算法,默认是轮询,配置之后变随机
- ribbon:
- #轮询
- NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
- #随机算法
- #NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
- #重试算法,该算法先按照轮询的策略获取服务,如果获取服务失败则在指定的时间内会进行重试,获取可用的服务
- #NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule
- #加权法,会根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越大。刚启动时如果同统计信息不足,则使用轮询的策略,等统计信息足够会切换到自身规则。
- #NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ZoneAvoidanceRule
- public class MyRule implements IRule {
- @Override
- public Server choose(Object o) {
- // 这里实现自己的负载均衡算法
- return null;
- }
-
- @Override
- public void setLoadBalancer(ILoadBalancer iLoadBalancer) {
-
- }
-
- @Override
- public ILoadBalancer getLoadBalancer() {
- return null;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。