Ciaran是Skimlinks项目团队中的一名领导者,热爱开发,在业余时间喜欢研究一门新语言。作者和他的团队在开发Skimlinks项目时遇到了一些困难,于是做了这份测试,文中将Node.js、Scala、Go、Python、PHP进行对比,最终Python获胜,目的的是为了让开发者为stack挑选最好的开发技术。
在过去的这段时间里,我之所以杳无音讯,是因为作为这个项目的领头人,我正从事一项有趣的项目,我们将其命名为“Skimlinks”。
我的大部分工作是从事后端引擎开发和支持SkimWords产品进程,通过一些非常完美的高科技进行识别和添加代销商网络产品链接从而让网站主获取利润。这是一种新颖的线上广告模式,相比于页面上的大幅banners图我更喜欢这种新颖的模式,我们正在尝试为用户添加有价值的信息如产品价格比较、添加链接让用户可直接购买想要的产品。
开发环境:
大部分前端开发是用PHP编写的,当公司需要快速、灵活开发项目时,选择PHP是个不错的选择。但是随着公司既定产品的知名度不断提高以及搜索的高并发访量,PHP正日益成为我们发展的一个瓶颈。
存在问题:
使用Apache多选程模块(MPM),apache会阻碍大量的搜索请求,当出现高并发访量时,页面无法响应。
这里有一个快速的方法可提高服务器的吞吐量增加工作进程,然而当RAM快要耗尽时,将会受到限制。每个进程都有独立的RAM数据块,增长和搜索取决于PHP在哪个点上,当没有足够的空间释放时,你必须将OOMing关闭(它可以迅速的将吞吐量降至为0)。
最可行的扩大规模的方法就是把项目管理模块从Apache prefork MPM换成更出色、更快速的Apache worker MPM。通过改变多进程大大增加了服务器请求数,唯一的缺陷只是为了这个工作而工作,PHP必须能够保证处理多个并发线程不会产生死机,然而事实并非如此。PHP的核心是多线程,因此我门认为它可能是因为某些驱动或者延长使用而导致失败,然而无论出于什么原因,PHP不在符合我们的需求。
为此,引发了我们会选择哪种语言进行开发而争论不休,每个人都在推崇他们喜欢的语言,有人赞成、有人反对。很明显,众口难调,没有一个衡量标准是很难选出来的,因此,我们决定用各个语言来测试一个系统,看它们的执行情况在做定夺。
参赛语言:
基本规则是,如果你想要某语言进行测试必须愿意提供执行API请求数,最后推选出:
挑战:
我们选择了一个非常简单的日志API系统,所做的这些是为了从JSON请求数中抓取详细信息,采用MD5,用于确保信息传输完整一致。(主流编程语言普遍都用MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理)每个执行阶段都将使用Apache Benchmark(Apache附带的一个小工具,专门用于HTTP Server的benchmark testing,可以同时模拟多个并发请求)来评估各种语言开发并发水平速度。
当Node.js和Python Tornado以单一线程运行时,使用Nginx(一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器 )来查看这两个实例。
针对Scala我甚至特意编写一份old-school Servlet(一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面,它担当客户请求Web浏览器或其他HTTP客户程序与服务器响应的中间层)在基于tomcat下运行。
采用AWS(Asp Web Server是一款基于netbox开发的asp web服务器,其个小功能强大,基本上能够取代IIS成为广大Asp程序员和网站开发者的利器)直接在服务器上执行基准,以消除任何一个网络瓶颈。
通过mongo删除每次测试数据,每次测试至少执行3次,选取平均值,以确保有足够的“热身”时间和消除任何异常结果。
通过在多个并发值下进行测试((10,50,100,200,500,1000),一起来看下在高负荷的情况下,性能发生了什么变化。
测试结果:
每秒请求数:这个测试给了我们一个实现纯速度的想法,最明显的一点(越高越好)。
有一点值得我很欣慰,Scala独占鳌头。PHP(正如预期所想的那样)受多线程的限制,香消玉损。另一个让我震撼的是Go语言当并发访量不断增加时,它以平缓的速度迅速下滑,最终也Over了。如期所料,两个单线程non-blocking solutions(node和 python)性能差不多,python要比Node稍微好点。
响应时间:
尽管每秒请求数进程的吞吐量呈现出一个好的迹象,但是同样重要的是在高负荷的情况下,表现很糟糕。由图表得知,在一段时间内完成的请求数比例,越低越好。
100并发请求数:
在这里,我们看到Scala需要的时间最少,而其他几门语言之间没有太大区别。
200并发请求数:
图中,我们看到有趣的现象,以9秒速度来计算请求数,Go和PHP都有受到影响,花费的时间比较多。
500并发请求数:
在500并发需求时,使用9—14秒完成请求。PHP无法响应,Go语言花费时间较多,占最高值。
1000并发需求数:
当我们遇到数以千计的请求数时, Go语言Over了,通过测试,根据apache规则要求超过50%的失败率就算出局。如图所示Node和Python依然存在,可以清楚的看到其性能特性。但是Python比Node要更好一点。但在第一幅图上,Python表现的要稍微差一点。
通过测试,能清楚的分辨出各语言的性能表现,以上测试的这些数据是我们APIs中的一部分,因此对我们来说非常重要。
Scala表现的很好,几乎很完美,我把它归功于在连接池的Mongo数据库中单独接入MessageDigests和快速进行JSON分析程序。我不确定Go语言到底是怎么了,也许是我使用的Mongo驱动的问题,但无论是什么原因,看到它这么差的表现真的让我很难过。
最后决定:
最终,我们经过讨论决定选择Python!Scala如此之快,我们为什么不选择Scala而另选Python呢?原因如下:
Scala这门语言很难,我需要很久才能将简单的API整合在一起,才能进行工作,python阅读起来就像haiku,而Scala阅读就像蛇类游戏一样。
线性编程是很痛苦的,对Scala来说,很容易也很安全,简单的单线程non-blocking解决方案总是很吸引人,但我们应该不断的去尝试挑战。
整个团队在Python上有着丰富的经验,如果让大家去接受一门新的语言,尤其像Scala这样的既昂贵又费时间。
此前网络速度、数据库查询等API成为我们发展的一个瓶颈,而今,我们已经找到正确的解决方案——Python,我们只需等待执行和发布,希望这个决定是正确的。
英文出自:skimlinks