記事ディレクトリ
Hystrix の重要な概念
https://github.com/Netflix/Hystrix/wiki/
使い方 https://github.com/Netflix/Hystrix
- サービスの低下: サーバーがビジーです。後でもう一度お試しください。クライアントを待たせずに、フレンドリーなプロンプトをすぐに返します。フォールバック
- サービス サーキット ブレーカー: シャットダウン、サービス ダウングレード -> その後サーキット ブレーカー -> 通話リンクを復元
- サービスの現在の制限: Flash は高い同時実行性やその他の操作を強制終了します。急いで集まったりすることは固く禁じられています。全員が 1 秒あたり N 個の列に並び、整然と進行します。
使用
POM
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
スタートアップクラス
@EnableHystrix
YML
feign:
hystrix:
enabled: true
例
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;
}
}
グローバルフォールバック
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
例: Hystrix が設定されていない場合は、@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ㄒ)/~~";
}
}
サービスが低下しています。クライアントがサーバーを呼び出し、サーバーがダウンまたはシャットダウンしています。
異常な:
- 走る
- タイムアウト
- ダウンタイム
インターフェイス Feign 呼び出しサービス インターフェイス
@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);
}
Service 実装クラスはすべての詳細をカバーし、Feign 呼び出しが失敗した場合には実装クラスのメソッドを呼び出します。
@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";
}
}
現時点では、サーバープロバイダーがダウンしていますが、
サーバーが利用できない場合に、サーバーをハングアップして強制終了することなく、クライアントが迅速な情報を取得できるように、サービスのダウングレード処理を実行しました。
サービスサーキットブレーカー
サービス低下 -> サーキット ブレーカー -> 通話リンクの復元
ノード マイクロサービスの通話応答が正常であることが検出されると、通話リンクが復元されます。
Spring Cloud フレームワークでは、サーキット ブレーカー メカニズムは Hystrix を通じて実装されます。Hystrix はマイクロサービス間の呼び出しのステータスを監視し、
失敗した呼び出しが特定のしきい値 (デフォルトでは 5 秒以内に 20 件の失敗した呼び出し) に達すると、サーキット ブレーカー メカニズムがアクティブになります。ヒューズ メカニズムのアノテーションは @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;
}
}
@HystrixCommand の commandProperties パラメーター
HystrixCommandProperties
クラスを見つける
Hystrix 実行プロセス
サービス監視 hystrixDashboard
POM
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
HystrixDashboardMain9001+新しいアノテーション @EnableHystrixDashboard
注:
@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;
}
}