首先说下为何须要灰度环境。随着业务的复杂度以及技术复杂度的上升,致使在测试环境可能有些问题没法全面复现,以及复杂度上升可能带来的某些配置的不一样步等等缘由,会致使测试环境看起来是没有问题的需求,到了线上反而出现了的问题,为了尽早发现这些问题,以及下降这些问题带来的影响,就须要一个和线上环境几乎同样的环境来作最后的质量把控。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 前端能够作的更多,让前端发挥更大的价值。