Using a RDBM as Queue database would be a poor choice for concurrent job. It would cause your DB hand up with thoundsands of connections. Inspite of restarting, It’s not respond until you stop the queue servers that connect to it.
In this post I will help you build a simple, robust Queue worker using database. Few months ago, my boss called me at 4 a.m and said that the system was down and please do something. I quickly opened the AWS RDS dashboard and saw the strange thing. There are tons of database connections but the CPU usage percentage is just few percent. What was that ? It was really made me headache for a month. I made a question in stackoverflow and laracast but still no hope.
Then I deep dive in laravel core framework and find out this piece of code.
Let’s see it more detail using pg_stat_statements
I will explain this snippet : it will pop a job from queue and delivery it to worker service and lock (lockForUpdate()) it while the worker service processing. Some reasons, service worker ‘s not respond, the current job is locked while another worker services begin transaction and wait for executing the next jobs. The result is the connection count grow up dramatically to few thousands.
You even cannot connect to database because there isn’t any slot. I will reproduce this issues as below:
Since PostgreSQL 9.4 release FOR UPDATE … SKIP LOCKED , now I can FIX and rebuild concurrent work queues.
Now, Worker services can get the jobs independently in order and the connection count now is equal workers count and no more connection explosion (y).
And well, That's it . If you have any questions, you can mail me. Thanks for reading!