ruby-amqp / bunny

Bunny is a popular, easy to use, mature Ruby client for RabbitMQ
Other
1.39k stars 304 forks source link

Few questions regarding highload use and thread-safety #283

Closed nateless closed 9 years ago

nateless commented 9 years ago

Hello,

I think that's not the right place to ask questions, however I couldn't find answers in documentation. And they are too specific for stackoverflow.

We've been using redis's pubsub in a threaded environment. It's a very concurrent app with high load, hundreds users online connected with websocket, each user runs new threads to get realtime updates. However app started to freeze randomly, with threads leaking and deadlocks, while we investigate it and discuss in redis-rb, I've decided to switch redis to something more stable like RabbitMQ and bunny.

However I've few questions regarding thread-safety.

  1. First of all we initialize global connection in initialize file. Is it safe to use global connection?
$rabbit = Bunny.new('amqp://guest:guest@localhost:5672')
$rabbit.start
  1. We publish data from different places for different queues. So the question is can we reuse channel = $rabbit.create_channel channel or it's better to create a new one for each method call? Also should we close channels and exchangers after usage? Considering its a websocket app which has a long run, user can call #stats method hundreds of times under one connection.
    def stats
        data = ...
        channel = $rabbit.create_channel
        x  = channel.fanout("stats")
        x.publish(data)
    end
  1. When clients connects we create a new thread to subscribe him to different queues. Consider it's a websocket it can throw an exception at any given moment and close the connection. With Redis we had to open new connection for each client as psubscribe blocks the thread and it goes to deadlock by some reason we haven't figured out yet. Is it safe to reuse our global connection or its better to open a new one for each client?
michaelklishin commented 9 years ago

It should be fine to share a connection. No need to create a channel per message published (that's a network round trip with a lock), so as long as the channel is open, just use it (one channel per thread — never share channels).

Is it safe to reuse our global connection or its better to open a new one for each client?

See above. Unless you have specific reasons, start with using just 1 connection.

We'd appreciate if questions were directed to ruby-amqp and rabbitmq-users Google groups in the future. Thank you.