1、Sentinel 教程进阶 Sentinel-API

这也不是一篇非常详细的源码领读,源码细节还需你自己仔细咀嚼

这只是我在改了些sentinel bug后,梳理的脉络,主要是脉络。看完后对Sentinel的源码模块划分和大致交互有个整体印象。

从而在想知道细节时知道从哪里下手。

Sentinel功能强大,但是开源出来的sentinel可以说是一个半成品,bug多,并且很多功能没有实现,可能是因为它有收费的版本吧。因此我们如果想在生产上应用就要戒骄戒躁,了解它的源码,对它进行优化改造。在改造过程中不可避免的要调用sentinel的api接口进行一些规则的同步等操作。

监听端口

服务集成sentinel的方式

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

启动服务后,一旦访问了接口,sentinel会通过websocket或netty的方式监听8719(默认)端口,提供一些接口方便我们以http的方式调用取获取、修改sentinel的限流规则,集群配置等。

监听的端口默认是8719,但是如果端口被占用,就会换自动换端口,具体换端口逻辑是8719+重试次数/3,这个没什么意思,不比深究。

代码实现

具体启动端口监听的逻辑在com.alibaba.csp.sentinel.transport.init.CommandCenterInitFunc中,该类在sentinel-transport-common模块中,具体依赖如下

 

@InitOrder(-1)
public class CommandCenterInitFunc implements InitFunc {

    @Override
    public void init() throws Exception {
        //commandCenter默认是SimpleHttpCommandCenter
        CommandCenter commandCenter = CommandCenterProvider.getCommandCenter();

        if (commandCenter == null) {
            RecordLog.warn("[CommandCenterInitFunc] Cannot resolve CommandCenter");
            return;
        }

        commandCenter.beforeStart();
        //启动监听
        commandCenter.start();
        RecordLog.info("[CommandCenterInit] Starting command center: "
                + commandCenter.getClass().getCanonicalName());
    }
}

上述代码中commandCenter默认是SimpleHttpCommandCenter,如果引入sentinel-transport-netty-http,则它就会变成NettyHttpCommandCenter,具体原因是sentinel为spi类定义了一个order属性,NettyHttpCommandCenter的order属性更高

 

 

具体模块之间的关系如下如

 

端口可通过参数:csp.sentinel.api.port指定。

具体启动逻辑可以自己跟一下,比较简单。

api接口

具体有哪些接口呢?

com.alibaba.csp.sentinel.command.CommandHandler接口的所有实现类

我们可以通过调用localhost:port/api获取到所有的api

 

这些handler基本上分布在三个模块中

  • sentinel-transport-common:提供一些规则相关的,基本的接口
  • sentinel-cluster-client-default:集群客户端相关接口
  • sentinel-cluster-server-default:集群服务端相关接口

sentinel-transport-common

ApiCommandHandler/api获取所有接口
FetchClusterModeCommandHandler/getClusterMode获取集群模式信息
ModifyClusterModeCommandHandler/setClusterMode修改集群模式
BasicInfoCommandHandler/basicInfo获取服务基本信息
FetchActiveRuleCommandHandler/getRules获取规则,参数type flow|degrade|authority|system
FetchClusterNodeByIdCommandHandler/clusterNodeById根据id查询clustNode信息
FetchClusterNodeHumanCommandHandler/cnodeget clusterNode metrics by id, request param: id=
FetchJsonTreeCommandHandler/jsonTree簇点链路
FetchOriginCommandHandler/originget origin clusterNode by id, request param: id=
FetchSimpleClusterNodeCommandHandler/clusterNodeget all clusterNode VO, use type=notZero to ignore those nodes with totalRequest <=0
FetchSystemStatusCommandHandler/systemStatusget system status
FetchTreeCommandHandler/treeget metrics in tree mode, use id to specify detailed tree root 统计信息
ModifyRulesCommandHandler/setRules更新规则
OnOffGetCommandHandler/getSwitchget sentinel switch status
OnOffSetCommandHandler/setSwitchset sentinel switch, accept param: value=
SendMetricCommandHandler/metricget and aggregate metrics, accept param:startTime={startTime}&endTime={endTime}&maxLines={maxLines}&identify=
VersionCommandHandler/versionsentinel版本1.8.1

sentinel-cluster-client-default

FetchClusterClientConfigHandler/cluster/client/fetchConfig获取集群-客户端配置
ModifyClusterClientConfigHandler/cluster/client/modifyConfig修改集群-客户端配置

sentinel-cluster-server-default

FetchClusterFlowRulesCommandHandler/cluster/server/flowRules获取集群限流规则
FetchClusterParamFlowRulesCommandHandler/cluster/server/paramRules获取集群热点参数规则
FetchClusterServerConfigHandler/cluster/server/fetchConfig获取集群server配置
FetchClusterServerInfoCommandHandler/cluster/server/info获取集群server信息
FetchClusterMetricCommandHandler/cluster/server/metricList获取集群统计信息
ModifyClusterFlowRulesCommandHandler/cluster/server/modifyFlowRules修改集群限流规则
ModifyClusterParamFlowRulesCommandHandler/cluster/server/modifyParamRules修改集群热点参数规则
ModifyClusterServerFlowConfigHandler/cluster/server/modifyFlowConfig待查看
ModifyClusterServerTransportConfigHandler/cluster/server/modifyTransportConfig修改集群server配置
ModifyServerNamespaceSetHandler/cluster/server/modifyNamespaceSet修改namespace信息

 

public class SimpleHttpCommandCenter implements CommandCenter {

public void run() {
    boolean success = false;
    ServerSocket serverSocket = SimpleHttpCommandCenter.getServerSocketFromBasePort(this.port);
    if (serverSocket != null) {
        CommandCenterLog.info("[CommandCenter] Begin listening at port " + serverSocket.getLocalPort(), new Object[0]);
        SimpleHttpCommandCenter.this.socketReference = serverSocket;
        SimpleHttpCommandCenter.this.executor.submit(SimpleHttpCommandCenter.this.new ServerThread(serverSocket));
        success = true;
        this.port = serverSocket.getLocalPort();
    } else {
        CommandCenterLog.info("[CommandCenter] chooses port fail, http command center will not work", new Object[0]);
    }

    if (!success) {
        this.port = -1;
    }

    TransportConfig.setRuntimePort(this.port);
    SimpleHttpCommandCenter.this.executor.shutdown();
}
}

项目集成sentinel启动后,api服务并不会启动,而是等到项目被访问的时候才会被启动,具体的方式是启动一个netty服务监听8719端口(默认)

SphU.entry("testRule1", EntryType.IN, 1, id);