健康检查

前文提到我们通过网关把流量转发到 Node 应用,那网关是如何确定 Node 应用的可用性呢?

如果 Node 应用在发布的过程中也把流量转发过来,就会导致请求失败,所以我们的网关会对 Node 应用做一个健康检查,要首先确定 Node 应用是健康的,也就是可以对外服务的。具体来说就是网关会每隔30秒调一下 Node 应用的健康检查的 HTTP 接口,如果接口返回的 code 是200,那就表示 Node 应用是可用的,用户的请求在下次检查之前都会转发过来,如果返回其他 code,表示应用不可用,请求就不会转发过来。过30秒再重复这个过程。

【示意图】

这个方案实现起来非常简单,只要再 Node 添加个能正常请求的 HTTP 接口即可,比如我们用的接口 `/health/check`它的 controller 内就 `this.ctx.body = 'OK'`就可以了。如果 Node 应用正常启动,可以接受用户请求,那么这个接口返回 code 就会是200,如果这个接口不能正常访问,返回的code不是200,那么也意味着整个应用是不能访问的。

那上面这个方案就没有问题了吗?肯定是有的,比如我们在发布时候,首先要让 Node 应用下线,如果恰好 Node 应用刚被健康检查通过后就下线了,那么就会导致后面30秒内转发到 Node 应用的流量访问失败,所以我们有了升级方案-平滑发布。

平滑发布

平滑发布就要跟发布系统进行配合了,就是我们在发布应用的时候发布系统会自动调用 Node 应用的下线接口,发布完成之后会调用 Node 应用的上线接口,这样就可以通过一个全局变量控制应用的状态,而这个状态是和应用的真实状态没有关系的。调用下线接口后,应用状态置为下线,然后等待一段时间才真正让应用下线,所以如果这时有流量进来应用依然可以正常服务。

【示意图】

逻辑很简单,但是实现的时候要考虑到 Egg.js 的多进程模型,Egg.js  一般根据服务器的 CPU 核数来定启动相应数量的 Worker 进程,这样就可以完美利用多核资源。每个进程里都跑的是同一份源代码,这些进程同时监听一个端口,所以当发布系统调用下线接口时,只有其中一个进程会收到请求,如果只是把收到请求的这个进程的全局变量置为下线的话,其它的进程在收到健康检查的时候依然返回的是在线状态,这样就不对了,所以要使用进程间通信,告诉所有进程下线。

基于这些分析我们实现了 Egg.js 插件 `pp-ndp` ,另外由于 Egg.js 插件中不允许有路由,所以我们通过中间件的形式实现,主要代码如下:

```

const { request } = ctx;

const { path, hostname } = request;

if (path === online) {

app.messenger.sendToApp(ONLINE, '');

ctx.body = 'NDP: Nodejs Is Online';

} else if (path === offline) {

app.messenger.sendToApp(OFFLINE, '');

ctx.body = 'NDP: Nodejs Is Offline';

} else if (path === check) {

ctx.body = 'NDP: Nodejs Start Success';

} else if (path === status) {

if (app[ISONLINE]) {

ctx.body = 'NDP: Nodejs Is Online';

} else {

ctx.status = 500;

}

} else {

await next();

}

```

当然这个方案的前提是有多台 Node 服务机器,并按分组进行发布。如果只有一台机器就没必要这么麻烦了,反正发布一定会导致停服。

插件 `pp-ndp` 为了满足不同业务需求,online、offline、check、status 这四个 URL 是支持自定义配置的。

这个方案不仅解决了我们平滑发布的问题,让发布不再那么恐怖,而且还可以利用这个方案让应用上线后能够更好的服务,比如:可以在应用获取配置之后再把应用置为上线状态,或者可以在应用成功注册或连接某服务之后再把应用置为上线状态。让应用保证最健康的状态对外服务。

代码上 CDN 和 代码发现

