数据库中间件Mycat源码解析(二):Mycat的网络通讯层

网络层主要的就是ServerSocketChannel和SocketChannel(请参照NIO2看此篇blog),讲Myca通讯层前首先得说几个概念:

FrontEnd/BackEnd:mycat将网络通讯分成了两部分,第一部分叫FrontEnd即负责接收业务方用户请求的部分;第二部分叫BackEnd即负责和后端数据库通讯的部分。

AIO/NIO/BIO:BIO是jdk1.4以前就提供的同步阻塞IO方式,NIO是JDK1.4以后开始提供的新的同步非阻塞IO方式,AIO是NIO2中提供的异步非阻塞IO方式。性能依次递增。

Connector/Acceptor:前者负责客户端发起连接,后者负责服务端接收请求。

Connection:表示连接的对象。

FrontendConnection:前端连接对象,在Reactor中被引用,负责接收前端数据,将数据导向可以处理该信息的Proccessor,并将数据库查询结果返回给客户端。

BackendConnection:后端连接对象,负责连接数据库,将查询sql发送给数据库并将查询结果返回。

FrontEnd部分mycat提供三种不同IO方式,BackEnd部分提供AIO的IO方式和数据库连接。FrontEnd的源码主要在net包下,BackEnd的源码主要在backend包下。

MycatServer在调用start()方法启动时会创建一个AIOReactor(当然也可能是NIOReactor),AIOReactor会打开Socket并进行监听,一旦客户端有数据出入则调用回调函数accept处理数据。这时它会用FrontendConnectionFactory(FrontEnd中负责将请求包装成FrontendConnection的是ServerConnectionFactory,它继承自FrontendConnectionFactory)的make方法包装socket。包装完成后会注册一个NIOProcessor到connection上,并调用register方法发送一个HandshakePacket包(此处的握手包不同于TCP连接是的握手概念)给客户端异步等待客户端回应。这样客户端就和mycat建立起了连接,后续的处理流程比如sql解析,sql路由到对应的流程会在后面的章节中讲到。

通讯层还是比较简单的,使用了BIO/NIO/AIO等socket读写方式,下面以NIOAcceptor和AIOAcceptor的源码比较下两者的不同:

NIOAcceptor.java

@Override
	public void run() {
		final Selector tSelector = this.selector;
		//死循环
		for (;;) {
			++acceptCount;
			try {
				//NIO中selector的select方法,不断轮询注册在其上的channel,一旦有数据进来就返回,最多等待1秒
			    tSelector.select(1000L);
				//获取返回selectedKeys
				Set<SelectionKey> keys = tSelector.selectedKeys();
				try {
					for (SelectionKey key : keys) {
						//一旦数据是可处理的就调用accept()方法处理
						if (key.isValid() && key.isAcceptable()) {
							accept();
						} else {
							key.cancel();
						}
					}
				} finally {
					keys.clear();
				}
			} catch (Exception e) {
				LOGGER.warn(getName(), e);
			}
		}
	}

	private void accept() {
		SocketChannel channel = null;
		try {
			//接收客户端连接
			channel = serverChannel.accept();
			//非阻塞方式
			channel.configureBlocking(false);
			//获取连接
			FrontendConnection c = factory.make(channel);
			c.setAccepted(true);
			c.setId(ID_GENERATOR.getId());
			//注册processor发送命令进行通讯
			NIOProcessor processor = (NIOProcessor) MycatServer.getInstance()
					.nextProcessor();
			c.setProcessor(processor);
			
			//reactor线程池处理
			NIOReactor reactor = reactorPool.getNextReactor();
			reactor.postRegister(c);

		} catch (Exception e) {
	        LOGGER.warn(getName(), e);
			closeChannel(channel);
		}
	}

AIOAcceptor.java

private void accept(NetworkChannel channel, Long id) {
		try {
			FrontendConnection c = factory.make(channel);
			c.setAccepted(true);
			c.setId(id);
			NIOProcessor processor = MycatServer.getInstance().nextProcessor();
			c.setProcessor(processor);
			c.register();
		} catch (Exception e) {
		    LOGGER.error("AioAcceptorError", e);
			closeChannel(channel);
		}
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值