Directorio de artículos
Conceptos importantes de Hystrix
https://github.com/Netflix/Hystrix/wiki/How-To-Use
https://github.com/Netflix/Hystrix
- Degradación del servicio: el servidor está ocupado, inténtelo de nuevo más tarde, no deje que el cliente espere y devuelva un mensaje amigable de inmediato, retroceda
- Disyuntor de servicio: apagar, degradación del servicio -> luego disyuntor -> restaurar el enlace de llamada
- Límite actual del servicio: Flash elimina la alta concurrencia y otras operaciones, está estrictamente prohibido apresurarse y aglomerarse, todos hacen cola, N por segundo, y proceden de manera ordenada
usar
POM
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
clase de inicio
@EnableHystrix
YML
feign:
hystrix:
enabled: true
ejemplo
package com.atguigu.springcloud.service;
import cn.hutool.core.util.IdUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Service
public class PaymentService
{
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="2000")
})
public String paymentInfo_TimeOut(Integer id)
{
//int age = 10/0;
try {
TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) {
e.printStackTrace(); }
return "线程池: "+Thread.currentThread().getName()+"success";
}
public String paymentInfo_TimeOutHandler(Integer id)
{
return "线程池: "+Thread.currentThread().getName()+"business"+id;
}
//=====服务熔断
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),// 是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),// 请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), // 时间窗口期
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),// 失败率达到多少后跳闸
})
public String paymentCircuitBreaker(@PathVariable("id") Integer id)
{
if(id < 0)
{
throw new RuntimeException("******id 不能负数");
}
String serialNumber = IdUtil.simpleUUID();
return Thread.currentThread().getName()+"\t"+"调用成功,流水号: " + serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id)
{
return "id 不能负数,请稍后再试,/(ㄒoㄒ)/~~ id: " +id;
}
}
Repliegue global
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
Ejemplo: si Hystrix no está configurado, use el método en @DefaultProperties
@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class OrderHystirxController
{
@Resource
private PaymentHystrixService paymentHystrixService;
@GetMapping("/consumer/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id)
{
String result = paymentHystrixService.paymentInfo_OK(id);
return result;
}
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
})
//@HystrixCommand
public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
{
int age = 10/0;
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
}
public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id)
{
return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o";
}
// 下面是全局fallback方法
public String payment_Global_FallbackMethod()
{
return "Global异常处理信息,请稍后再试,/(ㄒoㄒ)/~~";
}
}
El servicio está degradado, el cliente llama al servidor y el servidor está apagado o apagado.
anormal:
- correr
- se acabó el tiempo
- Falta del tiempo
La interfaz Feign llama a la interfaz de Servicio.
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT" ,fallback = PaymentFallbackService.class)
public interface PaymentHystrixService
{
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
La clase de implementación del Servicio cubre todos los detalles y llama a los métodos en la clase de implementación cuando la llamada de Feign no tiene éxito.
@Component
public class PaymentFallbackService implements PaymentHystrixService
{
@Override
public String paymentInfo_OK(Integer id)
{
return "-----PaymentFallbackService fall";
}
@Override
public String paymentInfo_TimeOut(Integer id)
{
return "-----PaymentFallbackService fall TimeOut";
}
}
En este momento, el proveedor del servidor ha estado inactivo, pero hemos realizado un procesamiento de degradación del servicio
para que el cliente reciba información rápida cuando el servidor no esté disponible sin colgar y cerrar el servidor.
Disyuntor de servicio
Degradación del servicio -> luego disyuntor -> restaurar el enlace de llamada.Cuando
se detecta que la respuesta de llamada del microservicio del nodo es normal, se restaura el enlace de llamada.
En el marco de Spring Cloud, el mecanismo de disyuntor se implementa a través de Hystrix. Hystrix monitoreará el estado de las llamadas entre microservicios.
Cuando las llamadas fallidas alcanzan un cierto umbral, el valor predeterminado es 20 llamadas fallidas en 5 segundos, se activará el mecanismo de disyuntor. La anotación del mecanismo del fusible es @HystrixCommand.
@Service
public class PaymentService
{
//=====服务熔断
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),// 是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),// 请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), // 时间窗口期
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),// 失败率达到多少后跳闸
})
public String paymentCircuitBreaker(@PathVariable("id") Integer id)
{
if(id < 0)
{
throw new RuntimeException("******id 不能负数");
}
String serialNumber = IdUtil.simpleUUID();
return Thread.currentThread().getName()+"\t"+"调用成功,流水号: " + serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id)
{
return "id 不能负数,请稍后再试,/(ㄒoㄒ)/~~ id: " +id;
}
}
parámetro commandProperties en @HystrixCommand
Buscar HystrixCommandProperties
categoría
Proceso de ejecución de Hystrix
Monitoreo de servicios hystrixDashboard
POM
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
HystrixDashboardMain9001+nueva anotación @EnableHystrixDashboard
Nota:
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001
{
public static void main(String[] args) {
SpringApplication.run(PaymentHystrixMain8001.class, args);
}
/**
*此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
*ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream",
*只要在自己的项目里配置上下面的servlet就可以了
*/
@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;
}
}