首先說下爲何須要灰度環境。隨着業務的複雜度以及技術複雜度的上升,致使在測試環境可能有些問題沒法全面復現,以及複雜度上升可能帶來的某些配置的不一樣步等等緣由,會致使測試環境看起來是沒有問題的需求,到了線上反而出現了的問題,爲了儘早發現這些問題,以及下降這些問題帶來的影響,就須要一個和線上環境幾乎同樣的環境來作最後的質量把控。javascript
爲何不是預發環境?其實我以前的項目中不少都是使用預發環境的,並且業界使用預發環境的企業也不在少數,那咱們爲何使用實現難度更大的灰度環境呢?確定是有好處的啊!第一,從開發的角度,使用預發環境要麼使用預發域名,要麼使用預發機器IP 綁定,操做起來比較麻煩,對非開發同窗不友好。第二,灰度環境可讓真正的用戶進行使用,也能夠做爲A/B Test 使用。總結下就是預發環境能作的灰度環境基本都能作,預發環境不能作的灰度環境也能作。因此咱們使用灰度環境。html
既然要用灰度環境,首先要肯定的是經過什麼方式來區分用戶進入灰度或正式環境。網易互客做爲一個toB 的產品,固然但願是同一個公司的全部員工可以獲得一樣的使用體驗和功能。因此咱們經過企業 ID 來控制用戶進入灰度或正式環境。前端
【示意圖】 java
肯定方案以後就是技術實現了,咱們以前的網關只能經過請求的path 來區分請求,來控制流量轉發到 Java 或 Node 應用。如今咱們須要網關可以區分請求中的企業 ID,因此須要對網關進行升級,因而咱們使用新的技術方案 Eureka(Netflix開發的服務發現框架),這裏不對 Eureka 作過多介紹,主要說下 Node 端要實現的 **Eureka Client**,用來完成服務註冊及維持。node
npm 中已經有了 eureka-node-client 來實現 Node 端的服務註冊功能,可是要結合 Egg.js,以及平滑發佈的理念,仍是須要進一步的開發,以實現一個更完善的工具,因此咱們實現了 `pp-eureka` 這個 Egg.js 插件。npm
考慮到Egg.js 的多進程模型,爲了防止一臺機器屢次註冊,咱們經過擴展 agent 來實現這個插件的功能。主要代碼以下:json
```javascript網絡
const Eureka = require('eureka-node-client');app
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 就完成了。
自此應用發佈相關的問題都已基本解決,剩下的就是要隨時瞭解本身的應用的運行狀態了。
應用上線以後,爲了瞭解應用的運行狀態、服務是否穩定、有沒有潛在問題,咱們須要應用監控,有了應用監控之後能幫咱們解決如下問題:
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 性能平臺-阿里雲](https://help.aliyun.com/document_detail/60907.html?spm=a2c4g.11186623.6.555.41d676bfwLNpaH) 這個文檔便可,功能全面,關鍵是免費。若是還有對日誌更高的要求,可使用阿里雲的日誌服務。
利用好上面的工具能對解決應用中出現的問題提供很大的幫助,另外在代碼須要的地方打上日誌也是很是必要的,Egg.js 提供了很是完善的日誌功能,使用好它對了解應用的運行狀態以及排查問題都有很好的幫助。
至此我要分享的關於智慧企業Node.js 接入實踐已經結束,可是要開發好 Node 應用要考慮的還有不少。首先在開發思路上要和寫前端代碼有個區分,要具有服務端開發的思考能力,對性能、穩定、健壯等的考慮要更多。另外要養成良好的打日誌習慣,這個很是重要。還有單元測試也是很是重要的,寫單元測試是服務端開發的基本要求。Node 端開發對運維能力也有必定的要求,不像前端代碼,發上 CDN 以後基本就不須要關注了,可是作 Node 開發,代碼上線以後也要時刻關注應用的狀態,以及會不會有報錯等,要具有快速定位、解決問題的能力,將可能出現的問題致使的損失降到最小。Node的接入總體上對開發效率的提高仍是很顯著的,並且經過 Node 前端能夠作的更多,讓前端發揮更大的價值。