Weitere ähnliche Inhalte Ähnlich wie Nodejs in Production (20) Mehr von William Bruno Moraes (10) Kürzlich hochgeladen (20) Nodejs in Production4. seja rápido
Seja extremamente rápido, quanto menos tempo de NodeJS sua
aplicação tiver, mais ela irá escalar.
Assíncrono
Single Thread
V8 usa no máximo 1.6GB de RAM por processo
Consome pouca RAM e pouca CPU
6. use Objetos Literais
let AccountController = {
login: function doLogin(request, response, next) {
//..
}
};
module.exports = AccountController;
require() é síncrono, cacheado e singleton
8. não use módulos desnecessários
helmet
lodash/undescore
app.disable('etag');
app.disable('x-powered-by');
outros cabeçalhos no nginx
13. erros num único ponto
Trate os erros num único lugar
app.use(function handleError(err, request, response, next) {
response.status(err.status || 500);
//log
if (request.xhr) {
response.json({ err: err.message });
} else {
response.render('error', {
message: err.message
});
}
});
14. use debug
Não deixe console.log() perdidos no código
Tudo o que vai para o std output escreve no log
17. use a lib bluebird
Mais rápida que a implementação nativa de Promise
Possui o método .promisifyAll()
18. use npm scripts
{
"name": "app",
"scripts": {
"gulp": "gulp; ./scripts.sh akamai; gulp s3",
"jshint": "jshint server/*",
"karma": "./scripts.sh karma",
"nodemon": "nodemon ./server/bin/www",
"patch": "npm version patch -m "release: version %s" && git push --tags && git push",
"start": "./scripts.sh start",
"test": "./scripts.sh test"
},
19. use npm scripts#!/bin/bash
BROWSER=${2:-"PhantomJS"}
case "$1" in
start)
echo 'Starting...'
export DEBUG=blz:*
bower install
npm-run-all --parallel gulp-watch karma
;;
test)
echo 'Testing backend...'
gulp eslint:nodejs
export DEBUG=blz:*
./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha test/nodejs/*
;;
karma)
echo 'Testing frontend...'
gulp eslint:angular
gulp eslint:jquery
./node_modules/karma/bin/karma start --browsers $BROWSER ./test/angular/karma.conf.js
;;
akamai)
echo 'Updating akamai...'
export APPLICATION_VERSION=$(node -e "console.log(require('./package.json').version);")
mkdir -p _akamai/$APPLICATION_VERSION
cp -r dist/public/* _akamai/$APPLICATION_VERSION
chmod 400 akamai.key
scp -i akamai.key -o StrictHostKeyChecking=no -rp _akamai/$APPLICATION_VERSION user@..…upload.akamai.com:/dir/
;;
*)
echo "Usage: {start|akamai|test|karma}"
exit 1
;;
esac
22. https://github.com/wbruno/examples/tree/gh-pages/nodejs-in-production
#!/bin/sh
### BEGIN INIT INFO
# Provides: nodejs init script
# Required-Start: forever node module
# X-Interactive: true
# Short-Description: application initscript
# Description: Uses forever module to running the application
### END INIT INFO
NODE_ENV="{{ enviroment }}"
PORT="3002"
APP_DIR="/var/{{ application }}/dist/server"
NODE_APP="bin/www"
CONFIG_DIR="$APP_DIR/config"
LOG_DIR="/var/log/{{ application }}"
LOG_FILE="$LOG_DIR/app.log"
NODE_EXEC="forever"
###############
USAGE="Usage: $0 {start|stop|restart|status}"
start_app() {
mkdir -p "$LOG_DIR"
echo "Starting node app ..."
PORT="$PORT" NODE_ENV="$NODE_ENV" NODE_CONFIG_DIR="$CONFIG_DIR"
forever start "$APP_DIR/$NODE_APP" 1>"$LOG_FILE" 2>&1 &
}
stop_app() {
forever stop "$APP_DIR/$NODE_APP"
}
status_app() {
forever list
}
restart_app() {
forever restart "$APP_DIR/$NODE_APP"
}
case "$1" in
start)
start_app
;;
stop)
stop_app
;;
restart)
restart_app
;;
status)
status_app
;;
*)
echo $USAGE
exit 1
;;
esac
Unix service
23. https://github.com/wbruno/examples/tree/gh-pages/nodejs-in-production
start on filesystem and started networking
stop on shutdown
expect fork
setuid www-data
env HOME="/var/{{ application }}"
env NODE_ENV="{{ enviroment }}"
env MIN_UPTIME="5000"
env SPIN_SLEEP_TIME="2000"
chdir /var/{{ application }}/dist/server
env APP_EXEC="bin/www"
script
exec forever -a -l $HOME/forever.log --minUptime=$MIN_UPTIME --spinSleepTime=$SPIN_SLEEP_TIME start $APP_EXEC
end script
pre-stop script
exec forever stopall
end script
Ubuntu upstart
24. use o nginx-full
Ótimo web server
Ultra rápido
Assíncrono, não bloqueante
Super configurável
http2 (server push apenas no plus)
25. https://github.com/wbruno/examples/tree/gh-pages/nodejs-in-production
server {
listen 80;
server_name www.{{ domain }};
access_log /var/{{ application }}/www.{{ domain }}-access.log;
error_log /var/{{ application }}/www.{{ domain }}-error.log;
proxy_cache one;
root /var/{{ application }}/dist/public/;
error_page 400 404 414 500 502 503 504 /50x.html;
location /50x.html {
internal;
}
location /api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://nodejs/api;
}
location ~* .(?:ico|css|html|json|js|gif|jpe?g|png|ttf|woff|woff2|svg|eot|txt)$ {
access_log off;
expires 14d;
add_header Pragma public;
add_header Cache-Control "public, mustrevalidate, proxy-revalidate";
root /var/{{ application }}/dist/public;
}
}
location / {
add_header X-Cache-Status $upstream_cache_status;
add_header Strict-Transport-Security
"max-age=1440; includeSubdomains";
expires 60s;
set $mobile ‘@desktop';
if ($http_user_agent ~* "...") {
set $mobile "@tablet";
}
if ($http_user_agent ~* "...") {
set $mobile "@smartphone";
}
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_ignore_headers Cache-Control;
proxy_pass http://nodejs;
proxy_cache_key "$mobile$scheme://$host$request_uri";
proxy_cache_bypass $cookie_nocache $arg_nocache;
proxy_cache_valid 1m;
proxy_cache_min_uses 1;
}
26. https://github.com/wbruno/examples/tree/gh-pages/nodejs-in-production
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 60;
send_timeout 60;
client_body_timeout 60;
client_header_timeout 60;
client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 4 32k;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
default_type application/octet-stream;
log_format elb '$http_x_forwarded_for - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
proxy_cache_path /tmp/cache keys_zone=one:10m loader_threshold=100 loader_files=100 loader_sleep=30 inactive=30m max_size=2g;
charset utf-8;
gzip on;
gzip_disable "msie6";
gzip_min_length 1;
gzip_types *;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_buffers 16 8k;
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
include /etc/nginx/upstreams.d/nodejs;
}
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}