spring hystrix | 张洪铭的个人博客
张洪铭的个人博客

spring hystrix

在分布式系统中,远程系统或服务不可避免的调用失败(超时或者异常)
Netflix的组件Hystrix可以将这些请求隔离,针对服务限流,当服务不可用时能够熔断并降级,防止级联故障。

架构图:
此处输入图片的描述

创建hystrix 子项目

创建application.properties

1
2
3
4
5
6
7
8
9
10
11
12
server.port=8085
spring.application.name=hystrix
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
# 自定义实例ID格式
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
#hystrix.command.getUser.execution.isolation.thread.timeoutInMilliseconds = 3000
#hystrix.command.getUser.execution.isolation.strategy = SEMAPHORE
management.endpoints.web.exposure.include=hystrix.stream

创建 CustomHystrixPropertiesStrategy.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package spring.cloud.hystrix.plugin;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesCommandDefault;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
/**
* 自定义属性配置
* @author yinjihuan
*
*/
public class CustomHystrixPropertiesStrategy extends HystrixPropertiesStrategy {
public HystrixCommandProperties getCommandProperties(HystrixCommandKey commandKey, HystrixCommandProperties.Setter builder) {
// 这里可以自己控制
return new HystrixPropertiesCommandDefault(commandKey, builder);
}
}
创建RibbonApplication.java
```java
package spring.cloud.hystrix;
import com.netflix.hystrix.strategy.HystrixPlugins;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import spring.cloud.hystrix.plugin.CustomHystrixPropertiesStrategy;
@EnableHystrix
@SpringBootApplication
public class HystrixApplication {
public static void main(String[] args) {
// 手动注册插件
//HystrixPlugins.getInstance().registerEventNotifier(new CustomHystrixEventNotifier());
HystrixPlugins.getInstance().registerPropertiesStrategy(new CustomHystrixPropertiesStrategy());
SpringApplication.run(HystrixApplication.class, args);
}
}

创建RestConfiguration.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package spring.cloud.hystrix.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestConfiguration {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

创建 User.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package spring.cloud.hystrix.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
private int id;
private String name;
}

创建 HystrixController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package spring.cloud.hystrix.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import spring.cloud.hystrix.dto.User;
@RestController
public class HystrixController {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(commandKey="getUser", groupKey="user", fallbackMethod = "fallback", threadPoolKey ="tpk1",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
}
)
@GetMapping("/get")
public Object get() {
System.err.println(Thread.currentThread().getName());
User user = restTemplate.getForEntity("http://user-service/user/get?id=1", User.class).getBody();
return user;
}
@HystrixCommand(commandKey="getUser2", groupKey="user", fallbackMethod = "fallback", threadPoolKey ="tpk1",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "20000")
}
)
@GetMapping("/get2")
public Object get2() {
System.err.println(Thread.currentThread().getName());
User user = restTemplate.getForEntity("http://user-service/user/get?id=1", User.class).getBody();
return user;
}
@HystrixCommand(commandKey="getUser3", groupKey="user3", fallbackMethod = "fallback", threadPoolKey ="tpk3",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "20000")
},
threadPoolProperties = {
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "20")
}
)
@GetMapping("/get3")
public Object get3() {
System.err.println(Thread.currentThread().getName());
User user = restTemplate.getForEntity("http://user-service/user/get?id=1", User.class).getBody();
return user;
}
public Object fallback() {
return new User(100, "默认");
}
}

打开

http://localhost:8761/

此处输入图片的描述

修改UserController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package spring.cloud.ribbon.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import spring.cloud.ribbon.dto.User;
/**
* Created by zhanghongming on 2020/6/27.
*/
@RestController
public class UserController {
@GetMapping("/user/get")
public User getUser(int id) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new User(id, "zhm");
}
}

增加sleep10秒

打开http://localhost:8085/get

就会输出
{“id”:100,”name”:”默认”}

配置内容
https://github.com/Netflix/Hystrix/wiki/Configuration

创建 DashboardApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
package spring.cloud.hystrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@EnableHystrixDashboard
@SpringBootApplication
public class DashboardApplication {
public static void main(String[] args) {
SpringApplication.run(DashboardApplication.class, args);
}
}

打开
http://localhost:8080/hystrix

此处输入图片的描述

访问http://localhost:8006/actuator/hystrix.stream
此处输入图片的描述
此时访问
http://localhost:8006/get

查看返回值为
{“id”:100,”name”:”默认”}
此处输入图片的描述
查看hystrix
此处输入图片的描述

坚持原创技术分享,您的支持将鼓励我继续创作!