




已阅读5页,还剩17页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
如何进行高质量Node.js微服务的编写和部署微服务架构是一种构造应用程序的替代性方法。应用程序被分解为更小、完全独立的组件,这使得它们拥有更高的敏捷性、可伸缩性和可用性。一个复杂的应用被拆分为若干微服务,微服务更需要一种成熟的交付能力。持续集成、部署和全自动测试都必不可少。编写代码的开发人员必须负责代码的生产部署。构建和部署链需要重大更改,以便为微服务环境提供正确的关注点分离。Node.js 是构建微服务的利器,为什么这么说呢,我们先看下 Node.js 有哪些优势:1. Node.js 采用事件驱动、异步编程,为网络服务而设计2. Node.js 非阻塞模式的IO处理给 Node.js 带来在相对低系统资源耗用下的高性能与出众的负载能力,非常适合用作依赖其它IO资源的中间层服务3. Node.js轻量高效,可以认为是数据密集型分布式部署环境下的实时应用系统的完美解决方案。这些优势正好与微服务的优势:敏捷性、可伸缩性和可用性相契合(捂脸笑),再看下 Node.js 的缺点:1. 单进程,单线程,只支持单核CPU,不能充分的利用多核CPU服务器。一旦这个进程 down 了,那么整个 web 服务就 down 了2. 异步编程,callback 回调地狱第一个缺点可以通过启动多个实例来实现CPU充分利用以及负载均衡,话说这不是 K8s 的原生功能吗。第二个缺点更不是事儿,现在可以通过generator、promise等来写同步代码,爽的不要不要的。下面我们主要从 Docker 和 Node.js 出发聊一下高质量Node.js微服务的编写和部署:1. Node.js 异步流程控制:generator 与 promise2. Express、Koa 的异常处理3. 如何编写 Dockerfile4. 微服务部署及 DevOps 集成1 Node.js 异步流程控制:Generator 与 PromiseNode.js 的设计初衷为了性能而异步,现在已经可以写同步的代码了,你造吗?目前 Node.js 的LTS版本早就支持了Generator,Promise这两个特性,也有许多优秀的第三方库 bluebird、q 这样的模块支持的也非常好,性能甚至比原生的还好,可以用 bluebird 替换 Node.js 原生的 Promise:global.Promise = require(bluebird)blurbird 的性能是 V8 里内置的 Promise 3 倍左右(bluebird 的优化方式见/petkaantonov/bluebird/wiki/Optimization-killers)。1.1 ES2015 GeneratorGenerators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances. -/en-US/docs/Web/JavaScript/Reference/Statements/function*generator 就像一个取号机,你可以通过取一张票来向机器请求一个号码。你接收了你的号码,但是机器不会自动为你提供下一个。换句话说,取票机“暂停”直到有人请求另一个号码(next(),此时它才会向后运行。下面我们看一个简单的示例:从上面的代码的输出可以看出:1. generator 函数的定义,是通过function *()实现的2. 对 generator 函数的调用返回的实际是一个遍历器,随后代码通过使用遍历器的next()方法来获得函数的输出3. 通过使用yield语句来中断 generator 函数的运行,并且可以返回一个中间结果4. 每次调用next()方法,generator 函数将执行到下一个yield语句或者是return语句。下面我们就对上面代码的每次next调用进行一个详细的解释:1. 第1次调用next()方法的时候,函数执行到第一次循环的yield index+语句停了下来,并且返回了0这个value,随同value返回的done属性表明 generator 函数的运行还没有结束2. 第2次调用next()方法的时候,函数执行到第二循环的yield index+语句停了下来,并且返回了1这个value,随同value返回的done属性表明 generator 函数的运行还没有结束3. . .4. 第4次调用next()方法的时候,由于循环已经结束了,所以函数调用立即返回,done属性表明 generator 函数已经结束运行,value是undefined的,因为这次调用并没有执行任何语句PS: 如果在 generator 函数内部需要调用另外一个 generator 函数,那么对目标函数的调用就需要使用yield*。1.2 ES2015 PromiseThe Promise object is used for asynchronous computations. A Promise represents an operation that hasnt completed yet, but is expected in the future. -/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。一个 Promise 一般有3种状态:1. pending: 初始状态, 不是fulfilled,也不是rejected.2. fulfilled: 操作成功完成.3. rejected: 操作失败.一个 Promise 的生命周期如下图:下面我们看一段具体代码:asyncFunction这个函数会返回 Promise 对象, 对于这个 Promise 对象,我们调用它的then方法来设置resolve后的回调函数,catch方法来设置发生错误时的回调函数。该 Promise 对象会在setTimeout之后的16ms时被resolve, 这时then的回调函数会被调用,并输出 Async Hello world 。在这种情况下catch的回调函数并不会被执行(因为 Promise 返回了resolve), 不过如果运行环境没有提供 setTimeout 函数的话,那么上面代码在执行中就会产生异常,在 catch 中设置的回调函数就会被执行。小结如果是编写一个 SDK 或 API,推荐使用传统的 callback 或者 Promise,不使用 generator 的原因是: generator 的出现不是为了解决异步问题 使用 generator 是会传染的,当你尝试yield一下的时候,它要求你也必须在一个 generator function 内看来学习 Promise 是水到渠成的事情。2 Express、Koa 的异常处理一个友好的错误处理机制应该满足三个条件:1. 对于引发异常的用户,返回 500 页面2. 其他用户不受影响,可以正常访问3. 不影响整个进程的正常运行下面我们就以这三个条件为原则,具体介绍下 Express、Koa 中的异常处理。2.1 Express 异常处理在 Express 中有一个内置的错误处理中间件,这个中间件会处理任何遇到的错误。如果你在 Express 中传递了一个错误给next(),而没有自己定义的错误处理函数处理这个错误,这个错误就会被 Express 默认的错误处理函数捕获并处理,而且会把错误的堆栈信息返回到客户端,这样的错误处理是非常不友好的,还好我没可以通过设置NODE_ENV环境变量为production,这样 Express 就会在生产环境模式下运行应用,生产环境模式下 Express 不会把错误的堆栈信息返回到客户端。在 Express 项目中可以定义一个错误处理的中间件用来替换 Express 默认的错误处理函数:在所有其他app.use()以及路由之后引入以上代码,可以满足以上三个友好错误处理条件,是一种非常友好的错误处理机制。2.2 Koa 异常处理我们以Koa 1.x为例,看代码:把上面的代码放在所有app.use()函数前面,这样基本上所有的同步错误均会被try catch(err)捕获到了,具体原理大家可以了解下 Koa 中间件的机制。2.3 未捕获的异常uncaughtException上面的两种异常处理方法,只能捕获同步错误,而异步代码产生的错误才是致命的,uncaughtException错误会导致当前的所有用户连接都被中断,甚至不能返回一个正常的HTTP错误码,用户只能等到浏览器超时才能看到一个no data received错误。这是一种非常野蛮粗暴的异常处理机制,任何线上服务都不应该因为uncaughtException导致服务器崩溃。在Node.js 我们可以通过以下代码捕获uncaughtException错误:捕获uncaughtException后,Node.js 的进程就不会退出,但是当 Node.js 抛出 uncaughtException 异常时就会丢失当前环境的堆栈,导致 Node.js 不能正常进行内存回收。也就是说,每一次、uncaughtException都有可能导致内存泄露。既然如此,退而求其次,我们可以在满足前两个条件的情况下退出进程以便重启服务。当然还可以利用domain模块做更细致的异常处理,这里就不做介绍了。3 如何编写 Dockerfile3.1 基础镜像选择我们先选用 Node.js 官方推荐的node:argon官方LTS版本最新镜像,镜像大小为656.9 MB(解压后大小,下文提到的镜像大小没有特殊说明的均指解压后的大小)The first thing we need to do is define from what image we want to build from. Here we will use the latest LTS (long term support) versionargonofnodeavailable from the Docker Hub -/en/docs/guides/nodejs-docker-webapp/我们事先写好了两个文件package.json,app.js:下面开始编写 Dockerfile,由于直接从 Dockerhub 拉取镜像速度较慢,我们选用时速云的docker官方镜像docker_library/node,这些官方镜像都是与 Dockerhub 实时同步的:执行以下命令进行构建:docker build -t zhangpc/docker_web_app:argon .最终得到的镜像大小是660.3 MB,体积略大,Docker 容器的优势是轻量和可移植,所以承载它的操作系统即基础镜像也应该迎合这个特性,于是我想到了Alpine Linux,一个面向安全的,轻量的 Linux 发行版,基于musllibc和busybox。下面我们使用alpine:edge作为基础镜像,镜像大小为4.799 MB:,执行以下命令进行构建:docker build -t zhangpc/docker_web_app:alpine .最终得到的镜像大小是31.51 MB,足足缩小了20倍,运行两个镜像均测试通过。3.2 还有优化的空间吗?首先,大小上还是可以优化的,我们知道 Dockerfile 的每条指令都会将结果提交为新的镜像,下一条指令将会基于上一步指令的镜像的基础上构建,所以如果我们要想清除构建过程中产生的缓存,就得保证产生缓存的命令和清除缓存的命令在同一条 Dockerfile 指令中,因此修改 Dockerfile 如下:执行以下命令进行构建:docker build -t zhangpc/docker_web_app:alpine .最终得到的镜像大小是21.47 MB,缩小了10M。其次,我们发现在构建过程中有一些依赖是基本不变的,例如安装 Node.js 以及项目依赖,我们可以把这些不变的依赖集成在基础镜像中,这样可以大幅提升构建速度,基本上是秒级构建。当然也可以把这些基本不变的指令集中在 Dockerfile 的前面部分,并保持前面部分不变,这样就可以利用缓存提升构建速度。最后,如果使用了 Express 框架,在构建生产环境镜像时可以设置NODE_ENV环境变量为production,可以大幅提升应用的性能,还有其他诸多好处,下面会有介绍。小结我们构建的三个镜像大小对比见上图,镜像的大小越小,发布的时候越快捷,而且可以提高安全性,因为更少的代码和程序在容器中意味着更小的攻击面。使用node:argon作为基础镜像构建出的镜像(tag 为 argon)压缩后的大小大概为2
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 农业科技公司员工保密合同
- 简易手机抵押合同范本5篇
- 购销合同轮胎3篇
- 安全施工现场培训课件
- 瓶子里的小昆虫课件
- 理财培训课件
- 电力工程采购方案(3篇)
- 安全文明施工培训感想
- 贵港港平南港区长岐塘作业区罗洪码头提档升级工程环评报告
- 环卫作业管理知识培训课件
- 2025年中国电信招聘考试行政职业能力测试预测题集
- 静脉治疗知识培训课件
- 学风建设科研诚信宣教课件
- 江西省宜春市2025年上半年事业单位公开遴选试题含答案分析
- 2025繁轩科技发展(天津)有限公司公开招聘工作人员35人备考题库及答案解析
- 2025年度水电项目工程结算与审计服务协议
- 德育副校长在新学期德育工作部署会讲话范文
- (2025年标准)学生玩耍纠纷协议书
- 南昌二中初一数学试卷
- 2025-2026秋季学年第一学期学生国旗下演讲稿(20周):第五周 76载荣光里我们茁壮成长-喜迎国庆
- 2025金融消费权益保护知识竞赛题库(+答案)
评论
0/150
提交评论