SpringCloud Alibaba-Sentinel的使用

一、简介

官网:https://gitee.com/rmlb/Sentinel/wikis/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8?sort_id=3419419
对于sentinel的可视化说明:
sentinel要有效果,必须是在1秒内请求5次以上才会进行统计。

1.1 熔断降级限流

什么是熔断
A 服务调用 B 服务的某个功能,由于网络不稳定问题,或者 B 服务卡机,导致功能时
间超长。如果这样子的次数太多。我们就可以直接将 B 断路了(A 不再请求 B 接口),凡是
调用 B 的直接返回降级数据,不必等待 B 的超长执行。 这样 B 的故障问题,就不会级联影
响到 A。
什么是降级
整个网站处于流量高峰期,服务器压力剧增,根据当前业务情况及流量,对一些服务和
页面进行有策略的降级[停止服务,所有的调用直接返回降级数据]。以此缓解服务器资源的
的压力,以保证核心业务的正常运行,同时也保持了客户和大部分客户的得到正确的相应。
异同:
相同点:
1、为了保证集群大部分服务的可用性和可靠性,防止崩溃,牺牲小我
2、用户最终都是体验到某个功能不可用
不同点:
1、熔断是被调用方故障,触发的系统主动规则2、降级是基于全局考虑,停止一些正常服务,释放资源
什么是限流
对打入服务的请求流量进行控制,使服务能够承担不超过自己能力的流量压力

1.2 Hystrix 与 Sentinel 比较

在这里插入图片描述

二、使用步骤

主要分为几个步骤:
定义资源
定义规则
检验规则是否生效

2.1 定义资源

方式一★:主流框架的默认适配
方式二★:抛出异常的方式定义资源
方式三:返回布尔值方式定义资源
方式四★:注解方式定义资源
方式五:异步调用支持

三、springboot整合Sentinel

官网:https://gitee.com/rmlb/Sentinel/wikis/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8?sort_id=3419419

/**
 * 1、整合Sentinel
 *  1)、导入依赖 spring-cloud-starter-alibaba-sentinel
 *  2)、下载sentinel控制台
 *  3)、配置 sentinel 控制台地址信息
 *  4)、在控制台调整参数、【默认所有的流控规则保存在内存中,重启失效】
 *
 * 2、每一个微服务都导入 actuator :并配合 management.endpoints.web.exposure.include=*
 * 3、自定义 sentinel 流控返回的数据
 *
 * 4、使用Sentinel来保护feign远程调用,熔断;
 *  1)、调用方的熔断保护:feign.sentinel.enable=true
 *  2)、调用方手动指定远程服务的降级策略。远程服务被降级处理。触发我们的熔断回调方法
 *  3)、超大浏览的时候,必须牺牲一些远程服务。在服务的提供方(远程服务)指定降级策略;
 *      提供方是在运行,但是不允许自己的业务逻辑,返回的是默认的降级数据(限流的数据)
 *
 * 5、自定义受保护的资源
 *  1)、代码
 *          try (Entry entry = SphU.entry("seckillSkus")) {
 *              //业务逻辑
 *          } catch(Exception e) {}
 *
 *  2)、基于注解
 * // 原本的业务方法.
	@SentinelResource(blockHandler = "blockHandlerForGetUser")
	public User getUserById(String id) {
	    throw new RuntimeException("getUserById command failed");
	}
	
	// blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
	public User blockHandlerForGetUser(String id, BlockException ex) {
	    return new User("admin");
	}
 *
 */

在这里插入图片描述
在这里插入图片描述

第一步:引入依赖
在公共gulimall-common中引入

        <!--限流&熔断&降级-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
      

在每个微服务中引入

 <!--限流&熔断&降级   实现实时监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

查看版本
在这里插入图片描述
下载sentinel:https://github.com/alibaba/Sentinel/releases

第二步:在每个微服务中配置sentinel


