BlackHole开发日记-尝试NIO和ehcache

今天上班的路上在对比Tomcat和Jety的链接模型。Tomcat使用多线程处理请求,一个请求一个线程;Jetty则采用NIO。有文章说,对于逻辑复杂、处理时间较长的链接,Tomcat有优点,可是对于处理时间较短的链接,Jetty有优点。毫无疑问DNS的处理时间是很短的,看来把以前connector部分多线程的处理模型换成NIO的,应该性能会有一些提高。之后几天一个大的开发计划,就是调研Java NIO和Jetty里的实现,写一个完整的NIO connector。Cache机制开发延后。java

上午在网上找了点资料,磕磕碰碰把基于NIO的服务器模型搭出来了。由于DNS使用的是UDP协议,同时数据量很小,因此NIO并无起到理想中的效果。git

主要服务器部分代码在https://github.com/flashsword20/blackhole/blob/nio/src/main/java/us/codecraft/blackhole/connector/UDPSocketMonitor.java。测试以后的效果让人失望,NIO效率比多线程+BIO更低,只有24000~28000qps,而且由于代码不熟悉,系统变得很不稳定。因此暂时保留到NIO分支了。github

结论是这样的:缓存

一个DNS query的包大小大约是几十byte,而response也不超过100 byte,如此小的传输量,同时由于UDP包也不涉及链接创建等东西,发送速度也很快,因此NIO发挥不了效率。服务器

晚上回家,尝试加入cache机制:网络

使用了ehcache,可是死活都存在UDP包乱序的问题。后来发现数据结构

对于同一key,ehcache获取出来的对象老是同一个,这也是进程内缓存的特殊之处,不妨将其想一想为一个Map多线程

而我会尝试改变其ID值,结果就致使看起来ID变了,其实也改变了其余线程获取到的值,出现了不肯定性!并发

后来改进了数据结构,尝试写一个CopyOnWriteMessage(Message是dnsjava中DNS报文的抽象类),结果由于其不少方法都是私有,因此失败了。后来构建了一个UDPPackage的对象,尝试将byte[]用CopyOnWrite和访问锁的方式解决并发问题,测试结果CopyOnWrite性能会好一点,这也是由于数据量较小,并且Arrays.copyOf是本地方法吧。性能

后来测试,值得高兴的是有缓存的状况下,转发模式效率达到了40000qps,可喜可贺!

家里连公司,benchmark里,UDP丢包率大概在10%,效果至关差,因此说网络才是第一要素!

相关文章
相关标签/搜索