Cindy有感

 
taowen 写道
简单看了一下大牛写 的Cindy框架。小弟纯粹是一个服务器应用的新手,发表一点个人意见。我发现 Cindy的做法大概是这样的,Socket来开Chanel,然后把自己attach到key上。然后多个socket共用一个 eventgenerator,里面有一个while(true)的循环,从selector中取出ready的key,然后从key的附件中取出这个 key所属的socket(或者说session啦)。然后在循环内调用process然后是onEvent。如果对于多可客户端的情况,应该是服务器有 两个基本的线程,主线程开socket,处理事件。generator内的线程获得nio那ready的key,触发事件。



理解上基本正确,除开启动JVM的主线程外,最基本的线程应该只有一个,就是EventGenerator内部维护的一个线程。

taowen 写道
我是完全的 新手不知道这样的朴素的多线程交互会不会有问题,是不是有什么生产者消费者模型之类的东西啊。不过直觉上来说如果onEvent要处理很久的话,会影响 selectKey的速度,也就是服务器的响应就慢了。基本的两线程并发应该是肯定无法满足性能要求的吧。呵呵,SEDA学习中。



第一,Cindy并没有限制你使用什么样的模型。最基本的模型是所有的Session共用一个EventGenerator,即用一个线程 handle所有的连接。你也可以每200个Session用一个,这要在实际的环境上进行测试调整,哪种模型效率最高就采用哪种模型。Cindy并没有 规定一定要只使用一个线程handle所有的连接。

第二,OnEvent是在Session内部实现处理的,而不是由应用处理的,所以你想象中的那个“如果”其实是不存在的。应用是通过 SessionListener来监听相应的事件,而这个事件是由Dispatcher来分发的。即使在上一步中,所有的Session都使用同一个 EventGenerator,但是可以通过一个Dispatcher池来分发事件,彼此之间也不会阻塞。举个很简单的例子,比如两个Session共用 一个EventGenerator,但是它们彼此的Dispatcher是不同的,这样即使其中一个在SessionListener中休眠,也不会影响 到另一个Session处理网络操作。

第三,如果服务器只有一个CPU,用一个EventGenerator来handle所有的连接也并不会效率低下;但在多CPU的情况下结果会有些不同。建议可以读一读《Java NIO》一书4.5节“Selection Scaling”。

 

 

 

 

 

 

 

 

 

另外提一下,使用NIO来进行异步操作,基本上就是以下三种模型:
[list]

  • 1 Worker/1 Dispatcher
  • 1 Worker/n Dispatcher
  • m Worker/n Dispatcher[/list:u]
  • Cindy的默认设置是第一种,即用一个线程来处理所有的连接。应用在SessionListener中监听相应的事件,在处理过程中耗时非常长的话,会影响到其他的网络连接。

    如果采用第二种模型,则可以通过Session.setDispatcher(Dispatcher),比如每个Session置一个独立的Dispatcher线程。这样SessionListener中进行长时间处理也不会影响到其他的网络连接。

    如果要采用第三种模型,除开setDispatcher以为,还需要通过 Session.setEventGenerator(EventGenerator)来设置事件生成器。比如可以若干个Session共用一个 EventGenerator,另外的若干Session共用另一个。

    这三种模型之间进行选择并不会影响用户的业务逻辑处理,可以在最后进行性能调优时,在具体情况下进行测试,再进行调节即可。

    你可能感兴趣的:(Cindy有感)