Jak zaprojektować redis pub / sub dla systemu komunikatorów?
Jestem nowy w redis pub / sub. Mam czat w systemie, który jest jak im. Więc chciałbym użyć redis pub / sub. Ponieważ zbadałem próbki, większość z nich została zaprojektowana w oparciu o Czat. W moim systemie będę miał wiele czatów między użytkownikami jak;
A:B
A:C
D:C
E:F
/ Align = "center" bgcolor = "# e0ffe0 " / cesarz chin / / align = center / I zaimplementowałem serwer z węzłem.js jak poniżej;
var store = redis.createClient();
var pub = redis.createClient();
io.sockets.on('connection', function (socket) {
var sub = redis.createClient();
sub.on("message", function(pattern, data){
data = JSON.parse(data);
socket.send(JSON.stringify({ type: "chat", key: pattern, nick: data.nickname, message: data.text }))
}
});
socket.on('message', function (messageData) {
store.incr("messageNextId", function(e, messageId) {
var room = ""
var from = messageData.clientId > socket.nickname ? socket.nickname : messageData.clientId;
var to = messageData.clientId < socket.nickname ? socket.nickname : messageData.clientId;
room = from + ":" + to;
var message = { id: messageId, nickname: socket.nickname, text: messageData.text };
store.rpush("rooms:" + room, JSON.stringify(message), function(e, r) {
pub.publish(room, JSON.stringify(message))
});
});
});
Jak widzisz, tworzę nowego abonenta redis dla każdego połączenia. W innym czacie próbki redis klient Abonenta jest tworzony globalnie. I istnieją tylko trzy połączenia przez cały czas i to rozwiązuje ich problem, ponieważ kiedy wydawca publikuje wiadomość, wszyscy podłączeni klienci powinni ją otrzymać. Ale mam tu pewne ograniczenia. Chcę otworzyć sesję czatu między dwoma użytkownikami i tylko ci użytkownicy powinni być subskrybentami. Powyższy kod działa tak, jak chciałbym, ale nie wiem, czy redis jest w porządku, aby utworzyć nowego klienta Abonenta dla każdego połączenia.
To miło będzie usłyszeć Twoje sugestie. Z góry dzięki.
1 answers
Jak zawsze, musisz porównywać takie rzeczy do własnego użytku-nie można udzielać ogólnych porad. Może być konieczne zwiększenie maksymalnej liczby otwartych plików w systemie, zarówno dla całego systemu, jak i dla użytkownika redis. Dotyczy to oczywiście również użytkownika prowadzącego Twój serwer WWW.
To powiedziawszy, powinieneś upewnić się, że słuchasz socket.on('disconnect')
i quit()
Abonenta redis, gdy użytkownik odchodzi. Możesz być również zainteresowany, aby wiedzieć, że socket.io posiada zaplecze redis, który wykorzystuje redis pub / sub, a także ma koncepcję pokoi, więc możesz zaoszczędzić sobie kłopotów, używając tego, ponieważ już zależy od socket.io.
Edit: Po szybkim sprawdzeniu dostaję komunikat o błędzie z Redis po 991 subskrybentach:
Ready check failed: Error: Error: ERR max number of clients reached
Tutaj jest z domyślnego redis.conf
:
# Set the max number of connected clients at the same time. By default
# this limit is set to 10000 clients, however if the Redis server is not
# able ot configure the process file limit to allow for the specified limit
# the max number of allowed clients is set to the current file limit
# minus 32 (as Redis reserves a few file descriptors for internal uses).
#
# Once the limit is reached Redis will close all the new connections sending
# an error 'max number of clients reached'.
#
# maxclients 10000
Mój system (Ubuntu 11.11) ma domyślny nofile
limit 1024, więc mój szybki test powinien zawieść po 992 połączonych klientach, co wydaje się być w porządku z testu (mam też jednego klienta dla wydawcy). Moja sugestia dla ciebie to sprawdzenie swojego nofile
limitu (w moim systemie jest to w /etc/security/limits.{conf,d/*}
i twoje ustawienie redis maxclients
, a następnie benchmark, benchmark, benchmark!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-13 15:02:19