发布于 2026-01-06 6 阅读
0

Implementing an email queue with bullJs and hosting on Heroku! The problem... Prerequisite Bull Implementation Hosting this setup on Heroku Conclusion DEV's Worldwide Show and Tell Challenge Presented by Mux: Pitch Your Projects!

使用 bullJs 实现邮件队列并托管在 Heroku 上!

问题...

先决条件

公牛实施

将此设置托管在 Heroku 上

结论

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

问题...

如果你曾经接到过类似这样的任务,Setup an email service with SendGrid and nodemailer你大概会像我们大多数人一样……为生产环境配置 SendGrid,为开发和测试环境配置 nodemailer。如果你成功完成这些就此止步,没人会责怪你,但很多时候,某些应用程序的邮件发送还需要一些额外的配置才能保证其流畅运行。我们常常忘记问的一些问题是:

  • 邮件量的增加会对我的电子邮件设置产生什么影响?
  • 如果用户数量达到 10,000,并且每分钟至少发送一封电子邮件,它还能正常运行吗?
  • 当我的电子邮件由于各种原因第一次发送失败时会发生什么?

在本文中,我们将探讨如何使用 nodeJs 应用程序中的 bullJs 设置电子邮件队列系统,以及如何使用 Heroku 将此设置部署到类似生产环境中。

先决条件

你也可以根据自己的喜好搭建一个 Node.js 应用,然后集成这个示例中的代码,它应该都能正常运行。不过,本文将使用克隆的仓库进行演示。

克隆的仓库包含一些使用 Node.js、Express 和 Sequelize 搭建的样板代码。我添加了一个注册端点,用户需要输入用户名usernameemail地址server/controllers/auth才能注册。如果您按照仓库中的设置说明操作,readMe应该可以访问注册端点http://127.0.0.1:3333/v1/auth/register并注册用户。
替代文字

我已经预先在应用程序中配置了 SendGrid 和 nodemailer,它们以函数的形式存在,我们可以在需要发送电子邮件时调用它们server/config/emailSetup.js。我还添加了一个基础邮件模板函数,该函数接受一个usernameemail一个和link作为参数。我们现在想要做的是确保用户注册时会收到一封电子邮件,这封邮件会被放入队列,并由 bullJs 包进行处理。

Bull 是一个 Node 库,它实现了一个基于Redis 的快速而强大的队列系统。

虽然可以直接使用 Redis 命令实现队列,但该库提供了一个 API,它处理了所有底层细节,并增强了 Redis 的基本功能,从而可以轻松处理更复杂的用例。了解更多

公牛实施

导航到该server/config文件夹​​并添加一个名为bullConfig.js.的文件。粘贴以下代码。

import Queue from 'bull';
import dotenv from 'dotenv';

dotenv.config();

const { REDIS_URL } = process.env;

// Initiating the Queue with a redis instance
const sendMailQueue = new Queue('sendMail', REDIS_URL);

export default Sendmail queue;
Enter fullscreen mode Exit fullscreen mode

请确保您的.env文件包含 `<filename> REDIS_URL='redis://127.0.0.1:6379'`。在这个文件中,我们Queue从包中导入了 `<package_name> bull`。这样,我们就创建了 Bull 队列类的一个新实例并将其命名为 ` sendMailQueue<queue_name>`。我们可以为不同的用例创建多个队列,例如:

const imageQueue = new Queue('image transcoding');
Enter fullscreen mode Exit fullscreen mode

请确保后台运行着 Redis 服务器。

接下来,我们需要notifications.jsserver/helper文件夹中创建一个文件。在这个文件中,我们将介绍来自bullJs producer和 的两个关键概念consumer。我们还将创建一个函数,该函数接收收件人的电子邮件地址、姓名以及用于验证其电子邮件地址的链接。我们可以通过添加其他函数来扩展此实现,例如添加一个forgotPassword接收与该函数相同参数的函数registrationEmail。对于我们发送的每个新通知,我们需要producer通过调用 来触发sendMailQueue.add(data, options);

import emailService from '../config/emailSetup';
import sendMailQueue from '../config/bullConfig';
import template from './template';

/**
 *
 * @param {*} emailTo
 * @param {*} link
 * @param {*} name
 * @returns {*} sends an email to a new user
 */
const registrationEmail = (emailTo, link, name) => {
  const subject = 'Welcome to Karneek';
  const body = `<p>Dear ${name},</p>
  <p>We are thrilled to have you.</p>
  <p>Some random message with link</p>
      <a href="${link}" class="button">Confirm email</a>`;
  const message = template(subject, body, emailTo);

  const options = {
    attempts: 2,
  };
  const data = { emailTo, subject, message };

  // Producer: adds jobs to que, in this case emails to be sent out upon signup
  sendMailQueue.add(data, options);
};

// Consumer: this gets called each time the producer receives a new email.
sendMailQueue.process(async job => {
  emailService.mailSender(job.data);
});

const Notifications = { registrationEmail };

export default Notifications;
Enter fullscreen mode Exit fullscreen mode

最后,我们需要registrationEmail在注册路由中调用该函数。导航至[此处应server/controllers/auth.js填写地址]。导入我们的通知文件。

import notifications from '../helpers/notifications';
Enter fullscreen mode Exit fullscreen mode

registerUser函数中,紧接着verificatioToken变量 add之后。

      const { REGISTRATION_URL } = process.env;
      const verificationLink = `${REGISTRATION_URL}?token=${verificationToken}`;
      await notifications.registrationEmail(email, verificationLink, username);
Enter fullscreen mode Exit fullscreen mode

就这样。要测试一下,请运行服务器npm run start:dev并创建一个新用户!在你的控制台上,你应该会看到

替代文字

将此设置托管在 Heroku 上

这种方案的挑战在于我们需要将项目托管在像 Heroku 这样的远程服务器上。为了实现这一点,我们需要在 Heroku 上运行一个 Redis 实例。首先,我们需要添加一个名为 `<Heroku_addon_name>` 的 Heroku 插件,此外,由于该项目使用 Postgres 数据库,Heroku Redis我们还需要添加 `<Heroku_addon_name>` 。Heroku Postgres

前往 Heroku 控制面板,创建一个新应用。之后,前往新创建的 Heroku 应用的概览选项卡,然后点击……Configure Add-ons

替代文字

这将跳转到一个带有搜索框的新页面。搜索并添加Heroku Redis,以及Heroku Postgres

替代文字

复制你的 Heroku 应用名称,然后在终端运行以下命令。

heroku git:remote -a <name of heroku app>
heroku addons | grep heroku-redis
heroku addons:create heroku-redis:hobby-dev -a <name of heroku app>
Enter fullscreen mode Exit fullscreen mode

执行完最后一个命令后,你应该会看到类似这样的内容。

替代文字

此时你需要复制你的新 Redis 插件名称。我的插件名称是redis-deep-25660(见截图)。

运行以下命令

heroku addons:info <your addon name> 
heroku config | grep REDIS
git push heroku master 
Enter fullscreen mode Exit fullscreen mode

如果你在日志中看到类似这样的内容,那就完蛋了!😳
替代文字

要了解更多Heroku Redis工作原理…… https://devcenter.heroku.com/articles/heroku-redis#provisioning-the-add-on

结论

在本文中,我们成功地使用 bullJs 实现了邮件队列功能,并通过在 Heroku 应用上配置和运行 Redis 服务器,将我们的小型应用托管在了 Heroku 上。希望本文对您有所帮助。如果您遇到任何问题,可以点击此处查看完整代码或留言。

文章来源:https://dev.to/vic3king/implementing-an-email-queue-with-bulljs-and-hosting-on-heroku-257b