第十九章 springboot + hystrix
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十九章 springboot + hystrix相关的知识,希望对你有一定的参考价值。
hystrix是微服务中用于做熔断、降级的工具。
作用:防止因为一个服务的调用失败、调用延时导致多个请求的阻塞以及多个请求的调用失败。
1、pom.xml(引入hystrix-core包)
1 <!-- hystrix --> 2 <dependency> 3 <groupId>com.netflix.hystrix</groupId> 4 <artifactId>hystrix-core</artifactId> 5 <version>1.5.2</version> 6 </dependency>
2、application.properties
1 #hystrix
2 hystrix.timeoutInMillions = 3000
说明:设置hystrix属性,如上是"服务调用超时时间",其他属性设置见:https://github.com/Netflix/Hystrix/wiki/Configuration
3、HyStrixProperties
package com.xxx.firstboot.hystrix; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import lombok.Getter; import lombok.Setter; @Getter @Setter @Component @ConfigurationProperties(prefix = "hystrix") public class HyStrixProperties { private int timeoutInMillions; }
4、MyHyStrixCommand
package com.xxx.firstboot.hystrix; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.netflix.hystrix.HystrixCommand; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; public class MyHystrixCommand extends HystrixCommand<Response> { private static final Logger LOGGER = LoggerFactory.getLogger(MyHystrixCommand.class); private String url; public MyHystrixCommand(Setter setter, String url) { super(setter); this.url = url; } @Override protected Response run() throws Exception { LOGGER.info("服务正被调用,当前线程:‘{}‘", Thread.currentThread().getName()); Request request = new Request.Builder().url(url).build(); return new OkHttpClient().newCall(request).execute(); } @Override public Response getFallback() { LOGGER.error("服务调用失败,service:‘{}‘"); return null; } }
说明:
- 该类是最关键的一个类。
- 继承HystrixCommand<T>
- 添加构造器,注意:无法添加无参构造器,因此该类无法作为spring的bean来进行管理
- 程序开始时执行run(),当执行发生错误或超时时,执行getFallback()
5、HyStrixUtil
package com.xxx.firstboot.hystrix; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.netflix.hystrix.HystrixCommand.Setter; import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixCommandProperties; import com.squareup.okhttp.Response; @Component public class HystrixUtil { @Autowired private HyStrixProperties hp; public Response execute(String hotelServiceName, String hotelServiceMethodGetHotelInfo, String url) throws InterruptedException, ExecutionException { Setter setter = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(hotelServiceName));//被调用服务 setter.andCommandKey(HystrixCommandKey.Factory.asKey(hotelServiceMethodGetHotelInfo));//被调用服务的一个被调用方法 setter.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(hp.getTimeoutInMillions())); return new MyHystrixCommand(setter, url).execute();//同步执行 // Future<Response> future = new MyHystrixCommand(setter, url).queue();//异步执行 // return future.get();//需要时获取 } }
说明:
- hystrix的执行方式
- 同步执行:超时时间起作用
- 异步执行:超时时间不起作用(1.4.0之前的版本,在调用get()的时候开始计时起作用)
- hystrix的隔离级别
- HystrixCommandGroupKey:这个的名称设置为一个被调用的服务,eg.hotelService,所有这个服务下的方法都用同一个线程池(前提是没有配置ThreadPoolKey)
- HystrixCommandKey:这个名称通常是被调用服务的一个方法的名字(实际上就是被调用服务某一个controller中的一个对外方法),eg.getHotelInfo()
- ThreadPoolKey:这个用的很少,除非一个被调用服务中的有些被调用方法快、有的被调用方法慢,这样的话,就需要分别使用一个ThreadPoolKey,为每一个方法单独分配线程池
6、application.properties
1 service.hotel.name = hotelService
2 service.hotel.method.getHotelInfo = getHotelInfo
说明:定义被调用服务的服务名和被调用方法名,当然服务名也可以使用被调用服务的controller的简单类名。
7、HystrixController
package com.xxx.firstboot.web; import java.io.IOException; import java.util.concurrent.ExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.squareup.okhttp.Response; import com.xxx.firstboot.hystrix.HystrixUtil; @RestController @RequestMapping("/hystrix") public class HystrixController { @Value("${service.hotel.url}") private String HOTEL_URL; @Value("${service.hotel.name}") private String hotelServiceName; @Value("${service.hotel.method.getHotelInfo}") private String hotelServiceMethodGetHotelInfo; @Autowired private HystrixUtil hystrixUtil; @RequestMapping(value = "/firstHystrix", method = RequestMethod.GET) public String getHotelInfo(@RequestParam("id") int id, @RequestParam("name") String name) { String url = String.format(HOTEL_URL, id, name); Response response = null; try { response = hystrixUtil.execute(hotelServiceName, hotelServiceMethodGetHotelInfo, url); if (response != null) { return response.body().string(); } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } finally { if (response != null && response.body() != null) { try { response.body().close();// 资源关闭 } catch (IOException e) { e.printStackTrace(); } } } return "获取酒店信息失败"; } }
说明:
- 使用@value做属性注入,假设我们是在consul上配置了application.properties内容,当修改了属性文件的内容后,该服务也必须重启,因为@value只读一次(没测过,同事说的)
- 使用spring的Environment进行注入,当修改了属性文件的内容后,服务不需要重启,会每五分钟重新刷一次(没测过,同事说的)
- 使用boot构建一个属性收集类,如上边的HyStrixProperties类,不知道是否需要重启(没测过)
有测过的朋友和我讲一下,我有时间也会测一下。
下边是被调用服务的代码:
8、HotelController
@RestController @RequestMapping("/hotel") @Api("HotelController相关api") public class HotelController { @ApiOperation("获取酒店Hotel信息:getHotelInfo") @RequestMapping(value="/getHotelInfo",method=RequestMethod.GET) public Hotel getHotelInfo(@RequestParam("id") int id, @RequestParam("name") String name) { // try { // TimeUnit.MILLISECONDS.sleep(2000);//用于测试超时 // } catch (InterruptedException e) { // e.printStackTrace(); // } return new Hotel(id, name); } }
测试:启动被调用服务-->启动调用服务
参考:
http://blog.csdn.net/xiaoyu411502/article/details/50601687 官方的中文总结
https://stonetingxin.gitbooks.io/hystrix/content/ 基本上是官方的中文翻译
https://github.com/Netflix/Hystrix/wiki/Configuration hystrix配置介绍
http://blog.vicoder.com/hystrix-configuration/ 配置介绍
http://www.insaneprogramming.be/blog/2014/08/19/hystrix-spring-boot/ boot集成hystrix
以上是关于第十九章 springboot + hystrix的主要内容,如果未能解决你的问题,请参考以下文章