淘宝开发者社区上云记

前端开发

在 Serverless 理念如火如荼地被讨论的今天,如果你要上线一个全新的 Node.js 应用到公有云,将会是怎样的一种模式?笔者近期就上线了一个社区类应用,技术选型上采用了开源软件 NodeBB,由于是非标应用及安全性相关的原因,被迫上云。

在此过程中笔者经历了从零到一的上云之路,对云上的相关产品和开发链路有了一次较为完整的体验。其过程之繁琐,需自定义的环节之多,让笔者对 Serverless 相关的变革及云产品的整合有了更多的期待。

但是在当下,起码是最近半年,若是应用要上云恐怕绝大多数开发者还是得走笔者曾走过的这条路。本文即详尽地记录该过程,作为一种记录亦或者是操作教程,分享给有需要的同学。

Aone 内 Node.js 应用的构建和部署

在上云之前,让我们简单地回顾一下在 Aone 环境 Node.js 应用是如何被构建和部署的。以 Midway 应用为例:

应用上线流程:

构建环节:

部署环节:

通过 nodejsctl pubstart 启动应用。

ECS:云服务器

开始上云,最先最容易想到的方式就是购买 ECS 主机然后部署应用。此时应用的架构是这样:

以下是通过 ECS 部署 NodeBB 的指引教程。

创建 ECS 实例

首先我们需要一个 ECS 实例。访问 ECS 控制台 点击“创建实例”。

如果没有开通过 ECS 服务,则需要先开通服务。 阿里云文档中已经有关于 ECS 的详细介绍,这里不再解释。

以下是笔者的配置:

创建实例完成后,默认会获得一个固定公网 IP ,可以使用该 IP 通过 SSH(22端口)或浏览器(80端口)访问该 ECS 实例:

创建 MongoDB 实例

其次,NodeBB 支持 Redis 和 MongoDB 作为数据存储,笔者这里选择了 MongoDB,因此需要创建一个 MongoDB 实例。

访问 MongoDB 控制台 点击“创建实例”:

如果没有开通过 MongoDB 服务,则需要先开通服务。 阿里云文档中已经有关于 MongoDB 的详细介绍,这里不再解释。

配置数据库

部署应用

安装必要的软件环境并启动 NodeBB。

启用 Nginx

初始化 NodeBB

Nginx 配置和重启

域名映射及 HTTPS 配置

EDAS:企业级分布式应用服务

部署在 ECS 实例后应用仅仅处于「可用」的状态,还面临着如下问题和隐患:

  1. 迭代能力不足,无法优雅终止和快速启动应用 —— 每次重新部署都将会造成应用不可用;
  2. 健壮性不足,物理或系统出现的问题将可能导致应用不可用;
  3. 并发性不足,虽然在网站前期不会是瓶颈,但单机的模式扩容有其上限。

很容易就能想到使用容器化技术和集群模式。

这就可以应用 Docker 和 Kubernetes(以下简称 k8s),阿里云提供了容器服务 Kubernetes 版。此时应用的架构是这样:

参考:

以下是通过 EDAS 部署 NodeBB 的指引教程。

创建 Kubernetes 集群

首先我们需要一个 k8s 集群用于部署我们的应用。访问创建 Kubernetes 集群

参考:

创建 Docker 镜像

紧接着,我们需要构建出应用的 Docker 镜像。访问容器镜像服务控制台

创建 EDAS 应用

然后我们创建一个 EDAS 应用,并使用刚创建的镜像部署该应用。访问 EDAS 控制台

配置负载均衡

最后,我们在负载均衡层强制启用 HTTPS,并将域名解析到负载均衡的公网 IP。

访问负载均衡控制台操作:

云效:一站式企业协同研发

使用 EDAS 已经在一定程度上加强了我们应用的迭代能力、健壮性和并发性,但是在多人协作、持续集成、持续交付上依然空缺。阿里云上有没有类似 Aone 的研发协同平台?答案是云效。不过云效并不会在创建应用时自动为我们分配机器资源,也没有像 Aone 那样有沉淀的 Node.js 标准镜像和构建、部署脚本。

创建 Kubernetes 集群

