sentinel源码分析-02客户端处理服务端下发请求

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

客户端处理服务端下发请求

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;
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值