本文共 10003 字,大约阅读时间需要 33 分钟。
依赖:
cloud2020 pers.zhang.springcloud 1.0-SNAPSHOT 4.0.0 cloud-provider-hystrix-payment8001 org.springframework.cloud spring-cloud-starter-netflix-hystrix org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator pers.zhang.springcloud cloud-api-commons ${project.version} org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
配置:application.yml
server: port: 8001spring: application: name: cloud-provider-hystrix-paymenteureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://eureka7001.com:7001/eureka #defaultZone: http://eureka7001.com:7001/eureka,http://wureka7002.com:7002/eureka
Service:
@Servicepublic class PaymentService { /** * 正常访问,肯定OK * @param id * @return */ public String paymentInfo_OK(Integer id) { return "线程池:" + Thread.currentThread().getName() + " paymentInfo_OK, id:" + id; } /** * 超时错误 * @param id * @return */ @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") })//指定超时回调,时间为2秒 public String paymentInfo_TimeOut(Integer id) { //int a = 10 / 0; try { //睡3秒,模拟超时 TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } return "线程池:" + Thread.currentThread().getName() + " paymentInfo_TimeOut, id:" + id; } public String paymentInfo_TimeOutHandler(Integer id) { return "线程池:" + Thread.currentThread().getName() + " 系统繁忙,请稍后再试, id:" + id + "超时回调"; }}
Controller:
@RestController@Slf4jpublic class PaymentController { @Resource PaymentService paymentService; @Value("${server.port}") String serverPort; @GetMapping("/payment/hystrix/ok/{id}") public String paymentInfo_OK(@PathVariable("id") Integer id) { String result = paymentService.paymentInfo_OK(id); log.info("*****result:" + result); return result; } @GetMapping("/payment/hystrix/timeout/{id}") public String paymentInfo_TimeOut(@PathVariable("id") Integer id) { String result = paymentService.paymentInfo_TimeOut(id); log.info("*****result:" + result); return result; }}
启动类:
@SpringBootApplication@EnableEurekaClient@EnableCircuitBreaker//开启public class PaymentHystrixMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentHystrixMain8001.class, args); }}
依赖:
cloud2020 pers.zhang.springcloud 1.0-SNAPSHOT 4.0.0 cloud-consumer-feign-hystrix-order80 org.springframework.cloud spring-cloud-starter-openfeign org.springframework.cloud spring-cloud-starter-netflix-hystrix org.springframework.cloud spring-cloud-starter-netflix-eureka-client pers.zhang.springcloud cloud-api-commons ${project.version} org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
配置:application.yml
server: port: 80eureka: client: register-with-eureka: false service-url: defaultZone: http://eureka7001.com:7001/eureka/feign: hystrix: enabled: true #开启hystrix
Service:
@Component@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")//指定调用的服务名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);}
Controller:
@RestController@Slf4jpublic class OrderHystrixController { @Resource 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")//超时1.5秒 }) public String paymentInfo_TimeOut(@PathVariable("id") Integer id) { String result = paymentHystrixService.paymentInfo_TimeOut(id); return result; } public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id) { return "我是消费者80,对方支付系统繁忙,请10秒后再试或者自己运行出错请检查自己。"; }}
启动类:
@SpringBootApplication@EnableFeignClients@EnableHystrix//开启Hystrixpublic class OrderHystrixMain80 { public static void main(String[] args) { SpringApplication.run(OrderHystrixMain80.class, args); }}
我们在服务的提供方和消费方都使用了Hystrix,但是多数情况下只在消费方配置Hystrix。
启动Eureka,在启动支付和订单微服务。
先在8001端口进行本地测试:
访问:localhost:8001/payment/hystrix/ok/35
,成功
访问:localhost:8001/payment/hystrix/timeout/33
,失败,程序中睡眠3秒,触发Hystrix设置的2秒时限,服务降级,调用fallback方法:
通过80端口使用Feign调用8001:
访问:localhost/consumer/payment/hystrix/ok/22
:成功:
localhost/consumer/payment/hystrix/timeout/11
:失败,订单模块作为消费方做出的超时限制为1.5秒,等待1.5秒无返回立即触发服务降级,调用fallback方法。 每个方法都有一个fallback方法,为了避免代码膨胀,应该有一个同一的方法和自定义的fallback方法分开。
可以在类上加@Defaultproperties注解指定一个通用的fallback方法,凡是标注了@HystrixCommand但没有指定@HystrixProperty的方法,均使用@DefaultProperties指定的fallback方法。
修改80端口的Controller:
@RestController@Slf4j@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")public class OrderHystrixController { @Resource 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}") //未指定fallback,使用@DefaultProperties指定的payment_Global_FallbackMethod @HystrixCommand // @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod", commandProperties = { // @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")//超时1.5秒 // }) public String paymentInfo_TimeOut(@PathVariable("id") Integer id) { int a = 10 / 0; String result = paymentHystrixService.paymentInfo_TimeOut(id); return result; } public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id) { return "我是消费者80,对方支付系统繁忙,请10秒后再试或者自己运行出错请检查自己。"; } //默认fallback public String payment_Global_FallbackMethod() { return "Global异常处理信息,请稍后再试..."; }}
重启,访问:localhost/consumer/payment/hystrix/timeout/33
,失败,跳转到全局fallback:
目前业务逻辑和fallback都混在一起,应该将两者分开。
只需要为Feign客户端定义的接口添加一个服务降级处理的实现 类即可实现解耦。
新建类PaymentFallbackService,实现PaymentHystrixService接口:
@Componentpublic class PaymentFallbackService implements PaymentHystrixService { @Override public String paymentInfo_OK(Integer id) { return "-------PaymentFallbackService paymentInfo_OK fall back--------"; } @Override public String paymentInfo_TimeOut(Integer id) { return "-------PaymentFallbackService paymentInfo_TimeOut fall back--------"; }}
在@FeignClient中指明fallback处理类:
重启服务,访问:localhost/consumer/payment/hystrix/ok/55
,成功:
关闭8001服务,模拟宕机,再次访问:localhost/consumer/payment/hystrix/ok/55
:失败,执行PaymentFallbackService中对应的fallback方法
转载地址:http://hspqb.baihongyu.com/