第十九章 springboot + hystrix(1)
hystrix是微服务中用于做熔断、降级的工具。
作用:防止因为一个服务的调用失败、调用延时导致多个请求的阻塞以及多个请求的调用失败。
1、pom.xml(引入hystrix-core包)
<!-- hystrix -->
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.2</version>
</dependency>
2、application.properties
#hystrix
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
service.hotel.name = hotelService
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(1)的更多相关文章
- 第二十九章 springboot + zipkin + mysql
zipkin的数据存储可以存在4个地方: 内存(仅用于测试,数据不会持久化,zipkin-server关掉,数据就没有了) 这也是之前使用的 mysql 可能是最熟悉的方式 es Cassandra ...
- 第二十五章 springboot + hystrixdashboard
注意: hystrix基本使用:第十九章 springboot + hystrix(1) hystrix计数原理:附6 hystrix metrics and monitor 一.hystrixdas ...
- Python之路【第十九章】:Django进阶
Django路由规则 1.基于正则的URL 在templates目录下创建index.html.detail.html文件 <!DOCTYPE html> <html lang=&q ...
- 第十九章——使用资源调控器管理资源(1)——使用SQLServer Management Studio 配置资源调控器
原文:第十九章--使用资源调控器管理资源(1)--使用SQLServer Management Studio 配置资源调控器 本系列包含: 1. 使用SQLServer Management Stud ...
- 第十九章——使用资源调控器管理资源(2)——使用T-SQL配置资源调控器
原文:第十九章--使用资源调控器管理资源(2)--使用T-SQL配置资源调控器 前言: 在前一章已经演示了如何使用SSMS来配置资源调控器.但是作为DBA,总有需要写脚本的时候,因为它可以重用及扩展. ...
- 第十九章 Django的ORM映射机制
第十九章 Django的ORM映射机制 第一课 Django获取多个数据以及文件上传 1.获取多选的结果(checkbox,select/option)时: req.POST.getlist('fav ...
- Gradle 1.12用户指南翻译——第四十九章. Build Dashboard 插件
本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- Gradle 1.12翻译——第十九章. Gradle 守护进程
有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...
- Gradle 1.12用户指南翻译——第二十九章. Checkstyle 插件
其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...
随机推荐
- thinkphp3.2中开启静态缓存后对404页面的处理方法
静态缓存很实用但是有时有些不需要静态缓存,如404页面,第一次访问返回404页面并缓存,第二次换回的状态就是200,属于正常访问,虽然人眼可以看出是404页面,但是搜索引擎不会的,而是把这个页面当成正 ...
- vue开发computed,watch,method执行的先后顺序
1#computed:计算属性将被混入到 Vue 实例中.所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例. 2#methods:methods 将被混入到 Vue ...
- HDU - 1051 Wooden Sticks 贪心 动态规划
Wooden Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- iOS 11开发教程(二)编写第一个iOS 11应用
iOS 11开发教程(二)编写第一个iOS 11应用 编写第一个iOS 11应用 本节将以一个iOS 11应用程序为例,为开发者讲解如何使用Xcode 9.0去创建项目,以及iOS模拟器的一些功能.编 ...
- lamp 5.6.36 bug记录
后来发现另一个问题,php文字水印中文是乱码. 用yum安装lamp环境详见:https://blog.csdn.net/u010071211/article/details/80370201 在ce ...
- Python进阶篇:Python简单爬虫
目录 前言 要解决的问题 设计方案 代码说明 小结 前言 前一段一直在打基础,已经学习了变量,流程控制,循环,函数这几块的知识点,就想通过写写小程序来实践一下,来加深知识点的记忆和理解.首先考虑的就是 ...
- [BZOJ4883][Lydsy1705月赛]棋盘上的守卫(Kruskal)
对每行每列分别建一个点,问题转为选n+m条边,并给每条边选一个点覆盖,使每个点都被覆盖.也就是最小生成环套树森林. 用和Kruskal一样的方法,将边从小到大排序,若一条边被选入后连通块仍然是一个环套 ...
- [UOJ424]count
虽然题目不难,但是这应该是我第一次在考场上成功拿到计数题的不算低的分数,值得记录 如果对序列处理出$i$后面第一个比它大的位置$r_i$,那么两个序列同构的条件就是$r_i$都相同,而$r_i$构成一 ...
- hdu 1514 记忆化搜索
题意是给4堆(堆的高度小于等于40)有颜色(颜色的种类小于等于20)的物品,你有一个篮子最多能装5件物品,每次从这4堆物品里面任取一件物品放进篮子里,但是取每堆物品时,必须先取上面的物品,才能取下面的 ...
- spring boot2集成ES详解
一:运行环境 JDK:1.8 ES:5.6.4 二:学习内容 如何构建spring-data-elasticsearch环境? 如何实现常用的增删改查? 如何实现对象嵌套也就是1对多这种关系? 三:J ...