CAT源码分析5 - 服务端消息接收

本文深入解析CAT服务端如何接收并处理消息。初始化阶段涉及TcpSocketReceiver和MessageDecoder,其中Decoder对消息进行解码。消息消费采用生产者消费者模式,通过PeriodManager和PeriodStrategy管理消息分析器,按小时划分处理,提高处理效率并避免内存泄漏。RealtimeConsumer和PeriodTask协同工作,使用BlockingQueue暂存消息并进行消费。
摘要由CSDN通过智能技术生成

深度解析Cat源码系列专栏点击访问

CAT源码分析5 - 服务端消息接收

1. TcpSocketReceiver初始化

在CAT服务端启动初始化过程中,CatHomeModule在初始化时,会通过setUp()和execute()两个方法实现对消息接收器的初始化。

  • 通过setUp方法完成对Netty客户端网络通信的初始化
  • execute方法中有其他功能的初始化逻辑,包括对消息消费者的初始化

整体的初始化逻辑如下图
在这里插入图片描述

com.dianping.cat.CatHomeModule#setup 设置方法如下

  • 通过Peluxs容器实例化TcpSocketReceiver,并执行init初始化
  • 对进程设置销毁监听
@Override
protected void setup(ModuleContext ctx) throws Exception {
   
	final TcpSocketReceiver messageReceiver = ctx.lookup(TcpSocketReceiver.class);
	messageReceiver.init();
    // 销毁监听
	Runtime.getRuntime().addShutdownHook(new Thread() {
   
		@Override
		public void run() {
   
			messageReceiver.destory();
		}
	});
}

com.dianping.cat.analysis.TcpSocketReceiver#init的初始化逻辑如下:

  • 主要负责实例化Netty客户端,开启对2280端口通信的监听
  • 选择网络通信方式时,根据操作系统,linux下使用epoll更加高效
  • 绑定消息编解码器、设置网络配置参数
  • m_logger是通过Plexus容器的LoggerManager自动初始化注入的,LoggerManager默认设置为Log4j。该logger的打印是落磁盘的
public void init() {
   
	try {
   
        // 默认2280端口启动Netty客户端
		startServer(m_port);
	} catch (Exception e) {
   
		m_logger.error(e.getMessage(), e);
	}
}

public synchronized void startServer(int port) throws InterruptedException {
   
	// 根据操作系统,设置netty的相关工作线程数量和channel通信方式
    boolean linux = getOSMatches("Linux") || getOSMatches("LINUX");
	int threads = 24;
	ServerBootstrap bootstrap = new ServerBootstrap();
	m_bossGroup = linux ? new EpollEventLoopGroup(threads) : new NioEventLoopGroup(threads);
	m_workerGroup = linux ? new EpollEventLoopGroup(threads) : new NioEventLoopGroup(threads);
	bootstrap.group(m_bossGroup, m_workerGroup);
    // linux使用epoll
	bootstrap.channel(linux ? EpollServerSocketChannel.class : NioServerSocketChannel.class);
	bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
   
		@Override
		protected void initChannel(SocketChannel ch) throws Exception {
   
			ChannelPipeline pipeline = ch.pipeline();
			// pipeline添加消息编解码器
			pipeline.addLast("decode", new MessageDecoder());
			pipeline.addLast("encode", new ClientMessageEncoder());
		}
	});
	// 对bootstrap进行网络通信配置
	bootstrap.childOption(ChannelOption.SO_REUSEADDR, true);
	bootstrap.childOption(ChannelOption.TCP_NODELAY, true);
	bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
	bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
	try {
   
		m_future = bootstrap.bind(port).sync();
		m_logger.info("start netty server!");
	} catch (Exception e) {
   
		m_logger.error("Started Netty Server Failed:" + port, e);
	}
}

2. MessageDecoder消息解码器

MessageDecoder继承了ByteToMessageDecoder类,在netty通道上有消息进入时会被调用。对Byte字节码进行解析。且,MessageDecoder是TcpSocketReceiver的一个内部类,直接引用了后者注入的MessageHandler和ServerStatisticManager,是服务端消息处理的入口。
在这里插入图片描述

在其代码中,首先对消息定长读取,获取消息的长度,实现对半包/粘包问题的处理。之后,读到消息体,通过NativeMessa

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值