![图片[1]-Node.js微服务架构设计与实践](http://cdn.mrz2516.com//uploads/688bf3e306a8e_1754002403.jpeg)
一、微服务架构概述
1. 什么是微服务?
微服务是一种将单体应用拆分为多个小型、独立服务的架构模式。每个服务负责特定的业务功能,可以独立开发、部署和扩展。
2. 微服务的优势
– 技术多样性
:不同服务可以使用不同的技术栈
– 独立部署
:服务可以独立更新和部署
– 故障隔离
:单个服务故障不会影响整个系统
– 可扩展性
:可以根据需求独立扩展特定服务
– 团队自治
:不同团队可以独立负责不同服务
二、微服务设计原则
1. 服务拆分策略
```javascript
// Mrz微服务拆分示例
const mrzServiceArchitecture = {
// 按业务领域拆分
userService: {
responsibilities: ['用户注册', '用户认证', '用户信息管理'],
endpoints: ['/api/users', '/api/auth', '/api/profile'],
database: 'user_db'
},
orderService: {
responsibilities: ['订单创建', '订单查询', '订单状态管理'],
endpoints: ['/api/orders', '/api/order-status'],
database: 'order_db'
},
paymentService: {
responsibilities: ['支付处理', '退款处理', '支付记录'],
endpoints: ['/api/payments', '/api/refunds'],
database: 'payment_db'
},
notificationService: {
responsibilities: ['邮件通知', '短信通知', '推送通知'],
endpoints: ['/api/notifications'],
database: 'notification_db'
}
};
```
2. 领域驱动设计(DDD)
```javascript
// Mrz领域模型示例
class MrzUserDomain {
constructor() {
this.aggregates = {
User: {
entities: ['UserProfile', 'UserPreferences'],
valueObjects: ['Email', 'PhoneNumber'],
repositories: ['UserRepository']
},
Order: {
entities: ['Order', 'OrderItem'],
valueObjects: ['OrderNumber', 'Price'],
repositories: ['OrderRepository']
}
};
}
}
```
三、API网关设计
1. 网关功能实现
```javascript
// Mrz API网关实现
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const rateLimit = require('express-rate-limit');
class MrzApiGateway {
constructor() {
this.app = express();
this.setupMiddleware();
this.setupRoutes();
}
setupMiddleware() {
// 请求限流
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100, // 限制每个IP 15分钟内最多100个请求
message: 'Mrz API: 请求过于频繁,请稍后再试'
});
this.app.use(limiter);
// 身份验证
this.app.use('/api/*', this.authenticate);
// 请求日志
this.app.use(this.logRequest);
}
setupRoutes() {
// 用户服务路由
this.app.use('/api/users', createProxyMiddleware({
target: 'http://user-service:3001',
changeOrigin: true,
pathRewrite: {
'^/api/users': '/api'
}
}));
// 订单服务路由
this.app.use('/api/orders', createProxyMiddleware({
target: 'http://order-service:3002',
changeOrigin: true,
pathRewrite: {
'^/api/orders': '/api'
}
}));
// 支付服务路由
this.app.use('/api/payments', createProxyMiddleware({
target: 'http://payment-service:3003',
changeOrigin: true,
pathRewrite: {
'^/api/payments': '/api'
}
}));
}
authenticate(req, res, next) {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'Mrz API: 缺少认证令牌' });
}
// 验证JWT令牌
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
res.status(401).json({ error: 'Mrz API: 无效的认证令牌' });
}
}
logRequest(req, res, next) {
console.log(`Mrz Gateway: ${req.method} ${req.path} - ${new Date().toISOString()}`);
next();
}
}
```
2. 服务发现与负载均衡
```javascript
// Mrz服务发现实现
const consul = require('consul');
class MrzServiceDiscovery {
constructor() {
this.consul = consul({
host: process.env.CONSUL_HOST || 'localhost',
port: process.env.CONSUL_PORT || 8500
});
}
// 注册服务
async registerService(serviceName, servicePort) {
const serviceId = `${serviceName}-${Date.now()}`;
await this.consul.agent.service.register({
id: serviceId,
name: serviceName,
port: servicePort,
address: process.env.SERVICE_HOST || 'localhost',
tags: ['mrz-microservice', 'nodejs'],
check: {
http: `http://localhost:${servicePort}/health`,
interval: '10s',
timeout: '5s'
}
});
console.log(`Mrz Service Discovery: ${serviceName} registered with ID ${serviceId}`);
}
// 发现服务
async discoverService(serviceName) {
const services = await this.consul.catalog.service.nodes(serviceName);
return services.map(service => ({
id: service.ServiceID,
address: service.ServiceAddress,
port: service.ServicePort
}));
}
// 健康检查
async healthCheck(serviceName) {
const checks = await this.consul.agent.check.list();
return Object.values(checks).filter(check =>
check.ServiceName === serviceName && check.Status === 'passing'
);
}
}
```
四、服务间通信
1. RESTful API设计
```javascript
// Mrz用户服务API实现
const express = require('express');
const mongoose = require('mongoose');
class MrzUserService {
constructor() {
this.app = express();
this.setupRoutes();
this.connectDatabase();
}
setupRoutes() {
// 用户注册
this.app.post('/api/register', async (req, res) => {
try {
const { email, password, name } = req.body;
// 验证邮箱格式
if (!this.isValidEmail(email)) {
return res.status(400).json({
error: 'Mrz User Service: 邮箱格式不正确'
});
}
// 检查用户是否已存在
const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(409).json({
error: 'Mrz User Service: 用户已存在'
});
}
// 创建新用户
const hashedPassword = await bcrypt.hash(password, 10);
const user = new User({
email,
password: hashedPassword,
name,
createdAt: new Date()
});
await user.save();
res.status(201).json({
message: 'Mrz User Service: 用户注册成功',
userId: user._id
});
} catch (error) {
console.error('Mrz User Service Error:', error);
res.status(500).json({
error: 'Mrz User Service: 服务器内部错误'
});
}
});
// 用户登录
this.app.post('/api/login', async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user) {
return res.status(401).json({
error: 'Mrz User Service: 用户不存在'
});
}
const isValidPassword = await bcrypt.compare(password, user.password);
if (!isValidPassword) {
return res.status(401).json({
error: 'Mrz User Service: 密码错误'
});
}
// 生成JWT令牌
const token = jwt.sign(
{ userId: user._id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '24h' }
);
res.json({
message: 'Mrz User Service: 登录成功',
token,
user: {
id: user._id,
email: user.email,
name: user.name
}
});
} catch (error) {
console.error('Mrz User Service Error:', error);
res.status(500).json({
error: 'Mrz User Service: 服务器内部错误'
});
}
});
// 获取用户信息
this.app.get('/api/profile/:userId', async (req, res) => {
try {
const { userId } = req.params;
const user = await User.findById(userId).select('-password');
if (!user) {
return res.status(404).json({
error: 'Mrz User Service: 用户不存在'
});
}
res.json({
message: 'Mrz User Service: 获取用户信息成功',
user
});
} catch (error) {
console.error('Mrz User Service Error:', error);
res.status(500).json({
error: 'Mrz User Service: 服务器内部错误'
});
}
});
}
isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
async connectDatabase() {
try {
await mongoose.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
console.log('Mrz User Service: MongoDB连接成功');
} catch (error) {
console.error('Mrz User Service: MongoDB连接失败:', error);
}
}
}
```
2. 消息队列通信
```javascript
// Mrz消息队列实现
const amqp = require('amqplib');
class MrzMessageQueue {
constructor() {
this.connection = null;
this.channel = null;
}
async connect() {
try {
this.connection = await amqp.connect(process.env.RABBITMQ_URL);
this.channel = await this.connection.createChannel();
console.log('Mrz Message Queue: RabbitMQ连接成功');
} catch (error) {
console.error('Mrz Message Queue: RabbitMQ连接失败:', error);
}
}
// 发布消息
async publishMessage(queueName, message) {
try {
await this.channel.assertQueue(queueName, { durable: true });
this.channel.sendToQueue(queueName, Buffer.from(JSON.stringify(message)));
console.log(`Mrz Message Queue: 消息已发布到队列 ${queueName}`);
} catch (error) {
console.error('Mrz Message Queue: 发布消息失败:', error);
}
}
// 消费消息
async consumeMessage(queueName, callback) {
try {
await this.channel.assertQueue(queueName, { durable: true });
this.channel.consume(queueName, (msg) => {
if (msg) {
const message = JSON.parse(msg.content.toString());
callback(message);
this.channel.ack(msg);
}
});
console.log(`Mrz Message Queue: 开始消费队列 ${queueName}`);
} catch (error) {
console.error('Mrz Message Queue: 消费消息失败:', error);
}
}
}
// 订单服务使用消息队列
class MrzOrderService {
constructor() {
this.messageQueue = new MrzMessageQueue();
this.setupMessageHandlers();
}
async setupMessageHandlers() {
await this.messageQueue.connect();
// 监听支付完成事件
this.messageQueue.consumeMessage('payment.completed', async (message) => {
console.log('Mrz Order Service: 收到支付完成消息:', message);
await this.updateOrderStatus(message.orderId, 'paid');
});
// 监听库存更新事件
this.messageQueue.consumeMessage('inventory.updated', async (message) => {
console.log('Mrz Order Service: 收到库存更新消息:', message);
await this.updateInventory(message.productId, message.quantity);
});
}
async createOrder(orderData) {
try {
// 创建订单
const order = new Order(orderData);
await order.save();
// 发布订单创建事件
await this.messageQueue.publishMessage('order.created', {
orderId: order._id,
userId: order.userId,
totalAmount: order.totalAmount,
items: order.items
});
return order;
} catch (error) {
console.error('Mrz Order Service Error:', error);
throw error;
}
}
}
```
五、数据管理策略
1. 数据库设计
```javascript
// Mrz微服务数据库设计
const mongoose = require('mongoose');
// 用户服务数据模型
const userSchema = new mongoose.Schema({
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
name: { type: String, required: true },
createdAt: { type: Date, default: Date.now },
updatedAt: { type: Date, default: Date.now }
});
// 订单服务数据模型
const orderSchema = new mongoose.Schema({
userId: { type: String, required: true },
items: [{
productId: { type: String, required: true },
quantity: { type: Number, required: true },
price: { type: Number, required: true }
}],
totalAmount: { type: Number, required: true },
status: {
type: String,
enum: ['pending', 'paid', 'shipped', 'delivered', 'cancelled'],
default: 'pending'
},
createdAt: { type: Date, default: Date.now },
updatedAt: { type: Date, default: Date.now }
});
// 支付服务数据模型
const paymentSchema = new mongoose.Schema({
orderId: { type: String, required: true },
userId: { type: String, required: true },
amount: { type: Number, required: true },
method: { type: String, required: true },
status: {
type: String,
enum: ['pending', 'completed', 'failed', 'refunded'],
default: 'pending'
},
transactionId: { type: String, unique: true },
createdAt: { type: Date, default: Date.now }
});
```
2. 数据一致性
```javascript
// Mrz Saga模式实现
class MrzSagaOrchestrator {
constructor() {
this.sagas = new Map();
}
// 创建订单Saga
async createOrderSaga(orderData) {
const sagaId = `saga_${Date.now()}`;
const saga = {
id: sagaId,
status: 'started',
steps: [
{ name: 'createOrder', status: 'pending' },
{ name: 'reserveInventory', status: 'pending' },
{ name: 'processPayment', status: 'pending' },
{ name: 'confirmOrder', status: 'pending' }
],
compensations: []
};
this.sagas.set(sagaId, saga);
try {
// 步骤1: 创建订单
const order = await this.createOrder(orderData);
saga.steps[0].status = 'completed';
// 步骤2: 预留库存
await this.reserveInventory(order.items);
saga.steps[1].status = 'completed';
// 步骤3: 处理支付
const payment = await this.processPayment(order);
saga.steps[2].status = 'completed';
// 步骤4: 确认订单
await this.confirmOrder(order.id);
saga.steps[3].status = 'completed';
saga.status = 'completed';
return { success: true, orderId: order.id };
} catch (error) {
console.error('Mrz Saga Error:', error);
await this.compensateSaga(sagaId);
throw error;
}
}
// Saga补偿机制
async compensateSaga(sagaId) {
const saga = this.sagas.get(sagaId);
if (!saga) return;
saga.status = 'failed';
// 按相反顺序执行补偿操作
for (let i = saga.steps.length - 1; i >= 0; i--) {
const step = saga.steps[i];
if (step.status === 'completed') {
try {
await this.executeCompensation(step.name);
step.status = 'compensated';
} catch (error) {
console.error(`Mrz Saga Compensation Error for ${step.name}:`, error);
}
}
}
}
async executeCompensation(stepName) {
switch (stepName) {
case 'createOrder':
// 删除订单
break;
case 'reserveInventory':
// 释放库存
break;
case 'processPayment':
// 退款
break;
case 'confirmOrder':
// 取消订单确认
break;
}
}
}
```
六、容器化与部署
1. Docker配置
```dockerfile
# Mrz用户服务Dockerfile
FROM node:18-alpine
WORKDIR /app
# 复制package文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制应用代码
COPY . .
# 创建非root用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
# 更改文件所有权
RUN chown -R nodejs:nodejs /app
USER nodejs
# 暴露端口
EXPOSE 3001
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3001/health || exit 1
# 启动应用
CMD ["npm", "start"]
```
2. Docker Compose配置
```yaml
# Mrz微服务Docker Compose配置
version: '3.8'
services:
# API网关
mrz-api-gateway:
build: ./api-gateway
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- JWT_SECRET=${JWT_SECRET}
depends_on:
- mrz-user-service
- mrz-order-service
- mrz-payment-service
networks:
- mrz-network
# 用户服务
mrz-user-service:
build: ./user-service
ports:
- "3001:3001"
environment:
- NODE_ENV=production
- MONGODB_URI=mongodb://mrz-mongodb:27017/user_db
- JWT_SECRET=${JWT_SECRET}
depends_on:
- mrz-mongodb
networks:
- mrz-network
# 订单服务
mrz-order-service:
build: ./order-service
ports:
- "3002:3002"
environment:
- NODE_ENV=production
- MONGODB_URI=mongodb://mrz-mongodb:27017/order_db
- RABBITMQ_URL=amqp://mrz-rabbitmq:5672
depends_on:
- mrz-mongodb
- mrz-rabbitmq
networks:
- mrz-network
# 支付服务
mrz-payment-service:
build: ./payment-service
ports:
- "3003:3003"
environment:
- NODE_ENV=production
- MONGODB_URI=mongodb://mrz-mongodb:27017/payment_db
- RABBITMQ_URL=amqp://mrz-rabbitmq:5672
depends_on:
- mrz-mongodb
- mrz-rabbitmq
networks:
- mrz-network
# MongoDB数据库
mrz-mongodb:
image: mongo:6.0
ports:
- "27017:27017"
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD}
volumes:
- mrz-mongo-data:/data/db
networks:
- mrz-network
# RabbitMQ消息队列
mrz-rabbitmq:
image: rabbitmq:3-management
ports:
- "5672:5672"
- "15672:15672"
environment:
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_PASSWORD}
volumes:
- mrz-rabbitmq-data:/var/lib/rabbitmq
networks:
- mrz-network
# Redis缓存
mrz-redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- mrz-redis-data:/data
networks:
- mrz-network
# Consul服务发现
mrz-consul:
image: consul:1.15
ports:
- "8500:8500"
command: agent -server -bootstrap-expect=1 -ui -client=0.0.0.0
networks:
- mrz-network
volumes:
mrz-mongo-data:
mrz-rabbitmq-data:
mrz-redis-data:
networks:
mrz-network:
driver: bridge
```
七、监控与日志
1. 应用监控
```javascript
// Mrz监控系统
const prometheus = require('prom-client');
const winston = require('winston');
class MrzMonitoringSystem {
constructor() {
this.setupMetrics();
this.setupLogging();
}
setupMetrics() {
// HTTP请求计数器
this.httpRequestsTotal = new prometheus.Counter({
name: 'mrz_http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status']
});
// 请求持续时间直方图
this.httpRequestDuration = new prometheus.Histogram({
name: 'mrz_http_request_duration_seconds',
help: 'HTTP request duration in seconds',
labelNames: ['method', 'route']
});
// 活跃连接数
this.activeConnections = new prometheus.Gauge({
name: 'mrz_active_connections',
help: 'Number of active connections'
});
// 内存使用量
this.memoryUsage = new prometheus.Gauge({
name: 'mrz_memory_usage_bytes',
help: 'Memory usage in bytes',
labelNames: ['type']
});
}
setupLogging() {
this.logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
defaultMeta: { service: 'mrz-microservice' },
transports: [
new winston.transports.File({ filename: 'mrz-error.log', level: 'error' }),
new winston.transports.File({ filename: 'mrz-combined.log' })
]
});
if (process.env.NODE_ENV !== 'production') {
this.logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
}
// 记录HTTP请求
recordHttpRequest(method, route, status, duration) {
this.httpRequestsTotal.inc({ method, route, status });
this.httpRequestDuration.observe({ method, route }, duration);
this.logger.info('HTTP Request', {
method,
route,
status,
duration,
timestamp: new Date().toISOString()
});
}
// 记录错误
recordError(error, context = {}) {
this.logger.error('Application Error', {
error: error.message,
stack: error.stack,
context,
timestamp: new Date().toISOString()
});
}
// 获取指标
async getMetrics() {
return await prometheus.register.metrics();
}
}
```
2. 分布式追踪
```javascript
// Mrz分布式追踪
const { trace, context } = require('@opentelemetry/api');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
class MrzDistributedTracing {
constructor() {
this.setupTracing();
}
setupTracing() {
const provider = new NodeTracerProvider();
const exporter = new JaegerExporter({
endpoint: process.env.JAEGER_ENDPOINT || 'http://localhost:14268/api/traces'
});
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
provider.register();
}
// 创建追踪span
createSpan(operationName, attributes = {}) {
const tracer = trace.getTracer('mrz-microservice');
const span = tracer.startSpan(operationName);
Object.entries(attributes).forEach(([key, value]) => {
span.setAttribute(key, value);
});
return span;
}
// 追踪HTTP请求
traceHttpRequest(req, res, next) {
const span = this.createSpan('http_request', {
'http.method': req.method,
'http.url': req.url,
'http.user_agent': req.get('User-Agent')
});
const originalSend = res.send;
res.send = function(data) {
span.setAttribute('http.status_code', res.statusCode);
span.end();
return originalSend.call(this, data);
};
next();
}
}
```
八、安全与认证
1. JWT认证
```javascript
// Mrz JWT认证中间件
const jwt = require('jsonwebtoken');
class MrzAuthentication {
constructor() {
this.secret = process.env.JWT_SECRET;
this.options = {
expiresIn: '24h',
issuer: 'mrz-microservice',
audience: 'mrz-users'
};
}
// 生成JWT令牌
generateToken(payload) {
return jwt.sign(payload, this.secret, this.options);
}
// 验证JWT令牌
verifyToken(token) {
try {
return jwt.verify(token, this.secret, this.options);
} catch (error) {
throw new Error('Mrz Authentication: 无效的令牌');
}
}
// 认证中间件
authenticate(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({
error: 'Mrz Authentication: 缺少认证令牌'
});
}
const token = authHeader.substring(7);
try {
const decoded = this.verifyToken(token);
req.user = decoded;
next();
} catch (error) {
return res.status(401).json({
error: 'Mrz Authentication: 无效的认证令牌'
});
}
}
// 角色授权中间件
authorize(roles) {
return (req, res, next) => {
if (!req.user) {
return res.status(401).json({
error: 'Mrz Authorization: 未认证用户'
});
}
if (!roles.includes(req.user.role)) {
return res.status(403).json({
error: 'Mrz Authorization: 权限不足'
});
}
next();
};
}
}
```
2. 网络安全
```javascript
// Mrz网络安全配置
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const cors = require('cors');
class MrzSecurityConfig {
constructor(app) {
this.app = app;
this.setupSecurity();
}
setupSecurity() {
// 设置安全头
this.app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
imgSrc: ["'self'", "data:", "https:"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));
// CORS配置
this.app.use(cors({
origin: process.env.ALLOWED_ORIGINS?.split(',') || ['https://www.mrz2516.com'],
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
// 请求限流
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100, // 限制每个IP 15分钟内最多100个请求
message: {
error: 'Mrz Security: 请求过于频繁,请稍后再试'
},
standardHeaders: true,
legacyHeaders: false
});
this.app.use('/api/', limiter);
// SQL注入防护
this.app.use(this.sanitizeInput);
}
// 输入数据清理
sanitizeInput(req, res, next) {
const sanitize = (obj) => {
for (let key in obj) {
if (typeof obj[key] === 'string') {
// 移除潜在的SQL注入字符
obj[key] = obj[key].replace(/['";\\]/g, '');
} else if (typeof obj[key] === 'object') {
sanitize(obj[key]);
}
}
};
sanitize(req.body);
sanitize(req.query);
sanitize(req.params);
next();
}
}
```
九、性能优化
1. 缓存策略
```javascript
// Mrz缓存系统
const Redis = require('ioredis');
class MrzCacheSystem {
constructor() {
this.redis = new Redis({
host: process.env.REDIS_HOST || 'localhost',
port: process.env.REDIS_PORT || 6379,
password: process.env.REDIS_PASSWORD,
retryDelayOnFailover: 100,
enableReadyCheck: false,
maxRetriesPerRequest: null
});
}
// 设置缓存
async set(key, value, ttl = 3600) {
try {
const serializedValue = JSON.stringify(value);
await this.redis.setex(`mrz:${key}`, ttl, serializedValue);
console.log(`Mrz Cache: 缓存已设置 ${key}`);
} catch (error) {
console.error('Mrz Cache Error:', error);
}
}
// 获取缓存
async get(key) {
try {
const value = await this.redis.get(`mrz:${key}`);
return value ? JSON.parse(value) : null;
} catch (error) {
console.error('Mrz Cache Error:', error);
return null;
}
}
// 删除缓存
async delete(key) {
try {
await this.redis.del(`mrz:${key}`);
console.log(`Mrz Cache: 缓存已删除 ${key}`);
} catch (error) {
console.error('Mrz Cache Error:', error);
}
}
// 缓存中间件
cacheMiddleware(ttl = 3600) {
return async (req, res, next) => {
const key = `api:${req.originalUrl}`;
try {
const cachedResponse = await this.get(key);
if (cachedResponse) {
return res.json(cachedResponse);
}
const originalSend = res.json;
res.json = function(data) {
this.set(key, data, ttl);
return originalSend.call(this, data);
};
next();
} catch (error) {
next();
}
};
}
}
```
2. 数据库优化
```javascript
// Mrz数据库优化
class MrzDatabaseOptimizer {
constructor() {
this.setupIndexes();
this.setupConnectionPool();
}
// 设置数据库索引
async setupIndexes() {
const db = mongoose.connection;
// 用户集合索引
await db.collection('users').createIndex({ email: 1 }, { unique: true });
await db.collection('users').createIndex({ createdAt: -1 });
// 订单集合索引
await db.collection('orders').createIndex({ userId: 1 });
await db.collection('orders').createIndex({ status: 1 });
await db.collection('orders').createIndex({ createdAt: -1 });
// 支付集合索引
await db.collection('payments').createIndex({ orderId: 1 });
await db.collection('payments').createIndex({ status: 1 });
await db.collection('payments').createIndex({ createdAt: -1 });
console.log('Mrz Database: 索引设置完成');
}
// 连接池配置
setupConnectionPool() {
mongoose.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
maxPoolSize: 10,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000,
bufferMaxEntries: 0
});
}
// 查询优化
async optimizedQuery(collection, query, options = {}) {
const { limit = 10, skip = 0, sort = {}, projection = {} } = options;
return await collection
.find(query, projection)
.sort(sort)
.skip(skip)
.limit(limit)
.lean() // 返回普通JavaScript对象,提高性能
.exec();
}
}
```
十、部署与CI/CD
1. GitHub Actions配置
```yaml
# Mrz CI/CD配置
name: Mrz Microservice CI/CD
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
services:
mongodb:
image: mongo:6.0
ports:
- 27017:27017
redis:
image: redis:7-alpine
ports:
- 6379:6379
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
env:
MONGODB_URI: mongodb://localhost:27017/test
REDIS_URL: redis://localhost:6379
- name: Run linting
run: npm run lint
- name: Build Docker images
run: |
docker build -t mrz-user-service ./user-service
docker build -t mrz-order-service ./order-service
docker build -t mrz-payment-service ./payment-service
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Deploy to production
run: |
echo "Mrz Deployment: 部署到生产环境"
# 这里添加实际的部署脚本
```
2. Kubernetes部署
```yaml
# Mrz Kubernetes部署配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: mrz-user-service
labels:
app: mrz-user-service
spec:
replicas: 3
selector:
matchLabels:
app: mrz-user-service
template:
metadata:
labels:
app: mrz-user-service
spec:
containers:
- name: mrz-user-service
image: mrz/user-service:latest
ports:
- containerPort: 3001
env:
- name: NODE_ENV
value: "production"
- name: MONGODB_URI
valueFrom:
secretKeyRef:
name: mrz-secrets
key: mongodb-uri
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: mrz-secrets
key: jwt-secret
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3001
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3001
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: mrz-user-service
spec:
selector:
app: mrz-user-service
ports:
- protocol: TCP
port: 80
targetPort: 3001
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mrz-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: api.mrz2516.com
http:
paths:
- path: /users
pathType: Prefix
backend:
service:
name: mrz-user-service
port:
number: 80
```
十一、总结
Node.js微服务架构为现代应用开发提供了强大的解决方案。通过合理的服务拆分、API网关设计、服务间通信、数据管理、容器化部署等策略,可以构建出高可用、可扩展、易维护的微服务系统。
记住,微服务不是银弹,需要根据具体业务需求和技术团队能力来选择合适的架构模式。持续学习、实践和优化是成功实施微服务架构的关键。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容