Весы Gevent Socketio
В настоящее время у меня есть настройка сайта с использованием Django. Я добавил Gevent Socketio, чтобы добавить функцию чата. Мне нужно его масштабировать, так как на сайте уже довольно много пользователей, и я не могу найти способ сделать это.
Я попробовал https://github.com/abourget/gevent-socketio/tree/master/examples/django_chat/chat
Я использую Gunicorn & the socketio.sgunicorn.GeventSocketIOWorker
рабочий класс, поэтому сначала я подумал об увеличении числа рабочих. К сожалению, это, кажется, периодически прерывается. Я начал переписывать его, чтобы использовать redis из нескольких найденных мной источников и иметь по 1 работника на каждом сервере, который в настоящее время сбалансирован по нагрузке. Однако это, похоже, та же проблема. Мне интересно, есть ли какая-то проблема в самом коде gevent socketio, которая не позволяет его масштабировать.
Вот как я начал, это просто код отправки сообщения.
def redis_client():
"""Get a redis client."""
return Redis(settings.REDIS_HOST, settings.REDIS_PORT, settings.REDIS_DB)
class PubSub(object):
"""
Very simple Pub/Sub pattern wrapper
using simplified Redis Pub/Sub functionality.
Usage (publisher)::
import redis
r = redis.Redis()
q = PubSub(r, "channel")
q.publish("test data")
Usage (listener)::
import redis
r = redis.Redis()
q = PubSub(r, "channel")
def handler(data):
print "Data received: %r" % data
q.subscribe(handler)
"""
def __init__(self, redis, channel="default"):
self.redis = redis
self.channel = channel
def publish(self, data):
self.redis.publish(self.channel, simplejson.dumps(data))
def subscribe(self, handler):
redis = self.redis.pubsub()
redis.subscribe(self.channel)
for data_raw in redis.listen():
if data_raw['type'] != "message":
continue
data = simplejson.loads(data_raw["data"])
handler(data)
from socketio.namespace import BaseNamespace
from socketio.sdjango import namespace
from supremo.utils import redis_client, PubSub
from gevent import Greenlet
@namespace('/chat')
class ChatNamespace(BaseNamespace):
nicknames = []
r = redis_client()
q = PubSub(r, "channel")
def initialize(self):
# Setup redis listener
def handler(data):
self.emit('receive_message',data)
greenlet = Greenlet.spawn(self.q.subscribe, handler)
def on_submit_message(self,msg):
self.q.publish(msg)
1 ответ
Я использовал части кода из https://github.com/fcurella/django-push-demo и gevent-socketio 0.3.5rc1 вместо rc2, и теперь он работает с несколькими работниками и балансировкой нагрузки.