Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JSDC.TW 2013 Node.js佈署心得

JSDC.TW 2013 Node.js佈署心得

forever, node.js garbage collection, nginx

Steven Su

May 18, 2013
Tweet

More Decks by Steven Su

Other Decks in Programming

Transcript

  1. Nodejs Deployment

    View full-size slide

  2. Steven, xpsteven, XP
    http://about.me/xpsteven

    View full-size slide

  3. http://fandora.tw/
    http://shop.fandora.tw/

    View full-size slide

  4. Easier async - flow control 的原理、應用、實作及展望

    View full-size slide

  5. 蝦米!難道不能關機!

    View full-size slide

  6. 初心者
    node app.js

    View full-size slide

  7. 初心者
    node app.js
    資深初心者
    node app.js &

    View full-size slide

  8. 初心者
    node app.js
    資深初心者
    node app.js &
    冒險者
    while:
    do
    node app.js
    done

    View full-size slide

  9. 初心者
    node app.js
    資深初心者
    node app.js &
    冒險者
    while:
    do
    node app.js
    done
    懶惰者
    npm install forever
    forever start app.js
    forever list
    forever stop app.js
    https://github.com/nodejitsu/forever

    View full-size slide

  10. 如何把code放到server?

    View full-size slide

  11. git pull
    forever stop app.js
    forever start app.js

    View full-size slide

  12. GC - Garbage Collection

    View full-size slide

  13. To ensure fast object allocation, short garbage collection pauses, and no memory
    fragmentation V8 employs a stop-the-world, generational, accurate, garbage collector. This
    means that V8:
    ● stops program execution when performing a garbage collection cycle.
    ● processes only part of the object heap in most garbage collection cycles. This minimizes
    the impact of stopping the application.
    ● always knows exactly where all objects and pointers are in memory. This avoids falsely
    identifying objects as pointers which can result in memory leaks.
    https://developers.google.com/v8/design

    View full-size slide

  14. 空間換取時間 時間換取空間

    View full-size slide

  15. ubuntu@server1:~$ node --v8-options
    ...
    --gc_global (always perform global GCs)
    type: bool default: false
    --gc_interval (garbage collect after allocations)
    type: int default: -1
    ...

    View full-size slide

  16. #!/bin/bash
    # /usr/bin/nodex
    node --gc_global $1

    View full-size slide

  17. 為何我的NODE跑不快?

    View full-size slide

  18. node app.js
    ab -n 400 -c 4 http://localhost:3001/
    Requests per second: 20.14 [#/sec] (mean)
    Time per request: 198.607 [ms] (mean)
    Transfer rate: 614.08 [Kbytes/sec] received
    Percentage of the requests served within a certain time (ms)
    50% 197
    66% 217
    75% 233
    80% 242
    90% 266
    95% 297
    98% 326
    99% 341
    100% 391 (longest request)
    NODE_ENV=production node app.js
    ab -n 400 -c 4 http://localhost:3001/
    Requests per second: 24.84 [#/sec] (mean)
    Time per request: 161.041 [ms] (mean)
    Transfer rate: 790.19 [Kbytes/sec] received
    Percentage of the requests served within a certain time (ms)
    50% 150
    66% 174
    75% 193
    80% 201
    90% 233
    95% 259
    98% 296
    99% 312
    100% 343 (longest request)
    在production下樣板引擎會將樣板變成函數放在記憶體裡

    View full-size slide

  19. 最終版伺服器啟動腳本
    git pull
    forever stop app.js
    NODE_ENV=production forever -c nodex start app.js

    View full-size slide

  20. port 80 or port 3001
    ?

    View full-size slide

  21. server {
    listen 80;
    server_name shop.fandora.tw;
    location / {
    proxy_pass http://localhost:3001;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto http;
    proxy_http_version 1.1;
    }
    }
    app.enable('trust proxy');

    View full-size slide

  22. More
    cluster2 https://github.com/ql-io/cluster2 並列化
    supervisor https://github.com/isaacs/node-supervisor 自動監控變化重新啟動

    View full-size slide

  23. More
    cluster2 https://github.com/ql-io/cluster2 並列化
    supervisor https://github.com/isaacs/node-supervisor 自動監控變化重新啟動
    但建議不要用micor-instance

    View full-size slide

  24. 動態產生不同Size的圖片

    View full-size slide

  25. solution 1

    node+graphicsmagick

    http://aheckmann.github.io/gm/

    Cloudfront+S3
    ● 上傳時就編譯好多種尺寸
    ● 優點
    ○ 速度快
    ● 缺點
    ○ 上傳慢
    ○ 如果以後要不同規格要寫批次檔
    ○ 編譯時很吃記憶體

    View full-size slide

  26. solution 2

    Cloudfront+EC2+S3
    ● 保留原始檔或單一壓縮檔到S3

    Cloudfront將Request導向EC2

    EC2上跑node動態產生縮圖
    ● 優點
    ○ 上傳變快了
    ○ 節省空間
    ● 缺點
    ○ 速度超慢,miss時約需8s
    ○ 記憶體要求高,會crash

    View full-size slide

  27. solution 3

    Cloudfront+Nginx+S3
    ● 保留原始檔或單一壓縮檔到S3

    Cloudfront將Request導向Nginx

    Nginx的image_filter模組動態產生縮圖
    ● 優點

    in-memory 縮圖 大幅提升效能
    ● 缺點
    ○ 沒有缺點 :P

    View full-size slide

  28. server {
    listen 80;
    server_name image.shop.fandora.tw;
    location ~ ^/([0-9]+)/(.*)$ {
    set $width $1;
    set $path $2;
    rewrite ^ /$path break;
    proxy_pass http://fantist-images-oregon-v1.s3-us-west-2.amazonaws.com;
    image_filter resize $width -;
    image_filter_buffer 20M;
    image_filter_jpeg_quality 95;
    expires 5d;
    }
    }
    http://cdn2.shop.fandora.tw/$width/$s3path
    http://image.shop.fandora.tw/$width/$s3path

    View full-size slide