与 Aone 创建应用自动分配机器资源不同,在云效内需要自己创建集群资源,并授予云效进行管理。例如,笔者参考Aone 的设置,搭建了日常、预发、线上集群:

操作步骤如下:

这样便做到了日常与线上环境的隔离,预发和线上环境的隔离:

这里还有一个命题是,如何实现日常和预发环境只允许特定的客户端进行访问?目前通过负载均衡连接 VPC 的方式,只要知道了负载均衡 IP ,任何客户端都可以访问我们日常和预发环境的应用,这是我们不希望的。

创建 MongoDB 实例

为了和日常、线上环境配合,我们可以创建两个 MongoDB 数据库,并将两个数据库设置在日常和线上专有网络。如何创建请参考上文中“ECS - 创建 MongoDB 实例”章节。

创建镜像仓库

应用构建依赖容器镜像服务,在创建应用时就需要指定镜像仓库,因此我们提前创建。

创建云效应用

在云效创建应用的过程与 Aone 类似,遵循项目 - 应用的结构,此前的过程不再赘述。这里简单罗列创建 Node.js 应用的配置:

配置流水线

与 Aone 已有“日常 - 预发 - 线上”默认的流水线及各环节的构建和部署配置不同,在云效内我们需要手动配置这些信息。

我们参照 Aone 配置了三条流水线

流水线

以日常流水线为例,需要配置最基本的两个阶段:构建和部署。

构建和启动脚本

在 Aone 内 begg 和 midway 已经为我们封装好了镜像、构建和部署脚本的细节,在云效的上线流程中其过程相似,但相关的环节则需要自定义。

在仓库根目录创建如下文件,定义构建和启动脚本

然后在云效新建特效分支,提交到集成,进行一次流水线的部署,云效便会构建并下发创建 k8s 应用:

监控和日志

在应用上线后,为确保应用在持续健康地运行,还需要有相应的监控及日志(在出现问题时进行现场回溯)。在集团内部,Sandbox 为我们提供了全链路的监控能力。

在云上,有云监控、业务实时监控服务、日志服务。以下简单介绍一下如何接入和查看指标。

日志服务

在 k8s 集群已开通日志服务的前提下,可以针对集群内的应用进行日志配置。点击应用编辑即可进行配置,首次点击保存 k8s 服务将会自动创建日志服务

例如笔者就针对应用级别、标准输出进行了存储:

undefined

保存后访问阿里云日志服务控制台即看到相关的日志服务已创建:

undefined

点击查询即可看到相应的日志,例如笔者配置的 NodeBB 应用日志:

更多内容可参考:《使用日志服务进行Kubernetes日志采集》

云监控

对于每个应用,可以通过 k8s 容器服务与云监控的集成,提供监控功能查看应用的资源使用情况。还可以通过可用性监控快速发现本地或依赖的远程服务无响应的情况。

前端监控

使用业务实时监控服务可从页面打开速度(测速)、页面稳定性(JS Error)和外部服务调用成功率(API)这三个方面监测 Web 页面的健康度。接入后在应用控制台审视相关数据:

更多内容可参考:《前端监控接入概述》

NodeBB 相关

除此之外,笔者还踩了一些 NodeBB 的定制的坑,在此分享给有需要的同学。

Scoket.io 长连接保持

主要是两个配置:

Taobao OAuth 2.0 登录

笔者已封装 nodebb-plugin-sso-taobao 插件,只需要申请并填写 Appkey 信息即可使用。

皮肤加载 Google 资源问题

NodeBB 的前端基于 Bootstrap 实现,皮肤方案则使用了 bootswatch。bootswatch 中的一些皮肤(例如 simplex)使用了 Google 的字体资源。这些资源由于网络原因在国内无法加载,将会造成网页的渲染阻塞。

NodeBB@1.11.x 版本中,目前笔者还没有比较好的办法解决这一问题。唯一的方法就是不使用皮肤,如果确实希望复用某个皮肤的样式,可以通过创建 NodeBB 主题(参考:《如何创建主题》)的方式,将这些资源放入主题包中。

相关链接

致谢

钉钉社区是笔者已知的集团内应用于外部用户的 NodeBB 应用。在笔者开发过程中,钉钉社区的开发同学 @消珥 提供了非常多有益的建议和帮助,在此表示感谢。