客户端处理服务端下发请求
sentinel客户端中会存储一些限流规则而这些限流规则是我们通过页面配置后由服务端下发下来的,下面让我们来看看客户端是如何接收服务端下发的命令的
上面我们分析了在执行init方法时HeartbeatSenderInitFunc心跳处理,现在我们继续分析一下CommandCenterInitFunc方法来完成sentinel服务端发送过来的请求相关操作
@InitOrder(-1)
public class CommandCenterInitFunc implements InitFunc {
@Override
public void init() throws Exception {
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());
}
}
beforeStart方法会将所有处理器已key-value的形式注册到handlermap中,其中key为CommandMapping注解配置的名称,value为对应的命令处理器
public void beforeStart() throws Exception {
// Register handlers 注册处理器
Map<String, CommandHandler> handlers = CommandHandlerProvider.getInstance().namedHandlers();
registerCommands(handlers);
}
public Map<String, CommandHandler> namedHandlers() {
Map<String, CommandHandler> map = new HashMap<String, CommandHandler>();
for (CommandHandler handler : serviceLoader) {
String name = parseCommandName(handler);
if (!StringUtil.isEmpty(name)) {
map.put(name, handler);
}
}
return map;
}
private String parseCommandName(CommandHandler handler) {
//通过注解获取handler名称
CommandMapping commandMapping = handler.getClass().getAnnotation(CommandMapping.class);
if (commandMapping != null) {
return commandMapping.name();
} else {
return null;
}
}
注册处理器完成后执行start方法,启动命令中心
public void start() throws Exception {
//cpu核数
int nThreads = Runtime.getRuntime().availableProcessors();
//创建处理请求线程池
this.bizExecutor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(10),
new NamedThreadFactory("sentinel-command-center-service-executor"),
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
CommandCenterLog.info("EventTask rejected");
throw new RejectedExecutionException();
}
});
Runnable serverInitTask = new Runnable() {
int port;
{
try {
//从配置文件中获取配置的监听端口
port = Integer.parseInt(TransportConfig.getPort());
} catch (Exception e) {
port = DEFAULT_PORT;
}
}
@Override
public void run() {
boolean success = false;
//创建ServerSocket
ServerSocket serverSocket = getServerSocketFromBasePort(port);
if (serverSocket != null) {
CommandCenterLog.info("[CommandCenter] Begin listening at port " + serverSocket.getLocalPort());
socketReference = serverSocket;
executor.submit(new ServerThread(serverSocket));
success = true;
port = serverSocket.getLocalPort();
} else {
CommandCenterLog.info("[CommandCenter] chooses port fail, http command center will not work");
}
if (!success) {
port = PORT_UNINITIALIZED;

本文详细描述了Sentinel客户端如何接收并处理服务端下发的命令,包括初始化CommandCenter、注册处理器、命令中心启动,以及处理HTTP请求,特别是涉及限流规则的加载和存储过程。
最低0.47元/天 解锁文章
3万+

被折叠的 条评论
为什么被折叠?



