背景 在AWS Elastic Beanstalk中,如果选用Ruby with Passenger运行Rails时,会遇到一个问题,就是EB环境中的Passenger的max_pool_size是默认的6。如果EB中的Instance选用的是性能比较高的类型,只起6个Passenger进程会是一个巨大的浪费。下面介绍几个修改EB中Passenger max_pool_size参数的方法。
Passenger官方说明 最新的官方Introduction to configuring Passenger Standalone 文档中,Passenger Standalone可以通过如下几种方式来修改启动参数
一、传递参数给启动命令passenger start
二、使用环境变量(从5.0.22开始)
三、通过配置文件Passengerfile.json
EB的限制 EB中的Passenger, 版本还是使用的4.0.60, 因此官网所述的三个方法中,在EB中并不完全适用。
方法二需要在5.0.22以上版本才支持,因此在EB环境中不可用
方法三中所述的Passengerfile.json是在5.0.1中才被正式使用的,在之前的版本中,使用的是passenger-standalone.json。所以在EB环境中,需要使用passenger-standalone.json来修改启动参数。文件命令的变化可参见Passenger 5.0.1的Release Note
实现 通过passenger-standalone.json来实现 在项目代码主目录下,添加文件passenger-standalone.json, 文件内容为
1 2 3 { "max_pool_size": 10 }
eb deploy完成后,使用EC2的key pair登陆EC2, sudo后运行passenger-status。可以看到max_pool_size已成功修改为10。
通过EB中的passenger命令参数来实现 EB环境中的EC2的passenger启动脚本是/etc/init.d/passenger,实际运行的是/opt/elasticbeanstalk/support/conf/passenger。
只要通过ebextension配置文件,修改/opt/elasticbeanstalk/support/conf/passenger,添加上对max_pool_size的支持即可。
原始的passenger文件参见origin_passenger
用来修改passenger,支持读取环境变量中的PASSENGER_MAX_POOL_SIZE的extension config如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 files: "/opt/elasticbeanstalk/support/conf/passenger": mode: "000755" owner: root group: root content: | #!/usr/bin/env bash # # chkconfig: 2345 80 20 # description: Passenger # EB_HTTP_PORT=$(/opt/elasticbeanstalk/bin/get-config container -k http_port) EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user) EB_APP_DEPLOY_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir) EB_APP_PID_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_pid_dir) EB_APP_LOG_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_log_dir) EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir) EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir) EB_NGINX_VERSION=$(/opt/elasticbeanstalk/bin/get-config container -k nginx_version) . $EB_SUPPORT_DIR/envvars . $EB_SCRIPT_DIR/use-app-ruby.sh if [ -f /etc/elasticbeanstalk/set-ulimit.sh ]; then . /etc/elasticbeanstalk/set-ulimit.sh fi # fixes http://code.google.com/p/phusion-passenger/issues/detail?id=614 export HOME=/tmp export PASSENGER_DOWNLOAD_NATIVE_SUPPORT_BINARY=0 if [ -d /etc/healthd ]; then STARTOPTS="--nginx-version $EB_NGINX_VERSION --nginx-config-template $EB_SUPPORT_DIR/conf/nginx_config_healthd.erb" else STARTOPTS="--nginx-version $EB_NGINX_VERSION --nginx-config-template $EB_SUPPORT_DIR/conf/nginx_config.erb" fi ENV_STAGE=${RACK_ENV:-$RAILS_ENV} # Read from $RAILS_ENV if $RACK_ENV is empty if [ ${ENV_STAGE,,} = "production" ]; then # Convert $ENV_STAGE to lower case and compare to "production" # Disable passenger friendly page for production stage STARTOPTS="$STARTOPTS --no-friendly-error-pages" fi GENERALOPTS="-p $EB_HTTP_PORT --pid-file $EB_APP_PID_DIR/passenger.pid" SELFOPTS="--max-pool-size ${PASSENGER_MAX_POOL_SIZE:-6}" function start() { touch $EB_APP_LOG_DIR/passenger.log if [ -d /etc/healthd ]; then mkdir -p $EB_APP_LOG_DIR/healthd chown -R $EB_APP_USER:$EB_APP_USER $EB_APP_LOG_DIR/healthd fi chown $EB_APP_USER:$EB_APP_USER \ $EB_APP_LOG_DIR/passenger.log passenger start $EB_APP_DEPLOY_DIR $STARTOPTS $GENERALOPTS $SELFOPTS\ -d -e ${RACK_ENV:-$RAILS_ENV} --user $EB_APP_USER \ --log-file $EB_APP_LOG_DIR/passenger.log } function stop() { passenger stop $GENERALOPTS } function status() { passenger status $GENERALOPTS } case "$1" in start) start ;; stop) stop ;; status) status ;; restart|graceful) stop start ;; reload) su -s /bin/bash -c "touch $EB_APP_DEPLOY_DIR/tmp/restart.txt" $EB_APP_USER ;; *) echo "Usage: $0 {start|stop|restart|reload|status}" exit 1 ;; esac exit 0
对原passenger脚本进行了两处修改
添加了SELFOPTS
添加SELFOPTS到passenger start命令之后。
1 2 3 4 5 6 7 8 9 10 $ diff origin_passenger passenger_with_selfopt 39a40 > SELFOPTS="--max-pool-size ${PASSENGER_MAX_POOL_SIZE:-6}" 51c52 < passenger start $EB_APP_DEPLOY_DIR $STARTOPTS $GENERALOPTS \ --- > passenger start $EB_APP_DEPLOY_DIR $STARTOPTS $GENERALOPTS $SELFOPTS\ 87a89 > $
该修改参考了如下的两篇帖子:
但这两篇帖子中,都把--max-pool-size放在了GENERALOPTS变量中,但这么设置是存在问题的。 因为脚本里的stop和status也会用到GENERALOPTS这个变量,但passenger stop和passenger status并不支持--max-pool-size这个参数,如果放在GENERALOPTS中,会导致passenger stop和passenger status运行失败。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@ip-172-31-40-19 ec2-user]# passenger stop -h Usage: passenger stop [options] Options: -p, --port NUMBER The port number of a Phusion Passenger Standalone instance (default: 3000) --pid-file FILE PID file of a running Phusion Passenger Standalone instance. -h, --help Show this help message [root@ip-172-31-40-19 ec2-user]# [root@ip-172-31-40-19 ec2-user]# passenger status -h Usage: passenger status [options] Options: -p, --port NUMBER The port number of a Phusion Passenger Standalone instance (default: 3000) --pid-file FILE PID file of a running Phusion Passenger Standalone instance. -h, --help Show this help message [root@ip-172-31-40-19 ec2-user]#
所以最终解决方案是额外添加了变量SELFOPTS用来存放参数--max-pool-size, 并且只将SELFOPTS添加到passenger start中。
使用eb deploy发布ebextension到EB中,在EB Console中添加环境变量PASSENGER_MAX_POOL_SIZE并设定所想要的值。
登陆Instance后,即可看到Max pool size已经被设置为PASSENGER_MAX_POOL_SIZE相同的值了。
相关修改的snippet 原始passenger文件以及ebextension配置文件可参照 https://github.com/jibing57/my-snippet/tree/master/AWS/ElasticBeanstalk/01_increase_passenger_max_pool_size
后记 要修改其他的Passenger启动参数,也可以使用类似的方法来实现。Passenger所支持的参数在官网中都有相关说明,**Configuration reference for Passenger Standalone **。 唯一要注意的是,EB中的Passenger版本是4.0.60的,版本要求大于4.0.60的选项在EB中是无效的。
Reference