1Hystrix Ribbon · SpringCloud微服务实战 · 看云
1.Hystrix Ribbon
导航
本节代码地址
GitHub: https://github.com/xuyisu/fw-sping-cloud/tree/master/fw-cloud-hystrix/fw-cloud-hystrix-ribbon
GitHub: https://github.com/xuyisu/fw-sping-cloud/tree/master/fw-cloud-ribbon/fw-cloud-ribbon-server
在Spring Cloud 中,Hystrix 主要用在被调用方,还是之前那张图,服务A调用服务B,如果服务A调用不同服务B是,及时回退信息给用户,防止因为超时问题引起更多的问题至服务不可用。
本次演示需要fw-cloud-ribbon-server先启动起来,用于提供服务,也就是上图的服务B,现在我们需要自己开发服务A。
1.1 新建项目
1.2 maven 配置
我们需要在maven引入spring-cloud-starter-netflix-hystrix的包。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
1.3 新建启动类
启动类中添加 @EnableHystrix注解用于开启Hystrix
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class FwHystrixRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(FwHystrixRibbonApplication.class, args);
}
}
1.4 创建接收用的实体
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private long id;
private String username;
private String realname;
private String email;
private String remark;
}
1.5 创建Ribbon调用类
这里需要注意我们在远程调用的方法上添加了@HystrixCommand(fallbackMethod = "findUserByIdFailure"),也就是说如果调用失败会执行findUserByIdFailure方法
@Service
@Slf4j
public class EurekaHystrixRibbonService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "findUserByIdFailure")
public User findUserById(Long id) {
return restTemplate.getForObject("http://fw-cloud-ribbon-server/user/" + id, User.class);
}
public User findUserByIdFailure(Long id) {
return new User(id,null,null,null,"网络繁忙,请稍后再试,请确认手牌");
}
}
1.6 Ribbon 基本配置
这里添加了一个getServlet()方法,用于后面Hystrix dashboard 用,继续读你可以看到的。
@Configuration
public class EurekaRibbonConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public IRule ribbonRule() {
return new RandomRule();
}
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
1.7 控制层
@RestController
public class EurekaHystrixController {
@Resource
private EurekaHystrixRibbonService eurekaRibbonService;
@GetMapping("/user/{id:\\d+}")
public User findUserById(@PathVariable long id){
return eurekaRibbonService.findUserById(id);
}
}
1.8 应用配置
server:
port: 8675
spring:
application:
name: fw-hystrix-ribbon
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
1.9 启动项目
需要先启动Eureka、再启动fw-cloud-ribbon-server、再启动当前项目
利用Postman测试localhost:8675/user/1
下面我们将fw-cloud-ribbon-server关掉,再测试,可以看到返回就是findUserByIdFailure设置的描述
1.10 @HystrixCommand配置拓展
除了指定fallbackMethod以外,还有很多属性可以配置,下图是@HystrixCommand的全部属性
例如
指定回退方法和默认方法都是findUserByIdFailure,也可以不同,指定超时时间100毫秒,线程池大小为1,忽略Exception触发的回退等,具体的属性,根据字面意思应该没问题。一般我们也用不到这么多属性
@HystrixCommand(fallbackMethod = "findUserByIdFailure"
, groupKey = "MyGroup"
, commandKey = "MyCommandKey"
, threadPoolKey = "MyThreadPool"
, commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100")}
, threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "1")}
, ignoreExceptions = {Exception.class}
, observableExecutionMode = ObservableExecutionMode.EAGER
, raiseHystrixExceptions = {HystrixException.RUNTIME_EXCEPTION}
, defaultFallback = "findUserByIdFailure"
)
1.11 默认配置
对于一些默认的配置,可以使用@DefaultProperties,可以减少@HystrixCommand中的代码量,如下
@Service
@Slf4j
@DefaultProperties(groupKey = "MyGroup")
public class EurekaHystrixRibbonService {
@Autowired
RestTemplate restTemplate;
......





