網易智慧企業 Node.js 實踐(3)| 灰度環境和應用監控

網易雲信發表於2020-07-09

灰度環境

首先說下為什麼需要灰度環境。隨著業務的複雜度以及技術複雜度的上升,導致在測試環境可能有些問題無法全面復現,以及複雜度上升可能帶來的某些配置的不同步等等原因,會導致測試環境看起來是沒有問題的需求,到了線上反而出現了的問題,為了儘早發現這些問題,以及降低這些問題帶來的影響,就需要一個和線上環境幾乎一樣的環境來做最後的質量把控。

為什麼不是預發環境?其實我之前的專案中很多都是使用預發環境的,而且業界使用預發環境的企業也不在少數,那我們為什麼使用實現難度更大的灰度環境呢?肯定是有好處的啊!第一,從開發的角度,使用預發環境要麼使用預發域名,要麼使用預發機器 IP 繫結,操作起來比較麻煩,對非開發同學不友好。第二,灰度環境可以讓真正的使用者進行使用,也可以作為A/B Test 使用。總結下就是預發環境能做的灰度環境基本都能做,預發環境不能做的灰度環境也能做。所以我們使用灰度環境。

既然要用灰度環境,首先要確定的是通過什麼方式來區分使用者進入灰度或正式環境。網易互客作為一個 toB 的產品,當然希望是同一個公司的所有員工能夠得到同樣的使用體驗和功能。所以我們通過企業 ID 來控制使用者進入灰度或正式環境。 enter image description here 【示意圖】

確定方案之後就是技術實現了,我們之前的閘道器只能通過請求的 path 來區分請求,來控制流量轉發到 Java 或 Node 應用。現在我們需要閘道器能夠區分請求中的企業 ID,所以需要對閘道器進行升級,於是我們使用新的技術方案 Eureka(Netflix開發的服務發現框架),這裡不對 Eureka 做過多介紹,主要說下 Node 端要實現的 Eureka Client,用來完成服務註冊及維持。

npm 中已經有了 eureka-node-client 來實現 Node 端的服務註冊功能,但是要結合 Egg.js,以及平滑釋出的理念,還是需要進一步的開發,以實現一個更完善的工具,所以我們實現了 pp-eureka 這個 Egg.js 外掛。

考慮到 Egg.js 的多程式模型,為了防止一臺機器多次註冊,我們通過擴充套件 agent 來實現這個外掛的功能。主要程式碼如下:

```javascript const Eureka = require('eureka-node-client');

module.exports = agent => { const eureka_client = new Eureka(agent.config.eureka);

eureka_client.start(function (error) { agent.logger.info(error || '啟動成功!'); }); } ```

如果僅僅是這樣倒也能實現灰度的需求,但是損失了上文提到的平滑釋出,所以又增加了一個 middleware 來監聽釋出系統的上下線請求,然後通過 app.messenger.sendToAgent(OFFLINE, ''); 來通知 agent ,agent 程式碼升級後如下:

```javascript const Eureka = require('eureka-node-client');

module.exports = agent => { const eureka_client = new Eureka(agent.config.eureka);

eureka_client.start(function (error) { agent.logger.info(error || '啟動成功!'); });

agent.messenger.on(OFFLINE, data => { eureka_client.stop(); }); } ```

Agent 收到下線通知後會讓 Eureka 停止註冊服務的心跳,這樣 Eureka 註冊中心就會把這臺 Node 機器踢掉,流量就不會轉發進來,以免在釋出過程中導致請求失敗。外掛開發好之後怎麼用呢?首先是在 config 目錄下增加 config.gray.js 灰度環境配置檔案,裡面新增 pp-eureka 的配置,如下:

json eureka: { eureka: { serviceUrls: { default: [ 'url' ] } }, instance: { app: 'huke', port: { '$': 7001, '@enabled': true }, metadata: { ysf_app: 'huke', ysf_env: 'gray' } } }

同時線上環境也增加對應的配置,只是 eureka.instance.metadata.ysf_env = 'prod' ,通過這個配置來區分是灰度環境還是線上環境。這樣就完成灰度環境工程相關的部分,剩下就是把所有的請求都預設帶上當前企業的 ID 就完成了。

自此應用釋出相關的問題都已基本解決,剩下的就是要隨時瞭解自己的應用的執行狀態了。

應用監控

enter image description here

應用上線之後,為了瞭解應用的執行狀態、服務是否穩定、有沒有潛在問題,我們需要應用監控,有了應用監控以後能幫我們解決以下問題:

  1. 能夠讓業務流轉呼叫鏈可追蹤,能夠知道一個請求在哪裡出了問題,方便解決
  2. 能夠了解應用的系統指標,比如:Load、CPU、記憶體、磁碟、網路、TCP 等
  3. 能夠在應用狀態異常的時候及時傳送通知給開發者,把影響降到最小

關於網易內部的工具我就不多介紹了,主要介紹下可以使用的第三方平臺或工具。

首先說下 Sentry,它是一個實時事件日誌記錄和聚合平臺。我們之前使用它來做前端程式碼的錯誤監控以及關鍵資料的統計。因為它也能支援 Node 端,所以我們就順便接入進來了,同時實現了 pp-sentry Egg.js 外掛。使用的時候只需要在 config 中配置 sentry project 的 dsn 即可捕獲 Node 中程式碼錯誤。

還有阿里開源的Pandora.js,是一個 Node.js 應用監控管理器。它整合了多種型別的能力諸如:監控、鏈路追蹤、除錯、程式管理等等。

另外就是阿里雲的 Node.js 效能平臺,如果使用 Egg.js 框架的話,接入非常方便,使用官方提供的 egg-alinode,參考 Egg 整合部署部署 runtime 與 agenthub使用者指南_Node.js 效能平臺-阿里雲 這個文件即可,功能全面,關鍵是免費。如果還有對日誌更高的要求,可以使用阿里雲的日誌服務。

利用好上面的工具能對解決應用中出現的問題提供很大的幫助,另外在程式碼需要的地方打上日誌也是非常必要的,Egg.js 提供了非常完善的日誌功能,使用好它對了解應用的執行狀態以及排查問題都有很好的幫助。

總結

至此我要分享的關於智慧企業 Node.js 接入實踐已經結束,但是要開發好 Node 應用要考慮的還有很多。首先在開發思路上要和寫前端程式碼有個區分,要具備服務端開發的思考能力,對效能、穩定、健壯等的考慮要更多。另外要養成良好的打日誌習慣,這個非常重要。還有單元測試也是非常重要的,寫單元測試是服務端開發的基本要求。Node 端開發對運維能力也有一定的要求,不像前端程式碼,發上 CDN 之後基本就不需要關注了,但是做 Node 開發,程式碼上線之後也要時刻關注應用的狀態,以及會不會有報錯等,要具備快速定位、解決問題的能力,將可能出現的問題導致的損失降到最小。Node的接入整體上對開發效率的提升還是很顯著的,而且通過 Node 前端可以做的更多,讓前端發揮更大的價值。

相關文章