目前我們網站都是寫在 node.js 上,然後用 nginx 當 reverse proxy 來接。
以四核然後有 VT 為例,nproc
看到的會是 8,此時一些相對應的 nginx.conf 設定:
1 2 worker_processes 8 ; worker_cpu_affinity 00010001 00010001 00100010 00100010 01000100 01000100 10001000 10001000 ;
worker_cpu_affinity 的值是按照 /proc/cpuinfo
內容來決定的,用來做範例的機器排列是 processor 0~3 對應到 core 0~3,然後 processor 4~7 又對應到 core 0~3,所以 processor [0, 4], [1, 5], [2, 6], [3, 7] 各自屬於同一個 core。同一個 core 可以允許 processes 互換,所以上面 worker_cpu_affinity 的意思是指定 worker 0 可以跑在 0, 4 兩個 CPU 上(第 0 跟第 4 bit 為 1),然後 worker 1 也是跑在 0, 4 上面。依此類推。
node.js 部份並沒有用 forever 來跑,而是用 upstart 來看住。相關的一些設定長這樣:
1 2 3 4 5 6 7 8 9 10 11 12 start on runlevel [2345] task script NPROC =$(nproc) for N in $(seq $NPROC ); do start portal-worker N =$N done end script
用 portal 去跑好幾個 portal-worker 起來。而 portal-worker 則是會看執行時給的 N 值來決定怎麼跑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 manual respawn instance $N env NODE_ENV =production setuid www-data setgid www-data chdir /home/johndoe/portal script test $N = 1 && exec taskset 0x11 node server.js -c config-1 test $N = 2 && exec taskset 0x11 node server.js -c config-2 test $N = 3 && exec taskset 0x22 node server.js -c config-3 test $N = 4 && exec taskset 0x22 node server.js -c config-4 test $N = 5 && exec taskset 0x44 node server.js -c config-5 test $N = 6 && exec taskset 0x44 node server.js -c config-6 test $N = 7 && exec taskset 0x88 node server.js -c config-7 test $N = 8 && exec taskset 0x88 node server.js -c config-8 end script
portal-worker 的 log 都會在 /var/log/upstart
底下,例如 N=1 時,就會是 /var/log/upstart/portal-worker-1.log。另外可以看到 taskset 的邏輯基本上跟 worker_cpu_affinity 是一樣的。後面 -c 是自訂參數,用來指定不同設定檔,例如規定 node process 聽在不同的 port 上。這樣搭配 nginx 裡頭 upstream 功能就可以平均分配:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 upstream portal { server 127.0 .0 .1 :5001 ; server 127.0 .0 .1 :5002 ; server 127.0 .0 .1 :5003 ; server 127.0 .0 .1 :5004 ; server 127.0 .0 .1 :5005 ; server 127.0 .0 .1 :5006 ; server 127.0 .0 .1 :5007 ; server 127.0 .0 .1 :5008 ; } server { # ...snipped... location / { proxy_pass http: proxy_redirect default ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $hostname; proxy_set_header X-Forwarded-Proto $scheme; } }
值得注意的是,upstart 在 12.04 有個 bug,Supplementary groups not set for user jobs ,這會導致上面的 setuid www-data 不如預期,例如 user www-data 的 supplementary group 有一個 groupabc,然後某檔案設定為 groupabc 可以寫,結果 upstart 跑起來以後是寫不進去的。 解法之一是改用 sudo -u www-data -E --
來跑。14.04 就沒這問題了。