编程语言API性能大比拼
Ciaran是Skimlinks項目團(tuán)隊中的一名領(lǐng)導(dǎo)者,熱愛開發(fā),在業(yè)余時間喜歡研究一門新語言。作者和他的團(tuán)隊在開發(fā)Skimlinks項目時遇到了一些困難,于是做了這份測試,文中將Node.js、Scala、Go、Python、PHP進(jìn)行對比,最終Python獲勝,目的的是為了讓開發(fā)者為stack挑選最好的開發(fā)技術(shù)。
在過去的這段時間里,我之所以杳無音訊,是因為作為這個項目的領(lǐng)頭人,我正從事一項有趣的項目,我們將其命名為“Skimlinks”。
我的大部分工作是從事后端引擎開發(fā)和支持SkimWords產(chǎn)品進(jìn)程,通過一些非常完美的高科技進(jìn)行識別和添加代銷商網(wǎng)絡(luò)產(chǎn)品鏈接從而讓網(wǎng)站主獲取利潤。這是一種新穎的線上廣告模式,相比于頁面上的大幅banners圖我更喜歡這種新穎的模式,我們正在嘗試為用戶添加有價值的信息如產(chǎn)品價格比較、添加鏈接讓用戶可直接購買想要的產(chǎn)品。
開發(fā)環(huán)境:
大部分前端開發(fā)是用PHP編寫的,當(dāng)公司需要快速、靈活開發(fā)項目時,選擇PHP是個不錯的選擇。但是隨著公司既定產(chǎn)品的知名度不斷提高以及搜索的高并發(fā)訪量,PHP正日益成為我們發(fā)展的一個瓶頸。
存在問題:
使用Apache多選程模塊(MPM),apache會阻礙大量的搜索請求,當(dāng)出現(xiàn)高并發(fā)訪量時,頁面無法響應(yīng)。
這里有一個快速的方法可提高服務(wù)器的吞吐量增加工作進(jìn)程,然而當(dāng)RAM快要耗盡時,將會受到限制。每個進(jìn)程都有獨(dú)立的RAM數(shù)據(jù)塊,增長和搜索取決于PHP在哪個點(diǎn)上,當(dāng)沒有足夠的空間釋放時,你必須將OOMing關(guān)閉(它可以迅速的將吞吐量降至為0)。
最可行的擴(kuò)大規(guī)模的方法就是把項目管理模塊從Apache prefork MPM換成更出色、更快速的Apache worker MPM。通過改變多進(jìn)程大大增加了服務(wù)器請求數(shù),唯一的缺陷只是為了這個工作而工作,PHP必須能夠保證處理多個并發(fā)線程不會產(chǎn)生死機(jī),然而事實(shí)并非如此。PHP的核心是多線程,因此我門認(rèn)為它可能是因為某些驅(qū)動或者延長使用而導(dǎo)致失敗,然而無論出于什么原因,PHP不在符合我們的需求。
為此,引發(fā)了我們會選擇哪種語言進(jìn)行開發(fā)而爭論不休,每個人都在推崇他們喜歡的語言,有人贊成、有人反對。很明顯,眾口難調(diào),沒有一個衡量標(biāo)準(zhǔn)是很難選出來的,因此,我們決定用各個語言來測試一個系統(tǒng),看它們的執(zhí)行情況在做定奪。
參賽語言:
基本規(guī)則是,如果你想要某語言進(jìn)行測試必須愿意提供執(zhí)行API請求數(shù),最后推選出:
- Node.js:流行程度依然高漲,它的目標(biāo)是幫助程序員構(gòu)建高度可伸縮的應(yīng)用程序,編寫能夠處理數(shù)萬條同時連接到一個(只有一個)物理機(jī)的連接代碼。?
- Scala (w/ Tomcat):我非常熱愛JVM,起初我也推薦過該語言,但因為它過于冗長而被否決,令人興奮的是,這次Scala得到了大家的認(rèn)可。
- Python (w/ Tornado):我們已經(jīng)有Python方面的經(jīng)驗。
- Go (golang):我對這門語言感興趣,而我的同伴們卻認(rèn)為這門語言不好,建議使用Java。我還建議使用C#和.NET/mono,但因為不公平性,最后都被否定了。
挑戰(zhàn):
我們選擇了一個非常簡單的日志API系統(tǒng),所做的這些是為了從JSON請求數(shù)中抓取詳細(xì)信息,采用MD5,用于確保信息傳輸完整一致。(主流編程語言普遍都用MD5實(shí)現(xiàn)。將數(shù)據(jù)(如漢字)運(yùn)算為另一固定長度值,是雜湊算法的基礎(chǔ)原理)每個執(zhí)行階段都將使用Apache Benchmark(Apache附帶的一個小工具,專門用于HTTP Server的benchmark testing,可以同時模擬多個并發(fā)請求)來評估各種語言開發(fā)并發(fā)水平速度。
當(dāng)Node.js和Python Tornado以單一線程運(yùn)行時,使用Nginx(一個高性能的HTTP和反向代理服務(wù)器,也是一個IMAP/POP3/SMTP代理服務(wù)器 )來查看這兩個實(shí)例。
針對Scala我甚至特意編寫一份old-school Servlet(一種服務(wù)器端的Java應(yīng)用程序,具有獨(dú)立于平臺和協(xié)議的特性,可以生成動態(tài)的Web頁面,它擔(dān)當(dāng)客戶請求Web瀏覽器或其他HTTP客戶程序與服務(wù)器響應(yīng)的中間層)在基于tomcat下運(yùn)行。
采用AWS(Asp Web Server是一款基于netbox開發(fā)的asp web服務(wù)器,其個小功能強(qiáng)大,基本上能夠取代IIS成為廣大Asp程序員和網(wǎng)站開發(fā)者的利器)直接在服務(wù)器上執(zhí)行基準(zhǔn),以消除任何一個網(wǎng)絡(luò)瓶頸。
通過mongo刪除每次測試數(shù)據(jù),每次測試至少執(zhí)行3次,選取平均值,以確保有足夠的“熱身”時間和消除任何異常結(jié)果。
通過在多個并發(fā)值下進(jìn)行測試((10,50,100,200,500,1000),一起來看下在高負(fù)荷的情況下,性能發(fā)生了什么變化。
測試結(jié)果:
每秒請求數(shù):這個測試給了我們一個實(shí)現(xiàn)純速度的想法,最明顯的一點(diǎn)(越高越好)。
有一點(diǎn)值得我很欣慰,Scala獨(dú)占鰲頭。PHP(正如預(yù)期所想的那樣)受多線程的限制,香消玉損。另一個讓我震撼的是Go語言當(dāng)并發(fā)訪量不斷增加時,它以平緩的速度迅速下滑,最終也Over了。如期所料,兩個單線程non-blocking solutions(node和 python)性能差不多,python要比Node稍微好點(diǎn)。
響應(yīng)時間:
盡管每秒請求數(shù)進(jìn)程的吞吐量呈現(xiàn)出一個好的跡象,但是同樣重要的是在高負(fù)荷的情況下,表現(xiàn)很糟糕。由圖表得知,在一段時間內(nèi)完成的請求數(shù)比例,越低越好。
100并發(fā)請求數(shù):
在這里,我們看到Scala需要的時間最少,而其他幾門語言之間沒有太大區(qū)別。
200并發(fā)請求數(shù):
圖中,我們看到有趣的現(xiàn)象,以9秒速度來計算請求數(shù),Go和PHP都有受到影響,花費(fèi)的時間比較多。
500并發(fā)請求數(shù):
在500并發(fā)需求時,使用9—14秒完成請求。PHP無法響應(yīng),Go語言花費(fèi)時間較多,占最高值。
1000并發(fā)需求數(shù):
當(dāng)我們遇到數(shù)以千計的請求數(shù)時, Go語言O(shè)ver了,通過測試,根據(jù)apache規(guī)則要求超過50%的失敗率就算出局。如圖所示Node和Python依然存在,可以清楚的看到其性能特性。但是Python比Node要更好一點(diǎn)。但在第一幅圖上,Python表現(xiàn)的要稍微差一點(diǎn)。
通過測試,能清楚的分辨出各語言的性能表現(xiàn),以上測試的這些數(shù)據(jù)是我們APIs中的一部分,因此對我們來說非常重要。
Scala表現(xiàn)的很好,幾乎很完美,我把它歸功于在連接池的Mongo數(shù)據(jù)庫中單獨(dú)接入MessageDigests和快速進(jìn)行JSON分析程序。我不確定Go語言到底是怎么了,也許是我使用的Mongo驅(qū)動的問題,但無論是什么原因,看到它這么差的表現(xiàn)真的讓我很難過。
最后決定:
最終,我們經(jīng)過討論決定選擇Python!Scala如此之快,我們?yōu)槭裁床贿x擇Scala而另選Python呢?原因如下:
Scala這門語言很難,我需要很久才能將簡單的API整合在一起,才能進(jìn)行工作,python閱讀起來就像haiku,而Scala閱讀就像蛇類游戲一樣。
線性編程是很痛苦的,對Scala來說,很容易也很安全,簡單的單線程non-blocking解決方案總是很吸引人,但我們應(yīng)該不斷的去嘗試挑戰(zhàn)。
整個團(tuán)隊在Python上有著豐富的經(jīng)驗,如果讓大家去接受一門新的語言,尤其像Scala這樣的既昂貴又費(fèi)時間。
此前網(wǎng)絡(luò)速度、數(shù)據(jù)庫查詢等API成為我們發(fā)展的一個瓶頸,而今,我們已經(jīng)找到正確的解決方案——Python,我們只需等待執(zhí)行和發(fā)布,希望這個決定是正確的。
英文出自:skimlinks
總結(jié)
以上是生活随笔為你收集整理的编程语言API性能大比拼的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Marshal在C#中的应用(void
- 下一篇: C#中使用指针转换数据类型[C#/uns