看到 CDN 可能会奇怪, Node 应用为什么要 CDN,其实是因为我们为了方便使用同构渲染,而把前端代码和 Node 代码放在了一个应用里面,虽然这样解决了服务端渲染代码访问问题,但是客户端代码还是走 CDN 比较合理。关于 webpack 使用 CDN 网上有很多文章可以参考,我主要介绍下如何发现前端代码的,包括代码上 CDN 和模版中插入前端代码 URL。

主要是使用 `webpack-manifest-plugin` 这个 webpack 插件,它会生成一个文件,比如我们用的 `manifest.json`,里面包括前端代码资源名称和对应路径,类似:

```

{

"vendor.js": "/static/f5e0281b/js/vendor.chunk.js",

"vendor.js.map": "/static/f5e0281b/js/vendor.chunk.js.map",

"Page.css": "/static/f2065164/css/Page.chunk.css",

"Page.js": "/static/f2065164/js/Page.chunk.js",

"Page.js.map": "/static/f2065164/js/Page.chunk.js.map",

}

```

只需要把这个文件内列的文件上传到 CDN 即可,不需自己手动去打包目录一个一个找。在上传 CDN 的时候给每个文件保持同样路径。使用我们实现的工具 `pp-cdn` 在发布过程中的代码编译完成之后进行上传。在 Node 模版中引用代码时,使用我们开发的 Egg.js 插件 `pp-just`,使用方式:

```html

<script src='{{ctx.just.use("Page.js")}}'></script>

```

插件内部也是读取 `manifest.json` 文件,输出加上 CDN 域名之后的 URL,比如上面的代码就转变为:

```html

<script src='https://qiyukf.nosdn.127.net/huke/static/f2065164/js/Page.chunk.js'></script>

```

其实之所以这么做,是为了利用前端代码多版本带来的好处,我们是使用文件 hash 作为文件路径的一部分作为多版本控制的,这样每次发布后编译后会把新生成的文件路径写入 `manifest.json`,然后通过上面讲的方式就可以获取到最新版本的代码。

当然目前 Node 和 前端代码在一起是不合理的,可能会导致不必要的发布,后续应该会完全分离,但是使用`manifest.json`也可以作为我们后续代码分离后的方案之一。

总结

技术方案的选择一般要结合团队已有的技术方案和业务需求,本文介绍的平滑发布方案在我们业务前期,确实解决了我们的发布问题,让发布变得更安全。

但是随着业务发展我们需要灰度环境,来更好的确保应用的健康状态,提前发现应用中的问题。另外我们还需要知道我们的应用的运行状态,所以在下一讲内容中,我们会分享关于灰度发布和应用监控相关的内容。

