Ribbon+Hystrix断路器实现微服务的降级和熔断

微服务宕机时,Ribbon无法实现转发请求,因此引入Hystrix.

Hystrix短路器的核心功能:
  1. 降级: 当后台微服务不可用或访问超时时,则转向执行降级代码,或返回错误信息,或返回缓存数据;
  2. 熔断: 默认配置下,后台微服务10秒内收到的请求达到20个,并且有一半的请求(50%)出现请求失败降级的情况,则Hystrix打开断路器(断路器默认关闭closed),表示后台微服务不可用,让所有请求执行降级代码;当断路器打开5秒后转为半开闭状态,该状态表示当有请求到达时,会尝试向后台微服务转发。如果请求成功,则关闭短路器,表示所有的请求都可请求到达后台微服务;若仍请求失败,则短路器仍保持打开状态。
1. 创建SpringBoot项目,添加依赖:

Ribbon+Hystrix断路器实现微服务的降级和熔断_第1张图片

2. 添加Hystrix依赖:
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
3. 添加自己项目的common工具类依赖:

Ribbon+Hystrix断路器实现微服务的降级和熔断_第2张图片

4. application.yml文件中进行相关配置:

Ribbon+Hystrix断路器实现微服务的降级和熔断_第3张图片

5.主启动类上加注解 @EnableCircuitBreaker和@EnableDiscoveryClient:

这三个注解可以用@SpringCloudApplication一个代替
Ribbon+Hystrix断路器实现微服务的降级和熔断_第4张图片

6. 创建RibbonController类,在该类中编写springMVC的controller方法,此外指定对应的降级方法,并在controller方法上通过注解标明指定的降级方法:
package com.tedu.sp7.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.tedu.sp01.pojo.Item;
import com.tedu.sp01.pojo.Order;
import com.tedu.sp01.pojo.User;
import com.tedu.web.util.JsonResult;

@RestController
public class RibbonController {
	@Autowired
	private RestTemplate rt;
	
	@GetMapping("/item-service/{orderId}")
	@HystrixCommand(fallbackMethod = "getItemsFB") //指定降级方法的方法名
	public JsonResult<List<Item>> getItems(@PathVariable String orderId) {
		return rt.getForObject("http://item-service/{1}", JsonResult.class, orderId);
	}

	@PostMapping("/item-service/decreaseNumber")
	@HystrixCommand(fallbackMethod = "decreaseNumberFB")
	public JsonResult decreaseNumber(@RequestBody List<Item> items) {
		return rt.postForObject("http://item-service/decreaseNumber", items, JsonResult.class);
	}

	/
	
	@GetMapping("/user-service/{userId}")
	@HystrixCommand(fallbackMethod = "getUserFB")
	public JsonResult<User> getUser(@PathVariable Integer userId) {
		return rt.getForObject("http://user-service/{1}", JsonResult.class, userId);
	}

	@GetMapping("/user-service/{userId}/score") 
	@HystrixCommand(fallbackMethod = "addScoreFB")
	public JsonResult addScore(@PathVariable Integer userId, Integer score) {
		return rt.getForObject("http://user-service/{1}/score?score={2}", JsonResult.class, userId, score);
	}
	
	/
	
	@GetMapping("/order-service/{orderId}")
	@HystrixCommand(fallbackMethod = "getOrderFB")
	public JsonResult<Order> getOrder(@PathVariable String orderId) {
		return rt.getForObject("http://order-service/{1}", JsonResult.class, orderId);
	}

	@GetMapping("/order-service")
	@HystrixCommand(fallbackMethod = "addOrderFB")
	public JsonResult addOrder() {
		return rt.getForObject("http://order-service/", JsonResult.class);
	}
	
	/

    //降级方法的参数和返回值,需要和原始方法一致,方法名任意
	public JsonResult<List<Item>> getItemsFB(String orderId) {
		return JsonResult.err("获取订单商品列表失败");
	}
	public JsonResult decreaseNumberFB(List<Item> items) {
		return JsonResult.err("更新商品库存失败");
	}
	public JsonResult<User> getUserFB(Integer userId) {
		return JsonResult.err("获取用户信息失败");
	}
	public JsonResult addScoreFB(Integer userId, Integer score) {
		return JsonResult.err("增加用户积分失败");
	}
	public JsonResult<Order> getOrderFB(String orderId) {
		return JsonResult.err("获取订单失败");
	}
	public JsonResult addOrderFB() {
		return JsonResult.err("添加订单失败");
	}

}
Hystrix常用配置:
  • hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
    请求超时时间,超时后触发失败降级
  • hystrix.command.default.circuitBreaker.requestVolumeThreshold
    10秒内请求数量,默认20,如果没有达到该数量,即使请求全部失败,也不会触发断路器打开
  • hystrix.command.default.circuitBreaker.errorThresholdPercentage
    失败请求百分比,达到该比例则触发断路器打开
  • hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds
    断路器打开多长时间后,再次允许尝试访问(半开),仍失败则继续保持打开状态,如成功访问则关闭断路器,默认 5000
参考链接: https://github.com/Netflix/Hystrix/wiki/Configuration

你可能感兴趣的:(Hystrix)