为Messenger架构选择哪种方法?

时间:2018-07-16 20:12:16

标签: node.js mongodb redis messenger

我们正在为我们的应用程序编写供个人使用的即时通讯程序。当前版本的计划负载是数百个用户,可能是一千或两个。

  1. 作为数据库,我使用Mongo。消息以messages编写(通过chats_id与user_chats和uid与users数据库中的外部表链接)。消息到达客户端会产生一系列事件作为响应(标记读取)。很明显,我需要排队。如何做得更好?有没有确定队列优先级的方法?

  2. 在真空中,节点的球形过程应承受多少用户?应该使用多少内存?我正在使用pm2进行流程管理,并使用node-ipc进行广播。

  3. 该向谁求助,以优化数据库请求。现在有一个快速的书面解释如下。此示例请求所有聊天,对于每个聊天,它选择最后一条消息,未读消息的数量和最近看到的用户。在MySQL中,我会提出一个大要求。在Mongo中这样做更好吗?我在Mongo的水平还处于中等水平。

  4. 体系结构本身。现在,来自客户端的操作进出处理程序,该处理程序了解如何处理该操作,并且需要通知该操作人员。通常,处理程序会通知相应的管理器,并且已经将其写入数据库,并在必要时通知其他进程。


const loadUserChatsStatistic = async (chatIds, userId) => {
  const startExecTime = new Date();
  const userChats = await db()
    .collection("user_chats")
    .aggregate([
      { $match: { uid: userId, chats_id: { $in: chatIds.map(ObjectID) } } },
      {
        $lookup: {
          from: "chats",
          localField: "chats_id",
          foreignField: "_id",
          as: "chat"
        }
      },
      { $unwind: "$chat" },
      {
        $lookup: {
          from: "user_last_seen",
          localField: "chats_id",
          foreignField: "chats_id",
          as: "last_seens"
        }
      }
    ])
    .toArray();

  const chats = await Promise.all(
    userChats.map(async userChat => {
      const usersCount = await db()
        .collection("user_chats")
        .find({ chats_id: userChat.chats_id })
        .count();

      let unreadCountQuery = {};

      if (userChat.last_read) {
        unreadCountQuery = { _id: { $gt: userChat.last_read } };
      } else {
        unreadCountQuery = { _id: { $gt: userChat._id } };
      }
      const unreadCount = await db()
        .collection("messages")
        .find({ ...unreadCountQuery, chats_id: userChat.chats_id })
        .count();
      const message =
        (await db()
          .collection("messages")
          .findOne({ chats_id: userChat.chats_id }, { sort: { _id: -1 } })) ||
        {};

      return { ...userChat, usersCount, unreadCount, message };
    })
  );

  console.log(
    "Execution time for loadUserChatsStatistic",
    new Date() - startExecTime
  );

  return chats.sort((a, b) => {
    if (!a.message._id) {
      return true;
    }

    if (!b.message._id) {
      return false;
    }

    return (
      new Date(ObjectID(a.message._id).getTimestamp()) <
      new Date(ObjectID(b.message._id).getTimestamp())
    );
  });
};

0 个答案:

没有答案