Skip to content

Commit 8057def

Browse files
committed
docs: update hystrix-timeout
基于 timeout 机制为服务接口的调用超时提供安全保护
1 parent ac26eed commit 8057def

File tree

4 files changed

+105
-2
lines changed

4 files changed

+105
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@
102102
### 降级
103103
- 如何进行降级?
104104

105-
## 微服务架构【额外新增,待补充】
105+
## 微服务架构
106+
- [微服务架构整个章节内容属额外新增,会陆续补充完善]()
106107
- [关于微服务架构的描述](/docs/micro-services/microservices-introduction.md)
107108

108109
### Spring Cloud 微服务架构
Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,103 @@
1-
## 基于 timeout 机制为服务接口调用超时提供安全保护
1+
## 基于 timeout 机制为服务接口调用超时提供安全保护
2+
一般来说,在调用依赖服务的接口的时候,比较常见的一个问题就是**超时**。超时是在一个复杂的分布式系统中,导致系统不稳定,或者系统抖动。出现大量超时,线程资源会被 hang 死,从而导致吞吐量大幅度下降,甚至服务崩溃。
3+
4+
你去调用各种各样的依赖服务,特别是在大公司,你甚至都不认识开发一个服务的人,你都不知道那个人的技术水平怎么样,对那个人根本不了解。
5+
6+
Peter Steiner 说过,"[On the Internet, nobody knows you're a dog](https://en.wikipedia.org/wiki/On_the_Internet,_nobody_knows_you%27re_a_dog)",也就是说在互联网的另外一头,你都不知道甚至坐着一条狗。
7+
8+
![220px-Internet_dog.jpg](/images/220px-Internet_dog.jpg)
9+
10+
像特别复杂的分布式系统,特别是在大公司里,多个团队、大型协作,你可能都不知道服务是谁的,很可能说开发服务的那个哥儿们甚至是一个实习生。依赖服务的接口性能可能很不稳定,有时候 2ms,有时候 200ms,甚至 2s,都有可能。
11+
12+
如果你不对各种依赖服务接口的调用做超时控制,来给你的服务提供安全保护措施,那么很可能你的服务就被各种垃圾的依赖服务的性能给拖死了。大量的接口调用很慢,大量的线程被卡死。如果你做了资源的隔离,那么也就是线程池的线程被卡死,但其实我们可以做超时控制,没必要让它们全卡死。
13+
14+
### TimeoutMilliseconds
15+
在 Hystrix 中,我们可以手动设置 timeout 时长,如果一个 command 运行时间超过了设定的时长,那么就被认为是 timeout,然后 Hystrix command 标识为 timeout,同时执行 fallback 降级逻辑。
16+
17+
`TimeoutMilliseconds` 默认值是 1000,也就是 1000ms。
18+
19+
```java
20+
HystrixCommandProperties.Setter()
21+
..withExecutionTimeoutInMilliseconds(int)
22+
```
23+
24+
### TimeoutEnabled
25+
这个参数用于控制是否要打开 timeout 机制,默认值是 true。
26+
27+
```java
28+
HystrixCommandProperties.Setter()
29+
.withExecutionTimeoutEnabled(boolean)
30+
```
31+
32+
## 实例 Demo
33+
我们在 command 中,将超时时间设置为 500ms,然后在 run() 方法中,设置休眠时间 1s,这样一个请求过来,直接休眠 1s,结果就会因为超时而执行降级逻辑。
34+
35+
```java
36+
public class GetProductInfoCommand extends HystrixCommand<ProductInfo> {
37+
38+
private Long productId;
39+
40+
private static final HystrixCommandKey KEY = HystrixCommandKey.Factory.asKey("GetProductInfoCommand");
41+
42+
public GetProductInfoCommand(Long productId) {
43+
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ProductInfoService"))
44+
.andCommandKey(KEY)
45+
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
46+
.withCoreSize(8)
47+
.withMaxQueueSize(10)
48+
.withQueueSizeRejectionThreshold(8))
49+
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
50+
.withCircuitBreakerEnabled(true)
51+
.withCircuitBreakerRequestVolumeThreshold(20)
52+
.withCircuitBreakerErrorThresholdPercentage(40)
53+
.withCircuitBreakerSleepWindowInMilliseconds(3000)
54+
// 设置是否打开超时,默认是true
55+
.withExecutionTimeoutEnabled(true)
56+
// 设置超时时间,默认1000(ms)
57+
.withExecutionTimeoutInMilliseconds(500)
58+
.withFallbackIsolationSemaphoreMaxConcurrentRequests(30)));
59+
this.productId = productId;
60+
}
61+
62+
@Override
63+
protected ProductInfo run() throws Exception {
64+
System.out.println("调用接口查询商品数据,productId=" + productId);
65+
66+
// 休眠1s
67+
TimeUtils.sleep(1);
68+
69+
String url = "http://localhost:8081/getProductInfo?productId=" + productId;
70+
String response = HttpClientUtils.sendGetRequest(url);
71+
System.out.println(response);
72+
return JSONObject.parseObject(response, ProductInfo.class);
73+
}
74+
75+
@Override
76+
protected ProductInfo getFallback() {
77+
ProductInfo productInfo = new ProductInfo();
78+
productInfo.setName("降级商品");
79+
return productInfo;
80+
}
81+
}
82+
```
83+
84+
在测试类中,我们直接发起请求。
85+
86+
```java
87+
@SpringBootTest
88+
@RunWith(SpringRunner.class)
89+
public class TimeoutTest {
90+
91+
@Test
92+
public void testTimeout() {
93+
HttpClientUtils.sendGetRequest("http://localhost:8080/getProductInfo?productId=1");
94+
}
95+
}
96+
```
97+
98+
结果中可以看到,打印出了降级商品相关信息。
99+
100+
```c
101+
ProductInfo(id=null, name=降级商品, price=null, pictureList=null, specification=null, service=null, color=null, size=null, shopId=null, modifiedTime=null, cityId=null, cityName=null, brandId=null, brandName=null)
102+
{"id": 1, "name": "iphone7手机", "price": 5599, "pictureList":"a.jpg,b.jpg", "specification": "iphone7的规格", "service": "iphone7的售后服务", "color": "红色,白色,黑色", "size": "5.5", "shopId": 1, "modifiedTime": "2017-01-01 12:00:00", "cityId": 1, "brandId": 1}
103+
```
18.7 KB
Loading

images/220px-Internet_dog.jpg

18.7 KB
Loading

0 commit comments

Comments
 (0)