在之前的文章中采用了ribbon后,简化了调用的代码
String baseUrl = "http://user-service/user/"; User user = this.restTemplate.getForObject(baseUrl + id, User.class)你可能以后需要编写类似的大量重复代码,格式基本相同,无非参数不一样。感觉比较丑陋,而且风格一样感觉不好维护,所以为了更好的使用,我们可以使用Fegin来完成远程调用
我们改造原来的consumer 消费者,将原来的调用方式在此优化
导入依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> Fegin的客户端 @FeignClient("user-service") //表示调用的服务名称 public interface UserClient { @GetMapping("/user/{id}")//访问的url //访问的服务提供者 抽象方法 User queryById(@PathVariable("id") Long id); }这种实现方法,就等同于,在消费者这边创建了一个接口,等服务者来实现这个接口的方法 服务者controller代码
@RestController @RequestMapping("user") @Slf4j public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public User queryById(@PathVariable("id") Long id) { return userService.queryById(id); } } 启动器修改 @SpringBootApplication @EnableDiscoveryClient // 开启Eureka客户端 @EnableFeignClients // 开启Feign功能 public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }删除了RestTemplate,不需要template来远程访问了
代码调用 @RestController @RequestMapping("consumer") @Slf4j public class ConsumerController { @Autowired private RestTemplate restTemplate; @Autowired private UserClient userClent; @GetMapping("{id}") public User queryById(@PathVariable("id") Long id){ return userClent.queryById(id); } }发现简洁了很多
运行测试 总结: Fegin利用将http的的服务调用,伪装成了实现类方法的调用,类似接口实现的方式来实现;Feign中本身已经集成了Ribbon依赖和自动配置 因此我们不需要额外引入依赖,也不需要再注册RestTemplate对象。
Fegin内置的ribbon默认设置了请求超时时长,默认是1000ms,我们可以通过手动配置来修改这个超时时长:
ribbon: ReadTimeout: 2000 # 读取超时时长 ConnectTimeout: 1000 # 建立链接的超时时长因为ribbon内部有重试机制,一旦超时,会自动重新发起请求。如果不希望重试,可以添加配置:
ribbon: ConnectTimeout: 500 # 连接超时时长 ReadTimeout: 2000 # 数据通信超时时长 MaxAutoRetries: 0 # 当前服务器的重试次数 MaxAutoRetriesNextServer: 1 # 重试多少次服务 OkToRetryOnAllOperations: false # 是否对所有的请求方式都重试 false只对get请求重试另外,Hystix的超时时间,应该比重试的总时间要大,比如当前案例中,应该配 大于25002 = 5000((连接超时时长+数据通信超时时长)(重试多少次服务+1(第一次正常访问)))
Feign默认也有对Hystix的集成: 只不过,默认情况下是关闭的。我们需要通过下面的参数来开启:
feign: hystrix: enabled: true # 开启Feign的熔断功能但是,Feign中的Fallback配置不像Ribbon中那样简单了。
1)首先,我们要定义一个类,实现刚才编写的UserFeignClient,作为fallback的处理类
@Component public class UserClientFallback implements UserClient { @Override public User queryById(Long id) { User user = new User(); user.setId(id); user.setName("用户查询出现异常!"); return user; } }2)然后在UserFeignClient中,指定刚才编写的实现类
@FeignClient(value = "user-service", fallback = UserFeignClientFallback.class) public interface UserClient { @GetMapping("/user/{id}") User queryById(@PathVariable("id") Long id); }3)重启测试:
我们关闭user-service服务,然后在页面访问:
Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。通过下面的参数即可开启请求与响应的压缩功能,同时,我们也可以对请求的数据类型,以及触发压缩的大小下限进行设置:
feign: compression: request: enabled: true # 开启请求压缩 mime-types: text/html,application/xml,application/json # 设置压缩的数据类型 min-request-size: 2048 # 设置触发压缩的大小下限注:上面的数据类型、压缩大小下限均为默认值。