中间件
commit信息:Updated Middleware (markdown) | 提交者:kevjin | 提交时间:2020-02-25 | 版本:c646c65
Sidekiq有着与Rack相似的中间件理念:少量代码即可实现功能。Sidekiq将中间件分为客户端和服务端。
- 客户端中间件 在将作业推送到Redis之前运行,并且让你在它被推送之前 修改/停止 该作业。
- 服务端中间件 ‘围绕着’作业处理运行。
定制中间件
Sidekiq 5+发表时没有中间件。许多gems和服务要安装中间件来跟踪作业或提供额外的功能。你也可以添加自己的中间件。
客户端中间件
在把作业推送到Redis之前,你可以使用客户端中间件给它添加作业元数据。如果你需要设置一些全局状态像 当前区域、在multi-tenant应用中的当前tenant等等,在作业被执行之前,相同的作业数据可以被服务端中间件使用。
客户端中间件可以接收类参数作为类对象,或者包含类名的字符串。
不调用 yield
或者不返回 job
以外的任何内容,这样将不会导致进一步的中间件被调用,并且该作业将不会被推送到队列。 (请注意,yield
将返回跟 job
相同的值)
module MyMiddleware
module Client
class CustomerJobAttribute
# @param [String, Class] worker_class the string or class of the worker class being enqueued
# @param [Hash] job the full job payload
# * @see https://github.com/mperham/sidekiq/wiki/Job-Format
# @param [String] queue the name of the queue the job was pulled from
# @param [ConnectionPool] redis_pool the redis pool
# @return [Hash, FalseClass, nil] if false or nil is returned,
# the job is not to be enqueued into redis, otherwise the block's
# return value is returned
# @yield the next middleware in the chain or the enqueuing of the job
def call(worker_class, job, queue, redis_pool)
# return false/nil to stop the job from going to redis
return false if queue != 'default'
job['customer'] = Customer.current_id
yield
end
end
end
end
服务端中间件
你可以使用服务端中间件在作业执行期间做一些工作。以下是一个记录任何作业的所有异常的例子。
不调用 yield
将导致不再有任何中间件被调用,并且该作业的perform
方法将不被调用。
class MyMiddleware::Server::ErrorLogger
# @param [Object] worker the worker instance
# @param [Hash] job the full job payload
# * @see https://github.com/mperham/sidekiq/wiki/Job-Format
# @param [String] queue the name of the queue the job was pulled from
# @yield the next middleware in the chain or worker `perform` method
# @return [Void]
def call(worker, job, queue)
begin
yield
rescue => ex
puts ex.message
end
end
end
在你注册一个中间件时,你也可以给该中间件的初始化器传递一些选项:
class MyMiddleware::Server::ErrorLogger
def initialize(options=nil)
# options == { :foo => 1, :bar => 2 }
end
def call(worker, msg, queue)
begin
yield
rescue => ex
puts ex.message
end
end
end
注册中间件
把你的中间件注册为链的一部分:
Sidekiq.configure_client do |config|
config.client_middleware do |chain|
chain.add MyMiddleware::Client::CustomerJobAttribute
end
end
Sidekiq.configure_server do |config|
config.server_middleware do |chain|
chain.add MyMiddleware::Server::ErrorLogger, :foo => 1, :bar => 2
end
end
我建议把这些代码放到你Rails应用的config/initializers/sidekiq.rb
文件中。
在两个地方都注册了客户端中间件
这些运行在Sidekiq服务中的作业,它们可以像客户端一样,自己推送新的作业给Sidekiq。在那种情况下,你也必须在configure_server
块中配置你的客户端中间件。
Sidekiq.configure_client do |config|
config.client_middleware do |chain|
chain.add MyMiddleware::Client::CustomerJobAttribute
end
end
Sidekiq.configure_server do |config|
config.client_middleware do |chain|
chain.add MyMiddleware::Client::CustomerJobAttribute
end
config.server_middleware do |chain|
chain.add MyMiddleware::Server::ErrorLogger, :foo => 1, :bar => 2
end
end
移除中间件
如果由于一些原因你需要移除一个中间件,你可以像下面这样写配置文件:
Sidekiq.configure_server do |config|
config.server_middleware do |chain|
chain.remove Some::Middleware
end
end
中间件排序
使用-v
选项启动Sidekiq时会打印配置了的客户端和服务端中间件链。如果多个中间件可能以某种方式发生冲突,排序就显得至关重要。