#sentinel 限流&熔断&降级的配置
spring.cloud.sentinel.transport.dashboard=localhost:8080
#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
spring.cloud.sentinel.transport.port: 8719
#暴露所有端点,为了实时监控使用
management.endpoints.web.exposure.include=*
# 开启feign得熔断降级功能
feign.sentinel.enabled=true

在方法上添加注释: @SentinelResource

第三步:触发流量控制或者降级策略后的返回值自定义

/**
 * @Description: 自定义限流返回方法
 * @Created: with IntelliJ IDEA.
 * @createTime: 2020-07-13 11:30
 **/

@Configuration
public class GulimallSeckillSentinelConfig {

    public GulimallSeckillSentinelConfig() {

        WebCallbackManager.setUrlBlockHandler(new UrlBlockHandler() {
            @Override
            public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws IOException {
                R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(), BizCodeEnum.TO_MANY_REQUEST.getMessage());
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json");
                response.getWriter().write(JSON.toJSONString(error));
            }
        });

    }

}

在这里插入图片描述
第四步:配置Feign调用不成功的熔断控制
方式一:在feign的调用方进行熔断降级控制,比如在超大浏览的时候,必须牺牲一些远程服务的降级策略。远程服务被降级触发我们的熔断回调方法。
在这里插入图片描述

@Configuration
public class GulimallCouponSentinelConfig {

    public GulimallCouponSentinelConfig() {

        WebCallbackManager.setUrlBlockHandler(new UrlBlockHandler() {
            @Override
            public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws IOException {
                R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(), BizCodeEnum.TO_MANY_REQUEST.getMessage()).put("coupon","降级");
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json");
                response.getWriter().write(JSON.toJSONString(error));

            }
        });

    }

}

在这里插入图片描述

方式二:在feign的提供方进行熔断降级控制
测试代码在下面的内容:五、Feign调用失败的降级处理,处理时在feign的调用端
在这里插入图片描述
在这里插入图片描述
没有熔断时:
在这里插入图片描述
熔断后的降级处理,这是上一步配置的返回值类型。
在这里插入图片描述
如果远程微服务掉线就会进入本服务的feign错误回调
在这里插入图片描述

第五步:测试
测试主要分为几个步骤:
定义资源
定义规则
检验规则是否生效

由于资源的定义的有5种,所以测试也有5种,我们只拿方式二和方式四举例
方式一★:主流框架的默认适配
方式二★:抛出异常的方式定义资源
方式三:返回布尔值方式定义资源
方式四★:注解方式定义资源
方式五:异步调用支持
为了测试方便,我把方式二和方式四结合使用了

@Resource
    private CouponFeignService couponFeignService;
    @GetMapping("/getinfo")
    @ResponseBody
    @SentinelResource(value = "seckill-hello-method",blockHandler ="getInfoblockHandler")
    public R getInfo(){
        Map<String,Object> map = null;
        //  使用自定义的资源来进行限流熔断降级
        try (Entry entry = SphU.entry("seckill-hello-map")) {
            //业务逻辑
            map  = new HashMap<>();
            map.put("category","产品部");
        } catch(BlockException e) {
            System.out.println("maruis--限流---->" + e.getMessage());
        }
        R r = couponFeignService.getProductInfo("张三");
        r.put("data",map);
        return r;
    }

    /**
     * getInfo 方法限流熔断或降级后的回调
     * @return
     */
    public R getInfoblockHandler(BlockException e){
        return R.error().put("msg",e);
    }

在这里插入图片描述
在这里插入图片描述
定义限流规则:
在这里插入图片描述
测试
在这里插入图片描述
测试
在这里插入图片描述

四、sentinel控制台

默认:http://localhost:8080
1)、簇点路径
在这里插入图片描述

2)流控规则
通过簇点链路和流控规则都可以添加规则。
在这里插入图片描述

五、Feign调用失败的降级处理,处理时在feign的调用端

5.1 编写feign接口

