前面说到,消息队列的进程要把任务放入队列中,由于有很多任务,需要排队,所以这些任务是需要存储起来的。在ruby中,有很多gem可以实现后台的消息队列,但它们的存储方式有区别,比如delayed_job就是用数据库(MySQL,Sqlite,PostgreSQL等)来存的,它会先让你创建表,如果有任务进来,就会插入到表中作为一条记录,要处理的时候就会取出这条记录。像和sidekiq就是用redis来存储数据的,redis是存储在计算机的内存中的。比较一下,就知道resque和sidekiq在存储方式上比delayed_job有优势,而delayed_job的好处是能直接利用数据库,不用额外安装redis。

    消息队列是另外的一个进程,任务进入消息队列中,一个接一个的处理,也就是说,A进程在被处理时,必须等前面的任务被处理完才能轮到它。这种方式体现在delayed_job和resque中。sidekiq的处理方式是多线程的,它是基于celluloid的,用Actor作为并发模型,它能同时处理多个任务。

    值得一提的是Ruby on Rails从4.2开始加上了。因为有各种各样的消息队列的解决方案,active_job就是提供了统一的接口和调用,要用到消息队列还是会用到上面提到的几个。这个东西就像activerecord一样,要指定数据库那也是很简单的,只要换相应的gem和改配置文件就行了,而active_job也正是这样。

    不过,这一篇文章不会详说上面的三种消息队列的实现,只会说到特用于PostgreSQL的消息队列queue_classic

    2. PostgreSQL的listen/notify

    是基于PostgreSQL的listen/notify来实现的,列队在等任务进来就是用的listen,把任务放入队列就是notify。

    懂了PostgreSQL的listen/notify,也就等于懂了其他的订阅/发布模式。

    它很简单,就相当于一种广播机制,比如,你定阅杂志,还有其他人也订阅了,这个过程就叫listen,也就是监听,等杂志有更新了,或者有新的杂志出来,它就会广播,就会送一份给订阅杂志的人,这个过程就是notify,也就是通知。

    listen/notify的使用很简单。

    首先是listen(监听),只接监听的通道的名称,这个名称自己定义。

    这个时候可以直接执行notify。

    还可以传参数。

    也可以结合sql语句来使用。

    只要连接到同一个数据库的所有session都会接到监听通道传过来的信息。

    可以尝试另开一个psql进程。然后notify,再回到之前的psql执行listen就可以测试的,如果显示正确的pid就成功的。

    完结。