Pull to refresh

Node.JS: Пример HTTP-сервера в режиме prefork с использованием Web Workers

Reading time 2 min
Views 8.4K
Original author: Peter Griess
Как обещал ранее, я публикую исходный код, демонстрирующий, как построить HTTP-сервер в режиме prefork, используя Web Workers и новый API net.Server.listenFD(). Я надеюсь, что этот код будет хорошим примером того, как легко нагрузить несколько ядер сервера, комбинируя пересылку файловых дескрипторов и Web Workers.

В master.js мы создаём сокет, прикрепленный к порту 8080, и порождаем 4 рабочих процесса для обработки запросов. Мы отправляем сообщение каждому обработчику со текстом, которую нужно будет использовать для всех ответов на запросы, а также файловый дескриптор нашего сокета.

  1. var path = require('path');
  2. var netBindings = process.binding('net');
  3. var Worker = require('webworker').Worker;
  4.  
  5. var fd = netBindings.socket('tcp4');
  6. netBindings.bind(fd, 8080);
  7. netBindings.listen(fd, 128);
  8.  
  9. for (var i = 0; i < 3; i++) {
  10.     var w = new Worker(path.join(__dirname, 'worker.js'));
  11.     w.postMessage({ 'banner' : 'Hello, world!' }, fd);
  12. }


В worker.js мы создаём экземпляр HTTP-сервера, но не вызываем listen(). Вместо этого мы ожидаем принятия сообщений от родительского процесса. При получении события иы забираем файловый дескриптор из сообщения и используем его для привязки нашего экземпляра http.Server к сокету. Как только будет вызван http.Server.listenFD(), этот процесс начнёт обрабатывать запросы.

  1. var assert = require('assert');
  2. var http = require('http');
  3.  
  4. var banner = undefined;
  5.  
  6. var srv = http.createServer(function(req, resp) {
  7.     resp.writeHead(200, {'Content-Type' : 'text/plain'});
  8.     resp.write(banner + ' (pid ' + process.pid + ')\n');
  9.     resp.end();
  10. });
  11.  
  12. onmessage = function(msg) {
  13.     assert.ok(msg.fd && msg.fd > 0);
  14.  
  15.     banner = msg.data.banner;
  16.  
  17.     srv.listenFD(msg.fd);
  18. };


Когда мы запускаем master.js, мы можем использовать curl для проверки, что запросы были обработаны разными процессами.

  1. % curl 'http://localhost:8080'
  2. Hello, world! (pid 27727)
  3. % curl 'http://localhost:8080'
  4. Hello, world! (pid 27728)
  5. % curl 'http://localhost:8080'
  6. Hello, world! (pid 27729)
  7. % curl 'http://localhost:8080'
  8. Hello, world! (pid 27727)


Очень просто.
Tags:
Hubs:
+27
Comments 28
Comments Comments 28

Articles