Node.js项目实现微服务架构

Node.js项目实现微服务架构

微服务是一种软件架构风格,在这种架构中,应用程序被构建为一组小的、独立的服务,每个服务负责处理特定的业务功能。这些服务可以独立开发、部署和扩展,并通过轻量级的通信机制(通常是 HTTP API)进行互相通信。


微服务的特点

  1. 模块化:每个微服务都是一个独立的模块,负责特定的业务功能。不同的团队可以独立地开发和维护不同的微服务。

  2. 独立部署:微服务可以独立部署和更新,而不必影响其他服务。这使得应用程序更具灵活性,能够快速响应变化。

  3. 技术多样性:不同的微服务可以使用不同的编程语言、数据库和技术栈,选择最适合其功能的技术。

  4. 可扩展性:由于微服务是独立的,特定的微服务可以独立扩展,从而优化资源利用。

  5. 容错性:因为微服务是分布式的,如果一个服务出现故障,通常不会导致整个系统崩溃。


Node.js实现微服务

将应用拆分为多个服务

首先,将单体应用拆分为多个独立的微服务。每个微服务应专注于一个特定的业务功能,例如用户管理、订单处理、支付等。

每个微服务可能会拥有自己的数据库,以实现服务之间的解耦。

数据库可能需要分片或者复制以提高性能和容错性。

在微服务之间或微服务与数据库之间使用缓存层(如 Redis、Memcached)来加速数据访问和减少数据库负载。

使用分布式数据库(如 Cassandra、CockroachDB)来存储和管理海量数据。

对于文件或大数据对象,可以使用分布式对象存储(如 AWS S3、MinIO)来存储和访问。

使用独立的代码库和包管理

每个微服务应当拥有自己的代码库和独立的package.json文件。这使得它们可以独立管理依赖项,并能够使用不同的 Node.js 版本或第三方库。

选择合适的通信方式

微服务之间需要通信。

微服务常见的通信方式:

  • HTTP/RESTfull API:每个微服务暴露 RESTfull API 供其他服务调用。
  • 消息队列(MQ):可以使用 MQ 来异步传递消息,常用的 MQ 有 RabbitMQ、Apache Kafka、Redis Streams 等。
  • gRPC:是一种 RPC(远程过程调用)框架,适合高性能通信场景。

选择合适的 web 框架构建 RESTfull 微服务

比如 Express 或者 Koa.js 等。

服务注册和发现

可以使用微服务注册和发现工具来管理与发现这些微服务。

常用的:Consul、Eureka、etcd

配置管理

每个微服务拥有自己的配置,可以使用配置管理工具来管理配置。

常用的:Consul、Vault

日志记录和监控

常用的日志聚合工具:ELK(Elasticsearch, Logstash, Kibana)

常用的监控工具:Prometheus、Grafana

部署

可以将每个微服务打包成 Docker 容器,再使用 Docker Compose 或者 K8s 自动化部署、扩展、管理这些容器。

CI/CD:使用 Jenkins、GitLab CI、CircleCI 等工具实现自动化的构建、测试和部署流程。

蓝绿部署/金丝雀发布:在发布新版本时,采用蓝绿部署或金丝雀发布策略,减少发布风险。

负载均衡和代理

微服务层之间需要使用负载均衡器来实现流量分发,以实现高可用性和容错性。

常用的负载均衡器:HAProxy、Nginx、AWS ELB

还需要使用反向代理来分发来自 API 网关的请求到适当的微服务,常用 Nginx 反向代理。

API 网关

可以使用 API 网关来统一管理和路由所有微服务的请求。

API 网关可以处理请求路由、认证、限流。

常用的 API 网关:Nginx、Kong、Express Gateway 等。

容错处理

在分布式系统中可能会出现某个微服务失效。

可以使用熔断器比如 opossum 来防止级联故障,确保在某个微服务失败时,系统其他部分仍然可用。


Node.js微服务简单实例

  1. 为微服务创建一个目录,用于存放所有的微服务。

微服务项目目录结构:

my-microservices-project/
├── api-gateway/
│   ├── package.json
│   ├── index.js
├── user-service/
│   ├── package.json
│   ├── index.js
├── order-service/
│   ├── package.json
│   ├── index.js
├── docker-compose.yml
└── README.md
  1. 为每个微服务创建一个目录。

  2. 每个微服务拥有自己的目录以及package.json文件。

user-service/package.json
1
2
3
4
5
6
7
8
{
"name": "user-service",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"express": "^4.17.1"
}
}
  1. 编写微服务,每个微服务都相当于是一个Node.js项目。
user-service/index.js
1
2
3
4
5
6
7
8
9
10
11
const express = require('express');
const app = express();
const port = 3001;

app.get('/users', (req, res) => {
res.json([{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]);
});

app.listen(port, () => {
console.log(`User service running on port ${port}`);
});
  1. API Gateway

创建api-gateway/index.js文件,用于路由客户端的请求到对应的微服务。

api-gateway/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const express = require('express');
const httpProxy = require('http-proxy');
const app = express();
const port = 3000;
const proxy = httpProxy.createProxyServer();

app.get('/users', (req, res) => {
proxy.web(req, res, { target: 'http://localhost:3001' });
});

app.get('/orders', (req, res) => {
proxy.web(req, res, { target: 'http://localhost:3002' });
});

app.listen(port, () => {
console.log(`API Gateway running on port ${port}`);
});
  1. 启动微服务
bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 启动gateway
cd api-gateway
npm install
node index.js

# 启动user-service服务
cd user-service
npm install
node index.js

# 启动order-service服务
cd order-service
npm install
node index.js

现在api-gateway和微服务已经运行了:

  • http://localhost:3000:运行了api-gateway,它将客户端请求路由到对应的微服务。
  • http://localhost:3001:运行了user-service服务。
  • http://localhost:3002:运行了order-service服务。
  1. 测试微服务

使用postman或者cURL测试微服务。

  1. 微服务容器化

为每个服务创建Dockerfile文件,然后使用Docker Compose或者K8s来编排这些服务的容器。

这里使用Docker Compose。

第一步:为每个服务创建Dockerfile文件

Dockerfile
1
2
3
4
5
6
FROM node:14
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
CMD ["node", "index.js"]

第二步:使用Docker Compose,创建docker-compose.yml文件来编排服务容器

docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
version: '3'
services:
user-service:
build: ./user-service
ports:
- "3001:3001"
order-service:
build: ./order-service
ports:
- "3002:3002"
api-gateway:
build: ./api-gateway
ports:
- "3000:3000"

第三步:启动所有服务

bash
1
docker-compose up

评论