SpringCould-降级

系统负载过⾼,突发流量或者⽹络等各种异常情况介绍,常⽤的解决⽅案

1、熔断:

保险丝,熔断服务,为了防⽌整个系统故障,包含⼦和下游服务
下单服务 -》商品服务
-》⽤户服务 (出现异常-》熔断)

2、降级:

抛弃⼀些⾮核⼼的接⼝和数据
旅⾏箱的例⼦:只带核⼼的物品,抛弃⾮核⼼的,等有条件的时候再去携带这些物品

3、熔断和降级互相交集

相同点:
1)从可⽤性和可靠性触发,为了防⽌系统崩溃
2)最终让⽤户体验到的是某些功能暂时不能⽤
不同点
1)服务熔断⼀般是下游服务故障导致的,⽽服务降级⼀般是从整体系统负荷考虑,由调⽤⽅
控制

增加的pom.xml

        <!--feign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>


        <!--hystrix依赖,主要是用  @HystrixCommand -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>


        <!--springboot整合redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

启动类添加注解

@EnableCircuitBreaker
package com.sxpcwlkj.order_server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
public class OrderServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServerApplication.class, args);
    }


    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }


}

controller 服务降级

http://localhost:8781/api/v1/order/selectByIdTwo?id=1

    @Autowired
    private StringRedisTemplate redisTemplate; 

    /**
     *
     * @param id
     * @return Feign 方式请求
     */
    @GetMapping("selectByIdTwo")
    @HystrixCommand(fallbackMethod = "saveOrderFail")

    public JsonResultObject selectByIdTwi(int id, HttpServletRequest request){
        try {
            return orderService.selectById(id);
        }catch (Exception e){
            e.printStackTrace();
            logger.error(e.getMessage());
            return JsonResultObject.getErroeResult(e.getMessage());
        }

    }

    //注意,方法签名一定要要和api方法一致
    private JsonResultObject saveOrderFail(int id, HttpServletRequest request){


        //监控报警
        String saveOrderKye = "save-order";
        String sendValue = redisTemplate.opsForValue().get(saveOrderKye);
        final String ip = request.getRemoteAddr();
        new Thread( ()->{
            if (StringUtils.isBlank(sendValue)) {
                System.out.println("紧急短信,用户下单失败,请离开查找原因,ip地址是="+ip);
                //发送一个http请求,调用短信服务 TODO
                redisTemplate.opsForValue().set(saveOrderKye, "save-order-fail", 20, TimeUnit.SECONDS);

            }else{
                System.out.println("已经发送过短信,20秒内不重复发送");
            }

        }).start();

        return JsonResultObject.getErroeResult("抢购人数太多,您被挤出来了,稍等重试");
    }

案例1:模拟请求超时

接口方法添加注解 @HystrixCommand(fallbackMethod = “saveOrderFail”)

创建一个方法捕获的方法上加上注解

saveOrderFail (注意,方法签名一定要要和api方法一致)

当请异常时,会走此方法

posted @ 2021-07-16 15:09  烟燃烟灭  阅读(100)  评论(0编辑  收藏  举报