zoukankan      html  css  js  c++  java
  • 高扩展的基于NIO的服务器架构(二)

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

    Reactor模式

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

    采用这种架构,连接的通道不得不注册在一个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或内存。因为需要线程切换好同步,响应时间上会逊色于传统的每个线程负责一个连接的架构。而这种事件驱动方式的架构是用来减少同步,优化线程管理,因此,这方面的开销忽略不计。

    未完待续

  • 相关阅读:
    Leetcode [654] 最大二叉树 &[105] 从前序与中序遍历序列构造二叉树 & [106] 从中序与后序遍历序列构造二叉树
    Leetcode [226] 翻转二叉树 & [116] 填充每个节点的下一个右侧节点指针 & [114] 二叉树展开为链表
    Leetcode 链表&二叉树刷题总结
    Leetcode 动态规划刷题总结
    Leetcode [1312] 让字符串成为回文串的最少插入次数 动态规划
    Leetcode [234] 回文链表 回文 链表
    动态规划之 KMP 算法详解(转)
    Leetcode [99] 恢复二叉搜索树 二叉树
    统计代码行数
    二叉树遍历(递归、非递归、mirror)转
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3429074.html
Copyright © 2011-2022 走看看