AppForge
返回首页
后端开发Node.js微服务架构

Node.js 微服务架构设计与实践

探索如何使用 Node.js 构建可扩展的微服务架构,包括服务发现、负载均衡和容错处理。

B
Bruce
全栈开发工程师,热爱技术分享
2024-12-3012 分钟

什么是微服务?


微服务是一种架构风格,将应用程序拆分为一组小型、独立的服务,每个服务运行在自己的进程中,通过轻量级机制(通常是 HTTP API)进行通信。


微服务的优势


  • **独立部署**:每个服务可以独立部署和扩展
  • **技术多样性**:不同服务可以使用不同的技术栈
  • **故障隔离**:一个服务的故障不会影响其他服务
  • **团队自治**:小团队可以独立负责一个服务

  • 使用 Express 创建微服务


    // user-service/index.ts

    import express from 'express'


    const app = express()

    app.use(express.json())


    const users = new Map()


    app.get('/users/:id', (req, res) => {

    const user = users.get(req.params.id)

    if (!user) {

    return res.status(404).json({ error: 'User not found' })

    }

    res.json(user)

    })


    app.post('/users', (req, res) => {

    const id = crypto.randomUUID()

    const user = { id, ...req.body }

    users.set(id, user)

    res.status(201).json(user)

    })


    app.listen(3001, () => {

    console.log('User service running on port 3001')

    })


    服务间通信


    HTTP 通信


    // order-service/index.ts

    import axios from 'axios'


    async function getUser(userId: string) {

    const response = await axios.get(`http://user-service:3001/users/${userId}`)

    return response.data

    }


    app.post('/orders', async (req, res) => {

    const { userId, items } = req.body


    // 调用用户服务验证用户

    const user = await getUser(userId)


    // 创建订单

    const order = { id: crypto.randomUUID(), userId, items, user }

    res.status(201).json(order)

    })


    消息队列


    // 使用 RabbitMQ

    import amqp from 'amqplib'


    async function publishMessage(queue: string, message: object) {

    const connection = await amqp.connect('amqp://localhost')

    const channel = await connection.createChannel()


    await channel.assertQueue(queue)

    channel.sendToQueue(queue, Buffer.from(JSON.stringify(message)))


    await channel.close()

    await connection.close()

    }


    // 发布订单创建事件

    await publishMessage('order-created', { orderId, userId, items })


    API 网关


    // api-gateway/index.ts

    import express from 'express'

    import { createProxyMiddleware } from 'http-proxy-middleware'


    const app = express()


    // 路由到不同的微服务

    app.use('/api/users', createProxyMiddleware({

    target: 'http://user-service:3001',

    pathRewrite: { '^/api/users': '/users' }

    }))


    app.use('/api/orders', createProxyMiddleware({

    target: 'http://order-service:3002',

    pathRewrite: { '^/api/orders': '/orders' }

    }))


    app.listen(3000, () => {

    console.log('API Gateway running on port 3000')

    })


    容错处理


    import CircuitBreaker from 'opossum'


    const breaker = new CircuitBreaker(getUser, {

    timeout: 3000,

    errorThresholdPercentage: 50,

    resetTimeout: 30000

    })


    breaker.fallback(() => ({ id: 'unknown', name: 'Guest' }))


    breaker.on('open', () => console.log('Circuit breaker opened'))

    breaker.on('close', () => console.log('Circuit breaker closed'))


    // 使用熔断器

    const user = await breaker.fire(userId)


    总结


    微服务架构提供了更好的可扩展性和灵活性,但也带来了额外的复杂性。在采用微服务之前,需要仔细评估团队的能力和项目的需求。


    B

    Bruce

    全栈开发工程师,热爱技术分享

    感谢阅读!如果这篇文章对你有帮助,欢迎分享给更多的朋友。