高扩展的基于NIO的服务器架构(二)

接上文高扩展的基于NIO的服务器架构

Reactor模式

如下图所示,将不同事件的检测分离开,当一种事件发生时一个事件处理器EventHandler将通知与该事件处理相对应的专用工作线程

高扩展的基于NIO的服务器架构(二)

采用这种架构,连接的通道不得不注册在一个Selector上。这样才能通过调用register方法使通道有效。

未完待续

...

SocketChannel channel = serverChannel.accept();

channel.configureBlocking(false);



// register the connection

SelectionKey sk = channel.register(selector, SelectionKey.OP_READ);

...


 为了达到检测新事件的目的,Selector类具备向已注册channel所要它们的就绪事件的能力。通过调用select方法,Selector类收集到了已注册channel的就绪事件。在至少这些就绪事件中的一个事件已经完成之前,select方法是处于阻塞状态下的。这种情况下,select方法返回截至最后一次调用select方法时已经对I/O操作做好准备的连接的数量值。

已选择的连接可以通过调用Selector类的selectedKey方法被检索到。selectedKey方法会返回SelectionKey对象的一个结果集,这些结果集保持了IO事件的状态和连接的Channel的引用。

Selector被Dispatcher控制 。Dispatcher是一个单线程的类。与Selector是组合关系。Dispatcher类负责检索事件以及调遣处理所消耗的调度事件的EventHandler。通过循环,Dispatcher类调用Selector类的select方法来等待新事件。当新的事件进来时,select方法返回,同时先关联的channel通过调用selectedKeys方法被收回。

...

while (isRunning) {



	// blocking call, to wait for new readiness events

	int eventCount = selector.select();

	

	// get the events

	Iterator<SelectionKey> it = selector.selectedKeys().iterator();

	

	while(it.hasNext()) {

	

		SelectionKey key = it.next();

		it.remove();

		

		// readable event?

		if (key.isValid() && key.isReadable()) {

		

			eventHandler.onReadableEvent(key.channel());

		

		}

		

		// writable event?

		if (key.isValid() && key.isWritable()) {

		

			key.interestOps(SelectionKey.OP_READ);

			eventHandler.onWriteableEvent(key.channel());

		

		}

	

		...

	

	}

	

	...



}


像准备写或者准备读这样的事件,Dispatcher会调用EventHandler来处理。EventHandler负责解码请求数据,处理所需的服务活动,编码相应数据。由于工作线程为等待新的请求而而浪费事件,可扩展性和吞吐量的瓶颈只取决于系统资源如CPU或内存。因为需要线程切换好同步,响应时间上会逊色于传统的每个线程负责一个连接的架构。而这种事件驱动方式的架构是用来减少同步,优化线程管理,因此,这方面的开销忽略不计。

未完待续

 

你可能感兴趣的:(nio)