value = “gulimall-coupon” 远程调用的微服务名称
fallback = CouponFeignServiceFallBack.class 远程调用失败的回调方法,注意这个回调方法时实现下面的feign接口的。

@FeignClient(value = "gulimall-coupon",fallback = CouponFeignServiceFallBack.class)
public interface CouponFeignService {

    /**
     * 查询最近三天需要参加秒杀商品的信息
     * @return
     */
    @GetMapping(value = "/coupon/seckillsession/Lates3DaySession")
    R getLates3DaySession();

    /**
     * 获取信息
     * @return
     */
    @GetMapping(value = "/hello/getinfo")
    R getProductInfo(String username);
}

5.2 编写feign调用失败的回调,这相当于本地降级

注意:
1)一定要把回调的方法注入到ioc容器中,这样5.1 的调用才可以引用它,此处用的@Component
2) 实现CouponFeignService 中的所有方法,这样哪个方法调用失败就会回调到哪个方法中,并且还会携带参数。

@Component
public class CouponFeignServiceFallBack implements CouponFeignService {
	@Override
	public R getLates3DaySession() {
		System.out.println("maruis------>" + "getLates3DaySession");
		return R.error();
	}

	@Override
	public R getProductInfo(String username) {
		System.out.println("maruis------>" + "getProductInfo");
		return R.error().put("data",username);
	}
}

5.3 通过controller 测试

    @Resource
    private CouponFeignService couponFeignService;
    @GetMapping("/getinfo")
    @ResponseBody
    public R getInfo(){
        return couponFeignService.getProductInfo("张三");
    }
    
    @GetMapping("/3day")
    @ResponseBody
    public R get3DayInfo(){
        R lates3DaySession = couponFeignService.getLates3DaySession();
        return lates3DaySession;
    }

5.4 远程服务的controller

@RestController
@RequestMapping("hello")
public class HelloController {
	@RequestMapping("/getinfo")
	public R getInfo() throws InterruptedException {
		TimeUnit.MILLISECONDS.sleep(300);
		System.out.println("maruis------>" + "获取商品信息");
		return R.ok().put("info","123456");
	}
}

5.4 测试效果

测试时:不要启动远程调用的微服务
在这里插入图片描述

六、网关限流

文档:https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81

6.1 添加依赖

 <!--限流&熔断&降级   实现实时监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

<!--        &lt;!&ndash;限流&熔断&降级&ndash;&gt;-->
<!--        <dependency>-->
<!--            <groupId>com.alibaba.cloud</groupId>-->
<!--            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>-->
<!--        </dependency>-->
        <!--
            sentinel 与网关的整合,前提是已经导入sentinel依赖,我们在上面的gulimall-common中已经导入了sentinel的依赖
            2.1.0.RELEASE 这个版本号与springboot的版本是一致的。
        -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>

6.2 配置

sentinel配置

#sentinel 限流&熔断&降级的配置
spring.cloud.sentinel.transport.dashboard=localhost:8080
#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
spring.cloud.sentinel.transport.port: 8719
#暴露所有端点,为了实时监控使用
management.endpoints.web.exposure.include=*
# 开启feign得熔断降级功能
feign.sentinel.enabled=true

限流熔断降级的回调配置

package com.atguigu.gulimall.config;

import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.fastjson.JSON;
import com.atguigu.common.exception.BizCodeEnum;
import com.atguigu.common.utils.R;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


@Configuration
public class SentinelGatewayConfig {

    public SentinelGatewayConfig() {
        GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
            //网关限流了请求,就会调用此回调
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {

                R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(), BizCodeEnum.TO_MANY_REQUEST.getMessage());
                String errorJson = JSON.toJSONString(error);

                Mono<ServerResponse> body = ServerResponse.ok().body(Mono.just(errorJson), String.class);
                return body;
            }
        });
    }

}

6.3 测试

添加限流规则
在这里插入图片描述
利用postman添加了请求头hello
在这里插入图片描述
也可以对某一组的分类行进限流策略
新建api分组
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

七、sentinel的持久化

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值