這不是一篇Sentinel的基礎使用教程,基礎使用可以看sentinel官方文檔(雖然寫的不咋地)
這也不是一篇非常詳細的源碼領讀,源碼細節還需你自己仔細咀嚼
這只是我在改了些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 | /cnode | get clusterNode metrics by id, request param: id= | |
FetchJsonTreeCommandHandler | /jsonTree | 簇點鏈路 | |
FetchOriginCommandHandler | /origin | get origin clusterNode by id, request param: id= | |
FetchSimpleClusterNodeCommandHandler | /clusterNode | get all clusterNode VO, use type=notZero to ignore those nodes with totalRequest <=0 | |
FetchSystemStatusCommandHandler | /systemStatus | get system status | |
FetchTreeCommandHandler | /tree | get metrics in tree mode, use id to specify detailed tree root 統計信息 | |
ModifyRulesCommandHandler | /setRules | 更新規則 | |
OnOffGetCommandHandler | /getSwitch | get sentinel switch status | |
OnOffSetCommandHandler | /setSwitch | set sentinel switch, accept param: value= | |
SendMetricCommandHandler | /metric | get and aggregate metrics, accept param:startTime={startTime}&endTime={endTime}&maxLines={maxLines}&identify= | |
VersionCommandHandler | /version | sentinel版本 | 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);