標籤:
蟄伏了很久,一直忙著幾個大項目。
幾個項目內容彼此差異很大,但都對支付、結算部分具有很高的精度要求,其中一個,具有大量的即時同步的資料。
大量到什麼程度呢?大約平均每秒擷取30條更新資料,這30條資料,實際觸發200條左右的資料比較和更新。去年大約9、10月份在為這個項目做準備的階段,我主觀上覺得PHP+MySQL很難勝任此任務,一度對.net、Java、Scala、golang,以及不同的資料庫,包括pgsql、sqlserver、mongodb都做了很多的調研與測試準備,後來一度選擇了Scala的方案。不過真的動手的時候,靜態語言的特性,真的讓我有很多不適應的地方,尤其是servlet容器,每次更新都要reload——這方面可能我真的被動態語言寵壞了。
第一階段編寫了部分重構和改進的代碼,令我決定放棄了選擇靜態語言去改造整個項目的方案。因為線上部分的系統業務實在太龐大了,而且很多商務邏輯,早前開發的PHP的版本,已經封裝得是非常健壯和完善,唯一能說服我去改造的,只有語言之間的效能差異。經過了一些比對,尤其是servlet實際的部署更新方面與現有PHP的對比,我做了一個特性列表的比對,並且每個特性都實際測試了servlet模式和PHP模式的比較,最終決定放棄選擇靜態語言改造整個項目的方案。
在Web系統的構建上,PHP支援動態更新是一個非常重要的特性,這也許已經成為他區別現有所有的Web開發語言中,一個最大的優勢了。Ruby、node.js、golang、Java,最多隻能做到模板動態更新,發布模式下,類庫檔案屬於調用時才載入到位的機制、永不釋放、或編譯成二進位檔案、預先即載入。
放棄了重構的方案,就要轉換思路了。原來的設想,是以Web作為系統的核心,原本改造的一個目的是,讓Web具有更加主動的執行一些操作和任務的功能,讓他能主動的去發起和執行一些任務。但實際的情況下,第一階段已經用PHP開發的代碼,我並不想破壞或者重構——因為在商務邏輯的層面,他並沒有問題。我完全可以把已經開發的Web視作一個WebService的點,剩下的,就是部署多個的Service點,將外部的資料介面,和WebService對接,並由WebService發起對這些Service的管理與監控。
大概的情形就如下面的拓撲圖:
每個外部的Service,只包含實現自己本身所要執行操作的最小的程式邏輯,核心商務邏輯交給WebService。並且Service之間並不通訊,彼此不需要知道彼此的存在,必須做到,隨意添加、隨意部署、隨時更新。他們就像是章魚的觸手,但有著各自更明確具體的功用和任務,但是他們不具有思考和判斷的能力,他們只是準確無誤(尤其不能時誤)的去執行不同的任務。
確定這個思路的時候,我並不準確的知道他的可行性,這個環境最核心的環節是WebService的容納能力,這一點也是我最無法確定的。不過隨著時間的推進,我已經沒有更多的選擇了。外部Service部分,我選擇了node.js,因為npm的豐富度,以及我本身對js的熟悉度。
Service開發的難度不高,很快就封裝了一個任務調度器和WebSocket Server。經過長期密集的監控,任務調度器的時間延遲,在可接受的範圍內,這一點我之前測試node.js的時候就知道了,單核條件下,高密集的壓力下,他會毫不思考的直接將CPU可用的計算能力用到滿載為止。
很快的,新的Service部署上線了,校準資料,WebService商務邏輯的調整,這些自不必說了。我一直所擔心的,WebService上可能發生的問題,居然一點都沒發生——尤其是在測試伺服器上,那隻是一台最最低廉的伺服器(即棄即用,只要他系統一崩潰,我就直接從鏡像重裝),單機運行,居然絲毫不亂。PHP+MySQL的耐操能力,真的超乎我的想象,當然,因為事前對起容納能力和計算能力的擔心,針對商務邏輯的特點,我也設計了多層的緩衝解決方案,所以這裡還得加上Memcache。
但是這些用node.js寫的Service,其健壯度和穩定性真的很低,經常無緣由的停止服務,而且記憶體的調度和釋放方面,也不盡如人意。當然了,本身在開發Service的時候,我並沒有刻意的去最佳化(基本上可以用粗獷來形容),畢竟有很多事情還沒得到實踐驗證,沒必要過度的耗神費腦子。在我預算中,這部分遲早是要重構的——本身的邏輯也並複雜,最終的方案也未必會選擇node.js。
結合最早的調研和測試,對Service的重構,現在的關注點落在了jvm和golang上。jvm經過了這麼多年的風霜洗禮,他的記憶體管理已經比較完善,而且對於其調優的經驗與分享,google一搜一大把,可參照的依據也非常之多(再到Google趨勢上看看,這世間所有的開發語言裡面,Java也是遙遙領先),而且之前我已經開了一些可用的代碼。golang絕對是一個殺手級的語言,我相信這個語言絕對擁有比jvm更高的可調優的運行效能,不過看到他的指標符號,我真的有些心有餘悸,而且他的變數是可汙染的,這個有些麻煩啊。
PHP+MySQL真是皮糙耐操的組合