异步非阻塞 async_netrpc_server for openerp 简介及简单测试
-
async_netrpc_server 是使用tornado 的ioloop 实现的异步非阻塞的net-rpc socket server for openerp。此模块是由本人开发并维护,现已托管在google code 上(http://code.google.com/p/openerp-asynchronous-non-blocking-net-rpc-server/),在google code 上,我写了简单的安装方法,有兴趣的朋友可以下载并测试。此模块为开源项目,欢迎大家参与。
为什么要开发这个模块? 因为Openerp 官方的net-rpc server 是采取select 轮询的的socket 线程池模式,在一般情况下是没有任何问题的,但是如果在高并发的密集请求下,这种模式就会显得比较落后了。而tornado 是由facebook 开发的高性能框架,其核心是使用linux 的epoll (mac / bsd 下用 kqueue)实现异步非阻塞的socket模型。当然,windows下还是使用select 轮询,但并不是说windows 就一点都没用,线程池模式需要频繁创建和销毁对象,这对系统资源来说是一个很大的开销,而异步非阻塞的模型避免了这个缺点。所以,我在看了OE的代码之后,就萌生了这个想法,并因此有了这个模块。
那么,这个模块到底怎么样?是骡子是马,拉出来溜溜。。。我做了简单的测试,请看下面。
软硬件环境
DELL 1420 笔记本
CPU:Intel(R) Core(TM)2 Duo CPU T5450 @ 1.66GHz
内存:1G
硬盘:160G
操作系统:Debian Linux 2.6.39-2-686-pae #1 SMP Tue Jul 5 03:48:49 UTC 2011 i686 GNU/Linux
OpenERP Server版本:openerp-server-6.0.3
OpenERP web client:openerp-web-6.0.3
CherryPY 版本:3.1.2
相关参数设置
Openerp Server:
1、编辑 netrpc_server.py 修改 self.socket.listen(1024)。这个是官方的net-rpc server 的socket 等待队列,默认值是5,10个并发就挂了,所以必须修改。
2、编辑openerp-server.conf 添加db_maxconn = 128。这个是数据库连接池,默认值是64。
3、编辑openerp-server.conf,设置 xmlrpc = False 和 xmlrpcs = False,不启动http xmlrpc 服务 和 https xmlrpc服务。
4、测试官方的net-rpc server 时,编辑 openerp-server.conf 中 netrpc = True ,async_netrpc = False ,只启动官方的net-rpc server 。
5、测试async_netrpc_server 时,编辑 openerp-server.conf 中 netrpc = False ,async_netrpc = True ,只启动async_netrpc_serve。
Opery Web Client:
1、打开openerp-web.cfg,确认 server.environment = "development"(如果你是源码下载,这个就是默认值,无须修改)。
2、测试官方的net-rpc server 时,编辑openerp-web.cfg 中 openerp.server.port = '8070' 。
3、测试async_netrpc_server 时,编辑openerp-web.cfg 中 openerp.server.port = '8008' 。
CherryPY:编辑_cpserver.py 修改 socket_queue_size = 500 和 thread_pool = 1024。详细的修改方式和说明,请参见拙文Openerp压力测试:Openerp到底能支撑多大的用户数?。
测试过程
一、使用本人编写oetest.py 测试 10000总任务100并发测试(程序请到拙文Openerp压力测试:多线程直连OE Server NET-RPC/XML-RPC端口测试下载)
测试官方的net-rpc server 时,修改oetest.py 参数 PORT = '8070' 。测试async_netrpc_server 时,修改oetest.py 参数 PORT = '8008' 。
1、 官方的net-rpc server 测试结果<br />$ ./oetest.py <br /><br />Start at 2011-08-25 20:58:17.636473<br />End at 2011-08-25 20:59:35.510676<br /><br />Total Time: 0:01:20.874203<br />
2、 async_netrpc_server 测试结果<br />$ ./oetest.py <br /><br />Start at 2011-08-25 20:53:15.829595<br />End at 2011-08-25 20:54:18.310178<br /><br />Total Time: 0:01:02.480583<br />
从上面的结果来看,官方的net-rpc server处理时间是 80.87秒,async_netrpc_server 的处理时间是 62.48。(80.87−62.48)÷62.48 = %29.43 也就是说 async_netrpc_server 大概比官方的net-rpc server快 29%左右。那么,实际情况是否有如此大的差距呢?下面我们用ab (ApacheBench)来模拟下实际情况。
二、通过ab 测试/openerp/form/view?model=sale.order&id=1 地址,1000总任务1000并发。
本次测试的框架是 ab -> OpenERP Web Client -> OpenERP Server
1、 官方的net-rpc server 测试结果(点击下载测试文件)<br />$ ab -n 1000 -c 1000 -C session_id=16273c836063c55a73ff154f048884b450b76bed 'http://127.0.0.1:8080/openerp/form/view?model=sale.order&id=1'<br /><br />Server Software: CherryPy/3.1.2<br />Server Hostname: 127.0.0.1<br />Server Port: 8080<br /><br />Document Path: /openerp/form/view?model=sale.order&id=1<br />Document Length: 92818 bytes<br /><br />Concurrency Level: 1000<br />Time taken for tests: 372.131 seconds<br />Complete requests: 1000<br />Failed requests: 0<br />Write errors: 0<br />Total transferred: 93073000 bytes<br />HTML transferred: 92818000 bytes<br />Requests per second: 2.69 [#/sec] (mean)<br />Time per request: 372131.152 [ms] (mean)<br />Time per request: 372.131 [ms] (mean, across all concurrent requests)<br />Transfer rate: 244.25 [Kbytes/sec] received<br />
内存占用情况:
测试前:23.3M。测试使用firefox 登录并访问地址 /openerp/form/view?model=sale.order&id=1 ,然后察看进程内存占用情况。
[img [检测到链接无效,已移除] /img]
测试后:27.3M。测试完成1000任务后,察看进程内存占用情况。
[img [检测到链接无效,已移除] /img]
测试过程中,观察内存上升情况,发现是随着测试任务完成情况而线性增长的。
2、 async_netrpc_server 测试结果(点击下载测试文件)<br />$ ab -n 1000 -c 1000 -C session_id=9d82bf71745241afba1451f7fc8206e7a09a6e2d 'http://127.0.0.1:8080/openerp/form/view?model=sale.order&id=1'<br /><br />Server Software: CherryPy/3.1.2<br />Server Hostname: 127.0.0.1<br />Server Port: 8080<br /><br />Document Path: /openerp/form/view?model=sale.order&id=1<br />Document Length: 92818 bytes<br /><br />Concurrency Level: 1000<br />Time taken for tests: 365.387 seconds<br />Complete requests: 1000<br />Failed requests: 0<br />Write errors: 0<br />Total transferred: 93073000 bytes<br />HTML transferred: 92818000 bytes<br />Requests per second: 2.69 [#/sec] (mean)<br />Time per request: 371386.709 [ms] (mean)<br />Time per request: 371.387 [ms] (mean, across all concurrent requests)<br />Transfer rate: 244.74 [Kbytes/sec] received<br /><br />
内存占用情况:
测试前:23.3M。测试使用firefox 登录并访问地址 /openerp/form/view?model=sale.order&id=1 ,然后察看进程内存占用情况。
[img [检测到链接无效,已移除] /img]
测试后:23.8M。测试完成1000任务后,察看进程内存占用情况。
[img [检测到链接无效,已移除] /img]
测试过程中观察,完成100任务后内存上升到23.8之后就一直停留在23.8,没有再增长。
从以上的对比情况来看,处理时间基本上没有多大的差距,(372.131−365.387)÷365.387 = %1.845 。但是从内存占用情况来看,async_netrpc_server 仅增长了0.5M,而官方的net-rpc server 则增长了4M ,显示出 8 倍的差距。
结论
通过以上的测试,async_netrpc_server 对比 官方的 net-rpc 模块,显示出一些性能的优势。
1、第一种测试中的29%差距,应该仅是表明async_netrpc_server 异步非阻塞框架的优秀性能。而oe实际应用情况则比较复杂,涉及缓存、数据库读取等。所以,在第二种测试中,差距不到2%,也是正常情况。
2、第二种测试中,内存占用情况有8倍的差距,这个表明线程池模型在面对高并发时很有可能成为系统瓶颈。官方的net-rpc server 使用的线程池模型频繁创建销毁对象,带来较大的性能开销,虽说python有垃圾回收机制,但问题是你不知道它什么时候回收。如果线程池销毁的对象一直没有被回收的话,那将是一场灾难。
以上的测试,仅仅是本人在有限条件下进行的,并且受限于与本人知识水平,测试结果仅供各位参考。非常欢迎大家试用并测试async_netrpc_server模块。也欢迎大家和我讨论,我的联系方式在页面最下方。谢谢!
本文转自本人博客 [检测到链接无效,已移除] ,测试文件和程序请到本人博客下载。谢谢! -
兄弟技术精湛,才思敏捷,论述有理有据,行文流畅,图文并茂。
读你的文章非常受启发,本人甚是佩服。希望能看到更多此类文章。