什么是服务降级
小王现在非常饿,打开美团外卖选好了外卖,小王选择微信支付,刚好微信支付这个时候使用的人比较多,有的上传文件,有的聊天,导致现在微信响应非常慢,那么小王使用微信支付超过两秒未完成支付,那么我们是不是提示小王,现在业务繁忙,请稍后重试,不应该报超时错误吧。
栗子也举了,是不是要实际行动证明了
- 80 服务调用者 比如美团
- 8001 服务提供者 比如微信
- 7001 注册中心
- 7002 注册中心
前提是先把注册中心和服务调用先学好,这个我就不讲了。这篇只讲服务降级
8001微信支付接口
main
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class HystrixPaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(HystrixPaymentMain8001.class,args);
}
}
controller
import com.guigu.cloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/weixin")
@Slf4j
public class PaymentController {
@Autowired
private PaymentService paymentService;
/**
* 支付接口
* @param money 钱
* @return
*/
@GetMapping("/paymoney/{money}")
public String payMoney(@PathVariable("money") int money){
log.info("正在请求微信支付接口,money="+money);
return paymentService.payMoney(money);
}
}
service 实现类
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class PaymentService {
@Value("${server.port}")
private String servicePro;
/**
* 超时2秒 执行paymentInfo_TimeOutHandler
* @param money
* @return
*/
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "2000")})
public String payMoney(int money){
//模拟微信支付接口超时
try {
Thread.sleep(3*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "支付成功,一共支付了:"+money+"调用端口是:"+servicePro;
}
/**
* 兜底方法
* @param money
* @return
*/
public String paymentInfo_TimeOutHandler(int money){
return "业务繁忙,请稍后重试";
}
}
80美团
main
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class HystrixOpenFeigOrderMain80 {
public static void main(String[] args) {
SpringApplication.run(HystrixOpenFeigOrderMain80.class,args);
}
}
controller
import com.guigu.cloud.service.PaymentHystrixService;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 模拟美团后台调用微信支付后台接口
*/
@RestController
@RequestMapping("/meituan")
public class PaymentController {
@Autowired
private PaymentHystrixService paymentHystrixService;
/**
*
* @param money 钱
* @return
*/
@GetMapping("/weixinpaymoney/{money}")
public String weixinPayMoney(@PathVariable("money") int money){
return paymentHystrixService.weixinPayMoney(money);
}
}
service
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Service
@FeignClient(value = "CLOUD-HYSTRIX-PAYMENT-SERVICE")
public interface PaymentHystrixService {
@GetMapping("/weixin/paymoney/{money}")
String weixinPayMoney(@PathVariable("money") int money);
}
是驴是马拉出来遛遛是吧
最后解析一波:微信服务8001使用Thread.sleep(31000),造成服务使用很多人的情况,造成线程阻塞,然后直接超时。返回给美团服务80,告诉美团服务80,我现在自己都这样了,不给你使用了,你等我好点再说
那么我们把微信服务8001使用Thread.sleep(31000)去掉再看看结果:
最后呢就是这个服务降级是可以作用在消费端也可以作用在服务端,具体看业务需求。按照上方的写法代码耦合度过高,我写一个接口,就要写一个兜底方法,这样太繁琐,不利于后期的维护和二次开发。那么这种适合一些特殊的接口需要单独写兜底方法。
全局服务降级(服务端),美团80服务
美团80服务service
import com.guigu.cloud.service.impl.PaymentServiceImpl;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Service
/**
* PaymentServiceImpl 兜底实现
*/
@FeignClient(value = "CLOUD-HYSTRIX-PAYMENT-SERVICE",fallback = PaymentServiceImpl.class)
public interface PaymentHystrixService {
@GetMapping("/weixin/paymoney/{money}")
String weixinPayMoney(@PathVariable("money") int money);
}
service兜底方法具体实现
import com.guigu.cloud.service.PaymentHystrixService;
import org.springframework.stereotype.Component;
@Component
public class PaymentServiceImpl implements PaymentHystrixService {
@Override
public String weixinPayMoney(int money) {
return "微信支付异常,请稍后再试";
}
}