官网:https://sentinelguard.io/zh-cn/index.html

项目介绍:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

钉钉讨论群2:30150716

1.安装

下载:https://github.com/alibaba/Sentinel/releases

启动:(全部使用默认配置)

java -jar sentinel-dashboard-1.7.2.jar

默认的访问端口为:8080,默认的登录帐号和密码都是:sentinel

启动时指定端口,是否监控自己,项目名称,登录的帐号和密码:

java -Dserver.port=8480 -Dcsp.sentinel.dashboard.server=localhost:8480 -Dproject.name=sentinel-dashboard -Dsentinel.dashboard.auth.username=sentinel -Dsentinel.dashboard.auth.password=123456 -jar sentinel-dashboard-1.7.2.jar

参数说明:(注意:参数要放到 -jar的前边)

-Dserver.port=8480 # 指定控制台的端口为8480

-Dcsp.sentinel.dashboard.server=localhost:8480 # 指定要被哪个控制台监控(这里指定的是自己监控自己)

-Dproject.name=sentinel-dashboard # 指定实例名称(名称会在控制台左侧以菜单显示)

-Dsentinel.dashboard.auth.username=sentinel # 设置登录的帐号为:sentinel

-Dsentinel.dashboard.auth.password=123456 # 设置登录的密码为:123456

重启后访问:http://localhost:8480/ 

更多的参数参考:

启动配置:https://github.com/alibaba/Sentinel/wiki/%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E9%A1%B9

登录鉴权:https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0#%E9%89%B4%E6%9D%83

2.SpringCloud项目使用Sentinel进行管理

新建项目:https://start.spring.io/

添加配置:application.yml

server:
    port: 8321
spring:
    application:
        name: alibaba-sentinel # 项目名称,如果不写Sentinel会自己产生一个有端口号的名称
    cloud:
        sentinel:
            transport:
                # 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互
                port: 8719
                
                # sentinel控制台地址
                dashboard: localhost:8480

添加一个Service类:.

package com.example.service;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Service;

@Service
public class TestService {

    @SentinelResource(value = "sayHello")
    public String sayHello(String name) {
        return "Hello, " + name;
    }
}

添加一个控制器添加访问端口:

package com.example.controller;

import com.example.service.TestService;
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.RestController;

@RestController
public class IndexController {
    @Autowired
    private TestService service;

    @GetMapping(value = "/hello/{name}")
    public String apiHello(@PathVariable String name) {
        return service.sayHello(name);
    }
}

启动。

必须先访问一下:http://localhost:8321/hello/abc123,Sentinel中才会有监控项出现。

3.做一下限流看看

先对访问路径做下限流

 有了一条规则 

1秒内刷新超过1次,就被限制掉了

换成对资源进行限流

1秒内多次刷新:

抛出异常,所以这里要在代码里做一下限流的处理了。

给Service添加一个限流时的方法:

package com.example.service;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;

@Service
public class TestService {

    @SentinelResource(value = "sayHello", blockHandler = "blockHandler")
    public String sayHello(String name) {
        return "Hello, " + name;
    }

    /**
     * 被限流时调用的方法
     * @param str 被限流的方法的参数
     * @param ex 限流异常
     * @return String
     */
    public String blockHandler(String str, BlockException ex){
        return "被限流了。。。"+str;
    }
}

超出流量时的提示:

代码整理:TestService.java

package com.example.service;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;

@Service
public class TestService {

    @SentinelResource(value = "sayHello", blockHandler = "blockHandler", fallback = "fallBack")
    public String sayHello(String name) {
        if (name.equals("1")) {
            throw new ExceptionInInitializerError("出异常了,参数不能是:" + name);
        }
        return "Hello, " + name;
    }

    /**
     * 处理java代码中的异常,不管有没有达到Sentinel中的配置<br>
     * 只要java代码中出现异常就会调用,如果断流的方法被调用,则这个方法不被调用
     *
     * @param name 被控制的方法的参数
     * @param e 代码中抛出的异常,这个参数是可选的
     * @return
     */
    public String fallBack(String name, Throwable e) {
        System.err.println("Java代码有异常:"+e.getMessage());
        return "业务方法中出现异常: " + name + " -> " + e.getMessage();
    }

    /**
     * 根据Sentinel中(对资源名)的配置(流控/降级)来进行处理<br>
     * 当达到Sentinel中配置的条件阈值时将会调用(如:单位时间内超过流量限制,单位时间内超过异常数量的限制)
     *
     * @param name 被控制的方法的参数
     * @param e 断流的异常,参数必须加,不加这个参数即使达到了断流条件也不会执行
     * @return
     */
    public String blockHandler(String name, BlockException e) {
        return "超过了Sentinel中的设置,被断流了。。。" + name + " " + e.getMessage();
    }

}

4.半自动的持久化设置

Sentinel一个比较显著的问题,就是随着项目的重启,原来做好的配置就都没有了,还需要再配置。这点如果是在生产环境是不能发生的。做一个瘸腿的持久化(使用Nacos)。这个持久化的配置是用Nacos+微服务端实现的,在Sentinel的控制台修改后无法同步给Nacos。也就是在Nacos上配置后,由微服务端读取配置,然后同步给Sentinel。

首先,先启动好Nacos,在Nacos的public命名空间中添加一个配置项:

[
    {
        "resource": "sayHello",
        "limitApp": "default",
        "grade": 1,
        "count": 5,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

然后,给微服务的项目引入nacos的数据源jar包。这个包去maven库里找:

https://mvnrepository.com/search?q=nacos+datasource

去掉version和scope

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

最后,在微服务这边的application.yml中添加数据源的配置:

server:
    port: 8321
spring:
    application:
        name: alibaba-sentinel # 项目名称,如果不写Sentinel会自己产生一个有端口号的名称
    cloud:
        sentinel:
            transport:
                # 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互
                port: 8719
                
                # sentinel控制台地址
                dashboard: localhost:8480
                
            datasource:
                ds1:
                    nacos:
                        server-addr: localhost:8848 # nacos 地址(数据源地址)
                        data-id: sentinel-config # 配置项名称
                        data-type: json # 数据格式
                        rule-type: flow

启动项目,访问下然后去Sentinel查看下

不知道阿里为啥不把持久化这块做完整,难道是为了卖阿里云? (还有种方式是在微服务端存文件)

完毕。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