网易智慧企业 Node.js 实践(2)| 平滑发布和前端代码相关推荐

  1. 网易智慧企业 Node.js 实践(3)| 灰度环境和应用监控

    灰度环境 首先说下为什么需要灰度环境.随着业务的复杂度以及技术复杂度的上升,导致在测试环境可能有些问题无法全面复现,以及复杂度上升可能带来的某些配置的不同步等等原因,会导致测试环境看起来是没有问题的需 ...

  2. 网易智慧企业Node.js实践(1) | Node应用架构设计和React同构

    导读: 近期网易智慧企业在 Node.js(以下简称 Node) 的接入上已输出阶段性成果,特推出此系列文章,希望能与大家分享部分接入过程的方案,从而提供帮助.系列主要包括以下内容. 1. Node ...

  3. 网易智慧企业亮相TOP 100 Summit,以创新和匠心探索行业前沿

    11月14-17日,网易智慧企业部旗下业务品牌网易云信.网易七鱼受邀参加由麦思博主办的第八届TOP 100全球软件案例研究峰会(TOP 100 Summit).本次峰会围绕 "数字化转型与指 ...

  4. Node.js 框架设计及企业 Node.js 基础建设相关讨论

    大家好,我是若川.19年我写的 lodash源码 文章投稿到海镜大神知乎专栏竟然通过了,后来20年海镜大神还star了我的博客,同时还转发了我的微博.时间真快啊.今天分享这篇Node.js的讨论. 2 ...

  5. 「跨域」利用node.js实践前端各种跨域方式(上)

    前言 常言道,"读万卷书,不如行万里路".技术的学习也是如此,唯有实践才能更清楚的明白原理和加深印象,因此本文会利用node.js对前端的各种跨域方式进行实践,强烈建议一步一步跟着 ...

  6. 网易智慧企业2020年度见面会4大亮点抢先看!

    2020开年遭遇了新冠疫情"黑天鹅",在这个过程中,有的企业实现逆势增长,也有的企业业绩遭遇了断崖式下跌甚至被迫停业. "企业如何危中抢机?" "如何 ...

  7. 经信局推荐 | 网易智慧企业多产品入选《杭州市支持企业远程办公助力复工防疫产品和服务目录》!...

    为落实杭州市疫情防控指挥部<关于数字赋能线上审批服务远程办公的通告>精神,全力支持广大企业和群众实现网上办事.远程办公,助力复工复产和疫情防控,杭州市经信局征集和筛选了一批"支持 ...

  8. 3年营收翻8倍,网易智慧企业业务多品牌战略升级

    5月8日,网易旗下知名TO B产品网易云信和网易七鱼联合宣布一项战略升级,整合内部优质资源,成立网易智慧企业部,并推出面向企业客户的新产品网易云企课.当日在北京举行的战略发布会上,网易智慧企业部总经理 ...

  9. Pomelo:网易开源基于 Node.js 的游戏服务端框架

    Pomelo 是基于 Node.js 的高性能.分布式游戏服务器框架.它包括基础的开发框架和相关的扩展组件(库和工具包),可以帮助你省去游戏开发枯燥中的重复劳动和底层逻辑的开发.Pomelo 不但适用 ...

最新文章

  1. Mac OS Mountain Lion 下的Wireshark
  2. mysql跨服务器查询语句_MySQL 跨服务器访问之-FEDERATED引擎
  3. 使用Banner实现轮播展示
  4. 摘抄自知乎的redis相关
  5. Rails不用localhost访问的时候很慢
  6. linux小红帽系统能用微信,小红帽腾讯QQ微信登录版-小红帽腾讯版v1.0.3 安卓版-腾牛安卓网...
  7. java map 面试题_Java 面试系列:集合详解之 Map + 面试题
  8. java 封装dll_java调用C#封装的DLL文件
  9. mysql的数据层基类_C# 基于MySQL的数据层基类(MySQLHelper)
  10. jsp mysql论坛_体育论坛ssm,mysql)
  11. python入门20 导入模块(引包)
  12. Android ContentProvider简单总结
  13. hackrf+portapack 组装上手体验记录
  14. android与相机连接电脑,使用Android手机或平板电脑控制dSLR相机
  15. outlook服务器拒绝访问文件夹,无法打开共享日历文件夹 - Outlook | Microsoft Docs
  16. 【职场攻略】送礼给老板有讲究
  17. MySQL之Xtrabackup备份恢复数据库
  18. 权值衰减和L2正则化傻傻分不清楚?
  19. MySQL 是怎么加行级锁的?为什么一会是 next-key 锁,一会是间隙锁,一会又是记录锁?
  20. PPT设计的四大基本原则(亲密性)

热门文章

  1. 串口调试助手-打开报错
  2. BootStrap学习(6)_模态框
  3. OEM 按钮乱码解决办法
  4. 如何让采集的数据比原创还要原创!
  5. 设计一个算法找一条从迷宫入口到出口的最短路径。_我花了一夜用数据结构给女朋友写个H5走迷宫游戏...
  6. GraphPad Prism9 将正态分布拟合至频率分布
  7. 重磅!全网最全13010本SCI2020最新影响因子下载!CA+四大神刊!预警期刊最新影响因子一览!
  8. 医学科研如何快速掌握R语言?
  9. MATLAB | Matlab 2020a/202b/2018a/2019b安装教程及资源及matlab基本案例(图像练手教程)
  10. wd2003计算机考试,2015计算机一级MsOffice练习:Word2003