使用 Node.js 搭建微服务网关

Node.js 是什么

Node.js 是一个基于 Chrome v8 引擎的 Javascript 运行环境,它使用了一个"事件驱动"且"异步非阻塞 I/O" 的模型使其轻量且高效, Node.js 的包管理器 NPM 是全球最大的开源库生态系统。

对其定义的补充说明:

  • Node.js 是一个运行环境,而不是 Javascript 类库或者框架
  • Node.js 是基于 Chrome 浏览器的 V8 引擎开发的,该引擎是业界公认的高性能 js 引擎
  • Node.js 提供了事件驱动模型,可以将当前事件加入到事件队列中轮询
  • Node.js 提供了异步非阻塞式 I/O 模型,它比传统的同步阻塞式 I/O 模型具有更高的吞吐率
  • Node.js 的包管理器与 java 的 Maven 类似,但生态圈似乎更加庞大

安装 node.js

wget https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-x64.tar.xz
tar -xvzf node-v10.15.0-linux-x64.tar.xz -C /usr/local/ --strip-components=1

Node.js 入门

先给一段代码

var fs = require('fs')

fs.readFile('/etc/hosts', function (err, data) {
  if (err) {
     throw err;
  }
  console.log(data.toString());
});

Node.js 会创建一个读取文件的事件,并立刻将该事件加入到事件队列中,当前线程不会阻塞在这里。理论上后续不管有多少线程都会进来并产生一系列事件,这些事件都会加入到同样的事件队列中,它们会在事件队列中进行循环,一旦某个事件被触发(比如读取文件成功),就会执行后面定义的回调函数。

除了回调函数这种异步方式,它也提供了同步 API,代码如下

var fs = require('fs')

var data = fs.readFileSync('/etc/hosts')
console.log(data.toString());

Node.js 应用场景

Node.js 是针对实时 web 应用程序而开发的,非常适合为了满足实时性较强且并发量较大的应用场景。

  1. I/O 密集型 web 应用

    应用程序分为两大类

    • CPU 密集型应用
      • 对 CPU 要求较高,需要一个强大的计算过程
      • 如股票交易系统,数据分析系统等
    • I/O 密集型应用
      • 常常有频繁的网络传输或磁盘存储现象
      • 如高并发网站,实时 Web 系统等

    Express 是一个非常优秀的 web 框架

  2. Web 聊天室 Socket.IO

  3. 命令行工具

    可以写一段 Node.js 程序,通过 NPM 的命令将其安装到操作系统中,随时在命令行控制台输入该命令运行。

    Commander.js

    基于 Node.js 的前端开发工具如下 Bower, Grunt, Gulp, Webpack, Yeoman

  4. HTTP 代理服务器

Node.js 可以通过异步的方式处理大量的兵法请求,它可以作为服务器端应用程序的代理,起到如 Nginx, Apache 等 HTTP代理服务器的作用。

常用的 HTTP 代理服务器模块 node-http-proxy ,在实现微服务架构的服务网关是会用到该项技术。

npm 镜像

淘宝提供了一个 NPM 镜像,速度非常快。

npm install --registry=https://registry.npm.taobao.org

在安装一个要打包到生产环境的安装包时,你应该使用 npm install --save

如果你在安装一个用于开发环境的安装包(例如,linter, 测试库等),你应该使用 npm install --save-dev。可在 npm 文档 中查找更多信息。

淘宝 npm 镜像官网 http://npm.taobao.org/

使用 Node.js 搭建微服务网关

什么是微服务架构

先来整体回顾下下微服务架构

微服务网关(Node.js) 是微服务架构中的核心组件,它是客户端请求的门户,是调用具体服务端的桥梁。它类似于 Facade 模式(门面模式),将底层复杂的细节进行了屏蔽,对外提供简单且统一的调用方式,如 HTTP 方式。

微服务网关,也称为服务网关(Service Gateway),或者 API 网关(API Gateway)。它们之间的关系如下面架构图所示:

在上图中,我们使用服务网关来建立 client 与 service1 之间的联系。当从 client 发送请求时,请求首先进入 service gateway, 随后 service gateway 就会将请求路由到具体的服务器。在路由过程中,会涉及具体的路由算法,最简单的做法就是在 service gateway 中解析 client 请求中的路径和请求头,从而路由到具体的服务端。

为了确保服务具有较高的可用性,我们可部署多个相同的服务端,此时需要再 service gateway 中设置相关路由算法,将请求随机路由到具体的服务端,当然也可以对 client ip 地址进行 Hash 算法,从而实现请求路由。

服务网关的路由过程我们称为"反向代理"。和 Nginx ,Apache 类似。

反向代理的应用场景有

  1. 使静态资源与动态资源分离
  2. 实现 AJAX 跨域访问
  3. 搭建统一服务网关接口

使用 Node.js 实现反向代理

Node.js 搭建反向代理服务器,需要下面 3 步

  1. 使用如下命令安装 HTTP Proxy 模块

    npm install http-proxy
    
  2. 使用 HTTP Proxy 模块启动代理服务器,新建一个名为 app_proxy.js 的文件

    var http = require('http');
    
    var httpProxy = require('http-proxy');
    
    var PORT = 1234;
    
    // 创建代理服务器对象
    var proxy = httpProxy.createProxyServer();
    
    proxy.on('error', function (err, req, res) {
      res.end(); // 输出空白响应数据
    });
    
    var app = http.createServer(function (req, res) {
      // 执行反向代理
      proxy.web(req, res, {
        target: 'http://localhost:8080' // 目标地址
      })
    })
    
    app.listen(PORT, function() {
      console.log('server is running at %d', PORT)
    })
    
  3. 启动 app_proxy.js 应用程序

node app_proxy.js

运行后,就可以通过 "localhost:1234" 去访问 "localhost:8080"。

除了 HTTP,该模块还支持 HTTPS 与 WebSocket 的反向代理。

可以使用 apache bench 对其性能做一个简单的测试。模拟 1000 个用户,每个用户并发 100 个请求

ab -n 1000 -c 100 http://localhost:1234

Node.js 与 Nginx 相比性能不差,而且其扩展性远高于 Nginx。我们可以动态指定被代理的目标地址,而 Nginx 中配置的目标地址却是静态的。这一点对实现服务发现功能及其重要,因为我们需要从 Service Registry 中获取需要代理的微服务信息,并执行反向代理操作,调用相应的微服务 REST API。

最后需要说明的是,服务网关不仅仅提供反向代理与服务发现特性,此外它还具备安全认证,性能监控,数据缓存,请求分片,静态响应等特性,我们可以根据实际情况扩展。

参考

  • 《架构探险—轻量级微服务架构》
posted @ 2019-01-04 11:45  ReyCG  阅读(4100)  评论(0编辑  收藏  举报