2013-07-25 35 views
5

Tôi đang sử dụng Node.js cho lần đầu tiên và hy vọng cho một lời khuyên:node.js + socket.io + redis kiến ​​trúc - máy chủ ngangcấu hình kết nối socket?

i cài đặt các chương trình sau trên máy chủ của tôi:

  • Node.js v0.11.3-pre
  • nhanh v3.3.4
  • socket.io v0.9.14
  • connect-redis v1.4.5
  • redis máy chủ v = 2.6.14
  • redis -cli 2.6.14

Trước hết, tôi tạo ra một ứng dụng nhanh:

express testApplication 

Trong "package.json" tạo i được xác định tất cả depencies cần thiết.

Ngay từ đầu tôi đã xác định một cụm cho chiều dọc rộng (đa quá trình) trong một tập tin gọi là "cluster.js":

var cluster = require('cluster'); 

if(cluster.isMaster) { 
     var noOfWorkers = process.env.NODE_WORKERS || require('os').cpus().length; 

     console.log("Workers found: " + noOfWorkers); 

     for (var i = 0; i < noOfWorkers; i += 1) { 
       cluster.fork(); 
     } 
} else { 
     require('./app.js'); 
} 

cluster.on('exit', function(worker, code, signal) { 
     var exitCode = worker.process.exitCode; 

     console.log('worker' + worker.process.pid + ' died (' + exitCode + '). restarting...'); 

     if(typeof cluster.workers[worker.id] != "undefined") 
       cluster.workers[worker.id].delete(); 

     cluster.fork(); 
}); 

Trong "app.js" tập tin của tôi được xác định REDIS cho socket. lưu trữ io:

io.set('store', new RedisStore({ 
      redisPub: pub, 
      redisSub: sub, 
      redisClient: client 
      })); 

Cho đến nay, rất tốt, tất cả điều này hoạt động khá tốt.

Khi khách hàng kết nối với máy chủ socket.io, cụm sẽ xử lý các kết nối với các nhân viên khác nhau.

Ý định của tôi là, khách hàng có thể gửi thư đến một khách hàng cụ thể khác, vì vậy máy chủ socket.io phải tìm ổ cắm từ người nhận để gửi thư chỉ cho người dùng này. Giải pháp cho tôi là, tôi lưu trữ tất cả các id socket được tạo cho mỗi người dùng trong một mảng và khi gửi một tin nhắn, tôi chọn các id socket có liên quan trong mảng, lấy các socket bằng id, và gửi tin nhắn tới các socket).

Thao tác này rất tốt cho ứng dụng socket.io, chỉ chạy trên một máy chủ. Bây giờ, tôi muốn cấu hình một máy chủ khác có cùng chương trình, mô-đun và gói. Cân bằng tải có thể sẽ được xử lý bởi HAProxy. Vì vậy, các kết nối socket.io (ổ cắm) sẽ được lưu trữ và quản lý trên Máy chủ AMáy chủ B.

Ví dụ kịch bản:

dùng A kết nối với Server MộtNgười dùng B kết nối với Server B. Điều đó có nghĩa, Người dùng A có một ổ cắm trên Máy chủ A không phải Người dùng B trên Máy chủ B.

Làm thế nào để ứng dụng biết rằng nó phải tìm ổ cắm của Người dùng B trên Máy chủ B để gửi thông điệp? Trên máy chủ A nó sẽ không tìm thấy socket, vì nó được tạo trên Server B.

Thx rất nhiều!

Trả lời

5

Khi bạn đang mở rộng theo chiều ngang, bạn cần chia sẻ kho dữ liệu giữa các máy chủ của mình. Thuận tiện, bạn đã có một lý tưởng, đó là Redis. Thay vì giữ bản đồ socket của bạn trong một mảng, bạn cần phải đẩy nó vào Redis, và tìm kiếm từ đó.

Sau đó, bạn có thể quyết định để máy chủ gửi tin nhắn cho nhau, hoặc, mở rộng hơn, gửi tin nhắn thông qua Redis. Vì vậy, mỗi máy chủ sẽ xem xét hàng đợi của nó trên Redis để xem những thông điệp nào sẽ gửi đến các ổ cắm nào. Khi một máy chủ nhận được một tin nhắn, nó sẽ đẩy nó vào Redis được gửi đến máy chủ sẽ phân phối nó. Nếu thứ tự các thư quan trọng đối với bạn, tôi khuyên bạn nên xem https://github.com/learnboost/kue làm lớp trên cùng của Redis.

+0

@elchueko Bạn có thể đăng một ví dụ về cách bạn giải quyết bằng redis không? – patrick

Các vấn đề liên quan