为了账号安全,请及时绑定邮箱和手机立即绑定

用Node.js构建分布式系统

标签:
Node.js 架构

我造不了的东西我就搞不懂!

分布式系统就是多台电脑一起工作,对于客户端而言就像是用一台电脑一样。

你可能想不到分布式系统有多普遍!即使是小型的 B2B 初创公司,运行三个服务器,分别是用 Go 语言,Python 和 Node.js,也已经是分布式架构了。

这是我硬学得的。在我第一份开发工作的第三个月,我不得不接手一个项目。这既不在计划中,也不在我的职责范围内——但我别无选择。大多数教程?在那样的时候都不管用。我必须在实战中历练。带着伤痕累累。

我现在来给你讲明白。

让我们搭建一个使用纯JavaScript编写的Broker的分布式系统。

分布式架构

我更偏向实践,而不是理论——我更愿意先动手做,再争论定义。

别管那些学术上的吹毛求疵了。这里有一个更实用的定义:

分布式系统就像一个蜂巢——多台机器协同工作,仿佛是由一个统一的大脑控制。从客户端的角度来看,它感觉就像在使用一台计算机。

我们可以建那个。

最简单的服务器设置是我称之为单元系统(即后端的“与非门”)

客户端到服务器再到[数据库,存储桶[]]

切换到全屏模式 退出全屏

面试技巧:在系统设计面试中,从最简单的开始,比如一个用户和一个服务器。搞定这个后,然后开始扩展。每次都管用。


项目启动

创建项目结构:

    生产者/
        send.js
    消费者目录/
        consume.js
    .auth
    messagebroker.js
    package.json

全屏显示 退出全屏

安装所需的依赖项:

你可以试试在终端中运行这个命令:

npm i bunnimq@latest bunnimq-driver

切换到全屏 退出全屏

无来源信息。

运行以下命令克隆仓库: git clone https://github.com/SfundoMhlungu/bunni-example.git

全屏 退出全屏

消息代理:蜂巢心

消息中介就像是蜂巢的指挥中心,负责协调发送方和接收方。

设置代理

请注意,原文中的“Setting Up the Broker”在上下文中可能更准确地是指“设置消息代理”或“设置代理服务器”。如果需要更符合上下文的专业术语,请提供更多信息。此处根据专家建议直接翻译为“设置代理”。

在 messagebroker.js 中:

    import Bunny, { OPTS } from "bunnimq";
    import path from "path";
    import { fileURLToPath } from "url";

    OPTS.cwd = path.dirname(fileURLToPath(import.meta.url)); // 读取 .auth 文件的内容

    Bunny({ port: 3000, DEBUG: true });

切换到全屏模式 退出全屏模式

.auth 文件里:

简:doeeee:3
约翰:doeees:3

全屏进入 退出全屏

运行代理程序:

(注:此处“broker”根据具体上下文可能有不同译法,如“中间件”、“代理”等,此处采用“代理程序”作为示例。如有更具体的行业背景,建议使用更准确的翻译。)

运行消息代理文件
    node messagebroker.js

全屏,退出全屏

当 Bunny 启动时,它会找寻两个东西:

  • .auth 文件 – 类似于数据库中的用户记录。
  • 缓存队列 – 用于保证消息的持久化。

权限映射:

    const perms = {
      1: "发布",
      2: "消费",
      3: "发布和消费",
      4: "管理"
    };

全屏 退出全屏

为什么要用分布式系统?

请求和响应的周期非常快,但却很短暂。

    app.get("/endpoint", (req, res) => {
      // 做一些事情  
      res.send();
    });

切换到全屏模式,退出全屏

这没问题——直到你遇到长时间运行的任务(比如 FFMPEG 音频转换)。你不能让请求阻塞这么久

所以我们开始分工了:

  1. 注册任务
  2. 发送给代理
  3. 立即返回任务ID
    app.get("/endpoint", (req, res) => {
      const jobId = genUniqueJobId();
      sendMessageToBroker(jobId);
      res.send(jobId);  // 客户端会轮询此ID以获取进度
    });

进入全屏模式 退出全屏模式

兔子找到一个可用的工人,分配任务,并跟踪任务进度(例如,可以使用 Redis)。

    {
    "jobId": "xyz123",
    "progress": "20%"
    }

点击这里进入全屏 点击这里退出全屏

生产者:派发工作

在 send.js 文件中,代码如下所示:

    import Bunnymq from "bunnimq-driver";

    const 兔子mq = new Bunnymq({
      port: 3000,
      host: "localhost",
      username: "john",
      password: "doeees" // 请匹配你的 .auth 凭据
    });

    // 创建或连接到队列
    兔子mq.QueueDeclare(
      {
        name: "myqueue",
        config: {
          QueueExpiry: 60,
          MessageExpiry: 20,
          AckExpiry: 10,
          Durable: true, // 持久化消息内容
          noAck: false   // 需要确认应答
        }
      },
      (res) => console.log("队列创建成功:", res)
    );

    // 发布 500 个作业
    // 发布 500 个随机任务,每个任务都有一个唯一的 ID
    for (let i = 0; i < 500; i++) {
      兔子mq.Publish(`${Math.random()}-${i + 800}`, (res) => console.log(res));
    }

切换到全屏 退出全屏

运行生产者程序。

执行以下命令: node send.js

全屏 全退

你会看到来自 Bunni 的 "试图发送" 日志记录——但还没有进行处理。

目前还没有工人哩...

工作者:处理工作

在 'consume.js' 中:

    import Bunnymq from "bunnimq-driver";

    const 邦尼 = new Bunnymq({
      port: 3000,
      host: "localhost",
      username: "john",
      password: "doeees"
    });

    // 连接到队列
    邦尼.QueueDeclare({ name: "myqueue", config: undefined }, (res) => {
      console.log("队列连接:", res);
    });

    let 已处理的消息数量 = 0;

    // 消费消息
    邦尼.Consume("myqueue", async (msg) => {
      console.log("处理中:", msg);
      已处理的消息数量++;

      const [id, time] = msg.split("-");
      console.log(`任务ID: ${id}, 时长: ${time}毫秒`);

      await new Promise((resolve) => setTimeout(resolve, Number(time)));

      console.log(`已消费的消息数量: ${已处理的消息数量}`);
      邦尼.Ack((success) => console.log("准备好处理更多消息:", success));
    });

进入全屏模式 退出全屏模式

启动工作者:

运行 node consume.js

点击此处全屏/退出全屏

一旦工人连接并成功握手,就开始接收消息。

想要看看蜂巢的运作吗? 打开多个终端并启动更多工作进程,它们会自动分担工作。

这就是所谓的规模扩展,也是所谓的蜂群意识。

在实际场景中,你会将生产和消费的过程包裹在一个合适的服务器程序中,以便更好地管理和控制。

这篇文章是一个更大系列的一部分,在该系列中我们将从零开始构建bunni,面向对网络和系统感兴趣的开发者,并希望超越 CRUD 操作。

构建基于TCP的消息代理:超越API和端点 - Payhip

favicon payhip.com

本文涵盖了:

✅ 分布式系统的入门

✅ 自己动手做的一款消息中转站(用Node.js写的)

✅ 扩大用户规模来分配任务

溜了!🫡

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消