2012-04-19 15 views
9

Tôi khá mới đối với Node.js và tôi có một yêu cầu cho một ứng dụng sẽ nhận được một tải trọng của các gói UDP và xử lý nó.Cách thiết lập máy chủ UDP node.js rất nhanh

Tôi đang nói về hơn 400 thư mỗi giây, có thể đạt tới 200.000 thư/phút.

Tôi đã viết mã để thiết lập máy chủ UDP (được lấy từ tài liệu ở đây http://nodejs.org/api/all.html#all_udp_datagram_sockets thực sự) nhưng nó mất đi khoảng 5% gói.

Điều tôi thực sự cần phát triển là máy chủ sẽ nhận gói và gửi đến một nhân viên khác thực hiện công việc với thư. Nhưng có vẻ như luồng trong node.js là một cơn ác mộng.

Đây là cốt lõi của tôi như là:

var dgram = require("dgram"); 
var fs = require("fs"); 
var stream = fs.createWriteStream("received.json",{ flags: 'w', 
    encoding: "utf8", 
    mode: 0666 }); 

var server = dgram.createSocket("udp4"); 
server.on("message", function (msg, rinfo) { 
    console.log("server got: " + msg + " from " + 
    rinfo.address + ":" + rinfo.port); 
    stream.write(msg); 
}); 

server.on("listening", function() { 
    var address = server.address(); 
    console.log("server listening " + 
     address.address + ":" + address.port); 
}); 

server.bind(41234); 
// server listening 0.0.0.0:41234 
+2

Hãy nhớ rằng datagrams, không giống như TCP socket, không nhận được guarenteed. Thay vào đó, các gói dữ liệu tập trung vào tốc độ, mà không thừa nhận các thông báo riêng lẻ. – skeggse

+0

Đó là những thứ như thế khiến tôi chuyển sang Go và không bao giờ nhìn lại. –

+0

@AParacha Xin hãy giải thích, tôi đang nghe: D –

Trả lời

2

Bạn đang thiếu khái niệm, NodeJS được không có nghĩa là multi-thread về bạn có ý nghĩa, yêu cầu cần được xử lý trong một chu kỳ. Không có chủ đề nào khác tồn tại nên không có chuyển ngữ cảnh nào xảy ra. Trong môi trường đa lõi, bạn có thể tạo một cụm thông qua mô-đun cụm của nút, tôi có một bài đăng trên blog về số này here.

Bạn đặt chế độ dành cho phụ huynh thành quy trình con ngã ba và chỉ các quy trình con sẽ liên kết với cổng. Phụ huynh của bạn sẽ xử lý cân bằng tải giữa trẻ em.

Note: Trong bài viết trên blog của tôi, tôi đã i < os.cpus().length/2; nhưng nó phải là i < os.cpus().length;

+0

Tôi xin lỗi, tôi nghĩ rằng tôi đã không giải thích cho tôi khá tốt, nhưng điều này là: như một khách hàng UDP tôi có thể gửi hơn 10k gói UDP trong một giây, nhưng máy chủ UDP bị thiếu khoảng 5% trong một máy chủ cục bộ đến môi trường cục bộ. Dù sao, máy chủ của tôi đã khá nhạy, nó đáp ứng hơn 1000 (1kb) tin nhắn/giây là đủ cho tôi. – Panthro

+0

Bạn đã viết "Những gì tôi thực sự cần phát triển là một máy chủ sẽ nhận được gói tin và gửi cho một nhân viên khác thực hiện công việc với thông báo", nhưng tôi cho rằng bạn muốn giảm tỷ lệ lỗi 5%? Bạn có thể viết lại câu hỏi của mình không? – Mustafa

0

Tôi đã viết một dịch vụ chuyển tiếp xà phòng/xml có cấu trúc tương tự, và thấy rằng các thông tin sẽ đến trong 2 gói. Tôi cần cập nhật mã của mình để phát hiện 2 nửa thông điệp và đặt chúng lại với nhau. Điều này kích thước tải trọng có thể được nhiều hơn một vấn đề HTTP hơn một vấn đề udp, nhưng đề nghị của tôi là bạn thêm đăng nhập để viết ra tất cả mọi thứ bạn đang nhận được và sau đó đi qua nó với một chiếc lược răng tốt. Có vẻ như bạn sẽ đăng nhập những gì bạn đang nhận được ngay bây giờ, nhưng bạn có thể phải đào sâu vào 5% mà bạn đang mất.

Làm thế nào để bạn biết 5% của nó? nếu bạn gửi lại lưu lượng truy cập đó, nó sẽ luôn luôn là 5%? là các thư giống nhau luôn bị mất.

Tôi đã xây dựng một máy chủ UDP cho dữ liệu cuộc gọi voip/sip sử dụng ruby ​​và Event Machine, và cho đến nay mọi thứ đã hoạt động tốt. (Tôi tò mò về cách tiếp cận thử nghiệm của bạn, mặc dù tôi đã làm mọi thứ trên netcat, hoặc một khách hàng nhỏ ruby, tôi không bao giờ làm 10k tin nhắn)