reinstate nginx, use it in development, add smare concurrency settings
This commit is contained in:
parent
6cc0e6139f
commit
e03f79513a
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -1,9 +1,14 @@
|
||||||
config/travis.yml
|
config/travis.yml
|
||||||
config/database.yml
|
config/database.yml
|
||||||
.yardoc
|
config/nginx.conf
|
||||||
log/
|
|
||||||
vendor
|
|
||||||
config/skylight.yml
|
config/skylight.yml
|
||||||
|
|
||||||
|
tmp/
|
||||||
|
log/
|
||||||
|
logs/
|
||||||
|
|
||||||
|
vendor
|
||||||
|
|
||||||
|
.yardoc
|
||||||
.coverage
|
.coverage
|
||||||
*.env
|
*.env
|
||||||
tmp
|
|
||||||
|
|
|
@ -1,3 +1,89 @@
|
||||||
#!/bin/sh
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
"$@"
|
# make sure we kill all child processes once done
|
||||||
|
trap '{ pkill -P $$; rm -f config/nginx.conf; exit 255; }' EXIT
|
||||||
|
|
||||||
|
if [[ $RACK_ENV == "production" ]]; then
|
||||||
|
export tmp_dir=/tmp
|
||||||
|
else
|
||||||
|
mkdir -p tmp
|
||||||
|
export tmp_dir=./tmp
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f bin/nginx ]; then
|
||||||
|
nginx=bin/nginx
|
||||||
|
else
|
||||||
|
which nginx &>/dev/null || { echo "nginx not found" && exit 1; }
|
||||||
|
nginx=nginx
|
||||||
|
fi
|
||||||
|
|
||||||
|
psmgr=$tmp_dir/nginx-buildpack-wait
|
||||||
|
rm -f $psmgr
|
||||||
|
mkfifo $psmgr
|
||||||
|
|
||||||
|
#Evaluate config to get $PORT
|
||||||
|
erb config/nginx.conf.erb > config/nginx.conf
|
||||||
|
|
||||||
|
n=1
|
||||||
|
while getopts :f option ${@:1:2}
|
||||||
|
do
|
||||||
|
case "${option}"
|
||||||
|
in
|
||||||
|
f) FORCE=$OPTIND; n=$((n+1));;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
#Initialize log directory.
|
||||||
|
mkdir -p logs/nginx
|
||||||
|
touch logs/nginx/access.log logs/nginx/error.log
|
||||||
|
echo 'buildpack=nginx at=logs-initialized'
|
||||||
|
|
||||||
|
#Start log redirection.
|
||||||
|
(
|
||||||
|
#Redirect NGINX logs to stdout.
|
||||||
|
tail -qF -n 0 logs/nginx/*.log
|
||||||
|
echo 'logs' >$psmgr
|
||||||
|
) &
|
||||||
|
|
||||||
|
#Start App Server
|
||||||
|
(
|
||||||
|
#Take the command passed to this bin and start it.
|
||||||
|
#E.g. bin/start-nginx bundle exec unicorn -c config/unicorn.rb
|
||||||
|
COMMAND=${@:$n}
|
||||||
|
echo "buildpack=nginx at=start-app cmd=$COMMAND"
|
||||||
|
$COMMAND
|
||||||
|
echo 'app' >$psmgr
|
||||||
|
) &
|
||||||
|
|
||||||
|
if [[ -z "$FORCE" ]]
|
||||||
|
then
|
||||||
|
FILE="$tmp_dir/app-initialized"
|
||||||
|
|
||||||
|
#We block on app-initialized so that when NGINX binds to $PORT
|
||||||
|
#are app is ready for traffic.
|
||||||
|
while [[ ! -f "$FILE" ]]
|
||||||
|
do
|
||||||
|
echo 'buildpack=nginx at=app-initialization'
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo 'buildpack=nginx at=app-initialized'
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Start NGINX
|
||||||
|
(
|
||||||
|
#We expect nginx to run in foreground.
|
||||||
|
#We also expect a socket to be at $tmp_dir/nginx.socket.
|
||||||
|
echo 'buildpack=nginx at=nginx-start'
|
||||||
|
$nginx -p . -c config/nginx.conf
|
||||||
|
echo 'nginx' >$psmgr
|
||||||
|
) &
|
||||||
|
|
||||||
|
#This read will block the process waiting on a msg to be put into the fifo.
|
||||||
|
#If any of the processes defined above should exit,
|
||||||
|
#a msg will be put into the fifo causing the read operation
|
||||||
|
#to un-block. The process putting the msg into the fifo
|
||||||
|
#will use it's process name as a msg so that we can print the offending
|
||||||
|
#process to stdout.
|
||||||
|
read exit_process <$psmgr
|
||||||
|
echo "buildpack=nginx at=exit process=$exit_process"
|
||||||
|
exit 1
|
||||||
|
|
76
config/mime.types
Normal file
76
config/mime.types
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
types {
|
||||||
|
text/html html htm shtml;
|
||||||
|
text/css css;
|
||||||
|
text/xml xml;
|
||||||
|
text/cache-manifest manifest appcache;
|
||||||
|
image/gif gif;
|
||||||
|
image/jpeg jpeg jpg;
|
||||||
|
application/x-javascript js;
|
||||||
|
application/atom+xml atom;
|
||||||
|
application/rss+xml rss;
|
||||||
|
|
||||||
|
text/mathml mml;
|
||||||
|
text/plain txt;
|
||||||
|
text/vnd.sun.j2me.app-descriptor jad;
|
||||||
|
text/vnd.wap.wml wml;
|
||||||
|
text/x-component htc;
|
||||||
|
|
||||||
|
image/png png;
|
||||||
|
image/tiff tif tiff;
|
||||||
|
image/vnd.wap.wbmp wbmp;
|
||||||
|
image/x-icon ico;
|
||||||
|
image/x-jng jng;
|
||||||
|
image/x-ms-bmp bmp;
|
||||||
|
image/svg+xml svg;
|
||||||
|
|
||||||
|
application/java-archive jar war ear;
|
||||||
|
application/mac-binhex40 hqx;
|
||||||
|
application/msword doc;
|
||||||
|
application/pdf pdf;
|
||||||
|
application/postscript ps eps ai;
|
||||||
|
application/rtf rtf;
|
||||||
|
application/vnd.ms-excel xls;
|
||||||
|
application/vnd.ms-powerpoint ppt;
|
||||||
|
application/vnd.wap.wmlc wmlc;
|
||||||
|
application/vnd.google-earth.kml+xml kml;
|
||||||
|
application/vnd.google-earth.kmz kmz;
|
||||||
|
application/x-7z-compressed 7z;
|
||||||
|
application/x-cocoa cco;
|
||||||
|
application/x-java-archive-diff jardiff;
|
||||||
|
application/x-java-jnlp-file jnlp;
|
||||||
|
application/x-makeself run;
|
||||||
|
application/x-perl pl pm;
|
||||||
|
application/x-pilot prc pdb;
|
||||||
|
application/x-rar-compressed rar;
|
||||||
|
application/x-redhat-package-manager rpm;
|
||||||
|
application/x-sea sea;
|
||||||
|
application/x-shockwave-flash swf;
|
||||||
|
application/x-stuffit sit;
|
||||||
|
application/x-tcl tcl tk;
|
||||||
|
application/x-x509-ca-cert der pem crt;
|
||||||
|
application/x-xpinstall xpi;
|
||||||
|
application/xhtml+xml xhtml;
|
||||||
|
application/zip zip;
|
||||||
|
|
||||||
|
application/octet-stream bin exe dll;
|
||||||
|
application/octet-stream deb;
|
||||||
|
application/octet-stream dmg;
|
||||||
|
application/octet-stream eot;
|
||||||
|
application/octet-stream iso img;
|
||||||
|
application/octet-stream msi msp msm;
|
||||||
|
|
||||||
|
audio/midi mid midi kar;
|
||||||
|
audio/mpeg mp3;
|
||||||
|
audio/ogg ogg;
|
||||||
|
audio/x-realaudio ra;
|
||||||
|
|
||||||
|
video/3gpp 3gpp 3gp;
|
||||||
|
video/mpeg mpeg mpg;
|
||||||
|
video/quicktime mov;
|
||||||
|
video/x-flv flv;
|
||||||
|
video/x-mng mng;
|
||||||
|
video/x-ms-asf asx asf;
|
||||||
|
video/x-ms-wmv wmv;
|
||||||
|
video/x-msvideo avi;
|
||||||
|
}
|
45
config/nginx.conf.erb
Normal file
45
config/nginx.conf.erb
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
daemon off;
|
||||||
|
#Heroku dynos have at least 4 cores.
|
||||||
|
worker_processes <%= ENV['NGINX_WORKERS'] || ENV['WEB_CONCURRENCY'] || 4 %>;
|
||||||
|
|
||||||
|
events {
|
||||||
|
<% if `uname` != "Darwin\n" %>use epoll;<% end %>
|
||||||
|
accept_mutex on;
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
gzip on;
|
||||||
|
gzip_comp_level 2;
|
||||||
|
gzip_min_length 512;
|
||||||
|
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
log_format l2met 'measure#nginx.service=$request_time request_id=$http_x_request_id';
|
||||||
|
access_log logs/nginx/access.log l2met;
|
||||||
|
error_log logs/nginx/error.log;
|
||||||
|
|
||||||
|
include mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
sendfile on;
|
||||||
|
|
||||||
|
#Must read the body in 5 seconds.
|
||||||
|
client_body_timeout 5;
|
||||||
|
|
||||||
|
upstream app_server {
|
||||||
|
server unix:<%= ENV["tmp_dir"] %>/nginx.socket fail_timeout=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen <%= ENV["PORT"] %>;
|
||||||
|
server_name _;
|
||||||
|
keepalive_timeout 5;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_pass http://app_server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,8 +2,7 @@ root = File.expand_path('../..', __FILE__)
|
||||||
|
|
||||||
rackup "#{root}/config.ru"
|
rackup "#{root}/config.ru"
|
||||||
|
|
||||||
bind 'unix:///tmp/nginx.socket'
|
bind "unix://#{ENV["tmp_dir"]}/nginx.socket"
|
||||||
|
|
||||||
environment ENV['RACK_ENV'] || 'development'
|
environment ENV['RACK_ENV'] || 'development'
|
||||||
|
|
||||||
threads 0, 16
|
threads 0, 16
|
||||||
|
|
7
config/ruby_config.sh
Normal file
7
config/ruby_config.sh
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
export RUBY_HEAP_MIN_SLOTS=800000
|
||||||
|
export RUBY_GC_HEAP_INIT_SLOTS=$RUBY_HEAP_MIN_SLOTS
|
||||||
|
export RUBY_GC_MALLOC_LIMIT=59000000
|
||||||
|
export RUBY_HEAP_SLOTS_INCREMENT=10000
|
||||||
|
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
|
||||||
|
export RUBY_HEAP_FREE_MIN=100000
|
|
@ -1,19 +1,15 @@
|
||||||
# http://michaelvanrooijen.com/articles/2011/06/01-more-concurrency-on-a-single-heroku-dyno-with-the-new-celadon-cedar-stack/
|
# http://michaelvanrooijen.com/articles/2011/06/01-more-concurrency-on-a-single-heroku-dyno-with-the-new-celadon-cedar-stack/
|
||||||
|
|
||||||
worker_processes 4 # amount of unicorn workers to spin up
|
worker_processes Integer(ENV.fetch('WEB_CONCURRENCY')) # amount of unicorn workers to spin up
|
||||||
timeout 30 # restarts workers that hang for 15 seconds
|
timeout 30 # restarts workers that hang for 30 seconds
|
||||||
|
|
||||||
listen '/tmp/nginx.socket', backlog: 1024
|
listen File.expand_path("nginx.socket", ENV["tmp_dir"]), backlog: 1024
|
||||||
|
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
before_fork do |server, worker|
|
before_fork do |server, worker|
|
||||||
FileUtils.touch('/tmp/app-initialized')
|
# preload travis so we can have copy on write
|
||||||
end
|
require 'travis/api/app'
|
||||||
|
|
||||||
before_exec do |server|
|
# signal to nginx we're ready
|
||||||
ENV['RUBY_HEAP_MIN_SLOTS']=800000
|
FileUtils.touch("#{ENV["tmp_dir"]}/app-initialized")
|
||||||
ENV['RUBY_GC_MALLOC_LIMIT']=59000000
|
|
||||||
ENV['RUBY_HEAP_SLOTS_INCREMENT']=10000
|
|
||||||
ENV['RUBY_HEAP_SLOTS_GROWTH_FACTOR']=1
|
|
||||||
ENV['RUBY_HEAP_FREE_MIN']=100000
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,19 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
[ $PORT ] || PORT=3000
|
|
||||||
[ $RACK_ENV ] || RACK_ENV=development
|
|
||||||
|
|
||||||
cmd="ruby -I lib -S bundle exec ruby -I lib -S unicorn config.ru -p $PORT -E $RACK_ENV -c config/unicorn.rb"
|
. config/ruby_config.sh
|
||||||
[[ $RACK_ENV == "development" ]] && exec rerun "$cmd -l 127.0.0.1:$PORT"
|
|
||||||
|
[ $PORT ] || export PORT=3000
|
||||||
|
[ $RACK_ENV ] || export RACK_ENV=development
|
||||||
|
[ $WEB_CONCURRENCY ] || export WEB_CONCURRENCY=$(script/web_concurrency)
|
||||||
|
[ $NGINX_WORKERS ] || export NGINX_WORKERS=$(script/web_concurrency --nginx)
|
||||||
|
|
||||||
|
echo "port=$PORT rack_env=$RACK_ENV web_concurrency=$WEB_CONCURRENCY nginx_workers=$NGINX_WORKERS"
|
||||||
|
|
||||||
|
ruby="ruby -I lib -S"
|
||||||
|
bexc="$ruby bundle exec"
|
||||||
|
|
||||||
|
cmd="unicorn config.ru -E $RACK_ENV -c config/unicorn.rb"
|
||||||
|
[[ $RACK_ENV == "development" ]] && cmd="rerun -b -- $cmd"
|
||||||
|
cmd="bin/start-nginx $bexec je $cmd"
|
||||||
exec $cmd
|
exec $cmd
|
||||||
|
|
33
script/web_concurrency
Executable file
33
script/web_concurrency
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
#!/usr/bin/env ruby --disable=gems --disable=rubyopt
|
||||||
|
GC.disable
|
||||||
|
|
||||||
|
module System
|
||||||
|
extend self
|
||||||
|
def cpu_count
|
||||||
|
return Java::Java.lang.Runtime.getRuntime.availableProcessors if defined? Java::Java
|
||||||
|
return File.read('/proc/cpuinfo').scan(/^processor\s*:/).size if File.exist? '/proc/cpuinfo'
|
||||||
|
require 'win32ole'
|
||||||
|
WIN32OLE.connect("winmgmts://").ExecQuery("select * from Win32_ComputerSystem").NumberOfProcessors
|
||||||
|
rescue LoadError
|
||||||
|
Integer `sysctl -n hw.ncpu 2>/dev/null` rescue 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ENV['DYNO']
|
||||||
|
# we're on Heroku
|
||||||
|
case `uname -u`.to_i
|
||||||
|
when 256 then concurrency = 2 # 1x dyno
|
||||||
|
when 512 then concurrency = 4 # 2x dyno
|
||||||
|
when 32768 then concurrency = 16 # px dyno
|
||||||
|
else $stderr.puts "Unkown dyno type, selecting concurrency of 4, because"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
case ENV['RACK_ENV'] || 'development'
|
||||||
|
when 'production' then concurrency ||= System.cpu_count
|
||||||
|
when 'development' then concurrency ||= 2 # use at least two so we can be sure things work concurrencly
|
||||||
|
else concurrency ||= 1
|
||||||
|
end
|
||||||
|
|
||||||
|
concurrency = System.cpu_count if ARGV[0] == '--nginx' and System.cpu_count < concurrency
|
||||||
|
print concurrency
|
Loading…
Reference in New Issue
Block a user