Scaling Node.js


86

Tôi khá mới đối với phát triển phía máy chủ quy mô lớn. Tôi muốn viết một máy chủ bằng cách sử dụng Node.js, nhưng trước khi bắt đầu, tôi muốn biết các nguyên tắc chung là gì để mở rộng nút lên, chẳng hạn như 20 truy vấn mỗi giây.

Dịch vụ tôi đang viết phần lớn sẽ là một giao diện với cơ sở dữ liệu, cộng với xác thực và xác nhận dữ liệu đầu vào.


Bạn có nghĩa là gì khi "mở rộng nút"? Bắt đầu nhiều quy trình nút?
Thilo

3
20 truy vấn mỗi giây là khá thấp. Node.js sẽ có thể xử lý hàng nghìn kết nối đồng thời. Chỉ cần không xử lý vòng lặp nặng vì nó sẽ chặn toàn bộ trình thông dịch. Nếu so sánh thì trường hợp sử dụng của bạn sẽ khá nhẹ. Trong Node, các kết nối cơ sở dữ liệu được tự động tạo thành các luồng và được xử lý không đồng bộ ở cấp javascript.
slbetman

Câu trả lời:


149

Cân bằng tải

Hầu hết có lẽ đối với các trang web đơn giản nhất, bạn không cần bất kỳ quy mô nào cả. Chỉ một hộp duy nhất sẽ giúp bạn được bảo hiểm. Sau đó, bạn nên thực hiện cân bằng tải như bạn đang đề cập, điều này gần như giống nhau đối với mọi kiến ​​trúc (giống như bạn đang nói rằng bạn có thể bắt đầu nhiều quy trình nút trước. Nhưng khi bạn thực sự lớn, bạn cần nhiều hộp hơn).

Ví dụ về cân bằng tải Nginx :

http {
  upstream myproject {
    server 127.0.0.1:8000 weight=3;
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;    
    server 127.0.0.1:8003;
  }

  server {
    listen 80;
    server_name www.domain.com;
    location / {
      proxy_pass http://myproject;
    }
  }
}

Redis

20 truy vấn mỗi giây

Không có mồ hôi cho node.js. Bạn nên sử dụng redis làm kho dữ liệu của mình vì nó rất nhanh :). Thậm chí còn có thư viện ac cho nút khi bạn sử dụng node_redis .

npm install hiredis redis

Hiredis là thứ mang lại cho bạn hiệu suất kickass vì nó biên dịch thành mã C bên trong nút. Dưới đây là một số điểm chuẩn từ redis khi được sử dụng với Rentis.

PING: 20000 ops 46189.38 ops/sec 1/4/1.082
SET: 20000 ops 41237.11 ops/sec 0/6/1.210
GET: 20000 ops 39682.54 ops/sec 1/7/1.257
INCR: 20000 ops 40080.16 ops/sec 0/8/1.242
LPUSH: 20000 ops 41152.26 ops/sec 0/3/1.212
LRANGE (10 elements): 20000 ops 36563.07 ops/sec 1/8/1.363
LRANGE (100 elements): 20000 ops 21834.06 ops/sec 0/9/2.287

Khi bạn nhìn vào những con số đó thì 20 / s là KHÔNG GÌ :).

Xác thực


Cập nhật:


Tôi đang nói điều này rất nhiều nhưng vì tình yêu của Chúa, xin đừng cố gắng triển khai hệ thống xác thực của riêng bạn. Nó có lẽ sẽ không an toàn (rất nhiều có thể sai), rất nhiều công việc. Để xác thực, bạn nên sử dụng facebook-connect, twitter đăng nhập một lần, v.v. bằng cách sử dụng thư viện connect-auth tuyệt vời . Sau đó, bạn được bảo vệ an toàn vì họ có các chuyên gia kiểm tra ở đó hệ thống đăng nhập để tìm các lỗ hổng và cũng không truyền mật khẩu qua văn bản thuần túy nhưng cảm ơn vì đã sử dụng https. Tôi cũng đã trả lời một chủ đề cho một người dùng muốn sử dụng facebook-connect .

xác nhận dữ liệu đầu vào

Để xác thực đầu vào, bạn có thể sử dụng trình xác thực nút .

var check = require('validator').check,
    sanitize = require('validator').sanitize

//Validate
check('test@email.com').len(6, 64).isEmail();       //Methods are chainable
check('abc').isInt();                               //Throws 'Invalid integer'
check('abc', 'Please enter a number').isInt();      //Throws 'Please enter a number'
check('abcdefghijklmnopzrtsuvqxyz').is(/^[a-z]+$/);

//Sanitize / Filter
var int = sanitize('0123').toInt();                  //123
var bool = sanitize('true').toBoolean();             //true
var str = sanitize(' \s\t\r hello \n').trim();      //'hello'
var str = sanitize('aaaaaaaaab').ltrim('a');        //'b'
var str = sanitize(large_input_str).xss();
var str = sanitize('&lt;a&gt;').entityDecode();     //'<a>'

Ngoài ra còn có thư viện biểu mẫu này để giúp bạn tạo biểu mẫu.


1
@nornagon chào mừng bạn :). Đặc biệt nhớ đừng viết hệ thống đăng nhập của riêng bạn;). Ngoài ra Jeff Atwood (tác giả của Stackoverflow) cũng khuyên bạn nên chống lại nó! => blog.stackoverflow.com/2010/04/openid-one-year-later
Alfred

10
Bạn có thể sử dụng HAProxy để cân bằng tải WebSockets vì nginx sẽ không hoạt động :) Điều này miễn là bạn đang phát triển các ứng dụng yêu cầu bạn sử dụng WebSockets ở đâu đó! Chỉ là một bổ sung cho câu trả lời đã tuyệt vời của @ alfred.
Shripad Krishna

5
Một ví dụ HAProxy thiết lập, trong trường hợp bạn sử dụng WebSockets: stackoverflow.com/questions/4360221/...
Shripad Krishna

9
Câu trả lời tốt. Tuy nhiên, tôi thực sự khuyên bạn nên dùng passport.js thay vì everyauth.
UpTheCreek

1
còn hộ chiếu thay vì everyauth thì sao?
chovy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.