使用Docker安装Rails、Sidekiq和Redis,在指定的时间执行作业
首先
在这篇文章中,我们将介绍如何使用Docker设置Rails、Sidekiq和Redis,并在指定的时间执行作业。本次例子中,我们将以向用户发送提醒邮件的功能为例。
Sidekiq 是什么?
Sidekiq是一个用于Ruby的背景作业处理库,用于执行异步处理。它用Redis作为后端来管理创建的作业。
非同步處理是指不需要等待前一項處理完成的行動。
程序同时执行多个任务。通过在后台执行繁重或耗时的操作,可以提高性能。
常见的做法是异步处理时间较长的任务,比如发送邮件或批量处理数据。
Docker和Docker Compose的配置
首先,使用Docker和Docker Compose来设置Rails、MySQL、Redis和Sidekiq的各个服务。在项目的根目录下创建以下Dockerfile和docker-compose.yml文件。
FROM ruby:3.1
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - && \
apt-get install -y nodejs
ENV TZ=UTC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir /VehicleMinders
WORKDIR /VehicleMinders
COPY Gemfile /VehicleMinders/Gemfile
COPY Gemfile.lock /VehicleMinders/Gemfile.lock
RUN bundle install
COPY . /VehicleMinders
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
version: '3'
services:
db:
platform: linux/amd64
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- '3306:3306'
command: --default-authentication-plugin=mysql_native_password
volumes:
- mysql-data:/var/lib/mysql
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- db
- redis
stdin_open: true
tty: true
sidekiq:
build: .
command: bundle exec sidekiq
volumes:
- .:/app
depends_on:
- db
- redis
redis:
image: redis
volumes:
mysql-data:
driver: local
Sidekiq的配置
配置Sidekiq。在Gemfile中添加gem ‘sidekiq’,然后运行bundle install。
gem 'sidekiq'
为了使用Sidekiq的仪表板功能,在routes.rb中添加以下代码。
通过访问http://localhost:3000/sidekiq,可以查看正在运行的作业和等待执行的作业。
Rails.application.routes.draw do
require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq'
end
创建Sidekiq的配置文件sidekiq.rb。在该文件中,对Sidekiq连接Redis服务器的配置进行设置。
redis_config = { url: 'redis://redis:6379/0' }
Sidekiq.configure_server do |config|
config.redis = redis_config
end
Sidekiq.configure_client do |config|
config.redis = redis_config
end
创建电子邮件发送功能
创建一个用于发送电子邮件的UserMailer。
class UserMailer < ApplicationMailer
def reminder_email(user)
@user = notification.user
mail(to: @user.email, subject: 'Your reminder')
end
end
创建电子邮件发送任务
创建一个在指定时间发送电子邮件的作业。将其创建在 app/workers 目录中。
作业是一个执行特定任务的类,包含 Sidekiq::Worker 模块,并定义 perform 方法。perform 方法在作业被执行时会被调用。
class ReminderMailerWorker
include Sidekiq::Worker
def perform(notification_id)
notification = Notification.find(notification_id)
UserMailer.reminder_email(notification).deliver_now
end
end
提醒事项的调度
安排提醒事项的日程安排。这次,我们向 Notification 模型添加了 after_create 和 after_update 的回调函数,并安排了发送提醒邮件的日程安排。
要将作业添加到队列中,可以使用 perform_async 方法。该方法会将作业保存到 Redis 中,然后在后台执行。
在下面的示例中,我们使用 perform_at 方法来指定执行 perform 方法的时间作为第一个参数。
class Notification < ApplicationRecord
belongs_to :user
after_save :schedule_reminder_mailer, if: -> { self.datetime.present? }
private
def schedule_reminder_mailer
ReminderMailerWorker.perform_at(self.datetime, self.id)
end
end
总结
这次介绍了使用Sidekiq在指定的时间执行作业的方法。还有一个名为sidekiq-cron的宝石,它可以用来管理需要定期执行的作业。
参考资料・网址
Sidekiq的使用方式
官方GitHub