From bb5726fa510a9780df6a3a7487864f980c4d9f3c Mon Sep 17 00:00:00 2001 From: Jevgenij Sevostjanov Date: Tue, 20 Feb 2018 12:16:51 +0200 Subject: [PATCH 1/3] Run php-fpm as a separate process --- cookbooks/php/recipes/fpm.rb | 171 +++++++++--------- cookbooks/php/resources/monit_service.rb | 34 ++++ .../php/templates/default/fpm-global.conf.erb | 10 +- .../php/templates/default/fpm-pool.conf.erb | 3 +- .../php/templates/default/php-fpm-openrc.erb | 48 +++++ .../php/templates/default/php-fpm.monitrc.erb | 17 +- 6 files changed, 185 insertions(+), 98 deletions(-) create mode 100755 cookbooks/php/resources/monit_service.rb create mode 100644 cookbooks/php/templates/default/php-fpm-openrc.erb diff --git a/cookbooks/php/recipes/fpm.rb b/cookbooks/php/recipes/fpm.rb index 280fb6f5..51ed3646 100755 --- a/cookbooks/php/recipes/fpm.rb +++ b/cookbooks/php/recipes/fpm.rb @@ -41,44 +41,39 @@ class Chef::Recipe action :create end +# stopping common php-fpm service if it's running +execute 'stop obsolete php-fpm service' do + command "/usr/bin/monit stop php-fpm" + only_if "/usr/bin/monit status php-fpm" +end + +# deleting obsolete service files +execute 'delete old init scripts' do + command "rm -f /etc/monit.d/php-fpm.monitrc && rm -rf /etc/init.d/php-fpm && rm -f /engineyard/bin/php-fpm" + only_if "test -f /etc/monit.d/php-fpm.monitrc" +end + +monit_service 'monit_reload_config' do + action :nothing +end bash 'eselect php and restart via monit' do code <<-EOH eselect php set fpm php#{node["php"]["minor_version"]} EOH not_if "php-fpm -v | grep PHP | grep #{node['php']['version']}" - notifies :run, 'execute[monit_restart_fpm]' -end - - -execute 'monit_restart_fpm' do - command "sudo monit restart php-fpm" - action :nothing + notifies :restartall, 'monit_service[monit_reload_config]' end - - - # get all applications with type PHP apps = node.dna['applications'].select{ |app, data| data['recipes'].detect{ |r| r == 'php' } } # collect just the app names app_names = apps.collect{ |app, data| app } -# generate global fpm config -template "/etc/php-fpm.conf" do - owner node["owner_name"] - group node["owner_name"] - mode "0644" - source "fpm-global.conf.erb" - variables({ - :apps => app_names - }) -# notifies :restart, resources(:service => "php-fpm"), :delayed -end - # Can't access get_fpm_coount inside block app_fpm_count = (get_fpm_count / node.dna['applications'].size) app_fpm_count = 1 unless app_fpm_count >= 1 +mc_hostnames = node.engineyard.environment.instances.map{|i| i['private_hostname'] if i['role'][/^app|solo/]}.compact.map {|i| "#{i}:11211"} # generate an fpm pool for each php app app_names.each do |app_name| @@ -91,7 +86,73 @@ class Chef::Recipe not_if { FileTest.exists?("/data/#{app_name}/shared/config/env.custom") } end - mc_hostnames = node.engineyard.environment.instances.map{|i| i['private_hostname'] if i['role'][/^app|solo/]}.compact.map {|i| "#{i}:11211"} + # Create init.d for each php-fpm application + # To be able to start and stop each application separately + template "/engineyard/bin/php-fpm_#{app_name}" do + owner node["owner_name"] + group node["owner_name"] + mode 0777 + source "php-fpm-openrc.erb" + variables( + :app_name => app_name, + :user => node["owner_name"], + :group => node["owner_name"] + ) + end + + # Delete any existing init.d file if it's not a symlink + cookbook_file "/etc/init.d/php-fpm_#{app_name}" do + action :delete + backup 0 + not_if "test -h /etc/init.d/php-fpm_#{app_name}" + end + + # Create a symlink under init.d + link "/etc/init.d/php-fpm_#{app_name}" do + to "/engineyard/bin/php-fpm_#{app_name}" + end + + # create symlinks for each app too. Required for deploy. + link "/engineyard/bin/app_#{app_name}" do + to "/engineyard/bin/php-fpm_#{app_name}" + end + + # Create monitrc file for the application and restart monit + template "/etc/monit.d/php-fpm_#{app_name}.monitrc" do + owner node["owner_name"] + group node["owner_name"] + mode 0600 + source "php-fpm.monitrc.erb" + variables( + :app_name => app_name + ) + backup 0 + notifies :reload, "monit_service[monit_reload_config]", :immediately + end + + # generate global fpm config + template "/etc/php/php-fpm_#{app_name}.conf" do + owner node["owner_name"] + group node["owner_name"] + mode "0644" + source "fpm-global.conf.erb" + variables({ + :app_name => app_name + }) + notifies :restart, "monit_service[php-fpm_#{app_name}]", :delayed + end + + # generate global fpm config + template "/etc/php/php-fpm_#{app_name}.conf" do + owner node["owner_name"] + group node["owner_name"] + mode "0644" + source "fpm-global.conf.erb" + variables({ + :app_name => app_name + }) + notifies :restart, "monit_service[php-fpm_#{app_name}]", :delayed + end template "/data/#{app_name}/shared/config/fpm-pool.conf" do owner node["owner_name"] @@ -109,67 +170,15 @@ class Chef::Recipe :max_children => app_fpm_count, :memcache_hostnames => mc_hostnames.join(',') }) - + notifies :restart, "monit_service[php-fpm_#{app_name}]", :delayed end -end - -# Report to Cloud dashboard -#ey_cloud_report "processing php" do -# message "processing php - monitoring" -#end - -# Create global init.d file -# We are unable to start and stop each app individually -cookbook_file "/engineyard/bin/php-fpm" do - owner node["owner_name"] - group node["owner_name"] - mode 0777 - source "init.d-php-fpm.sh" - backup 0 -end -# Delete any existing init.d file if it's not a symlink -cookbook_file "/etc/init.d/php-fpm" do - action :delete - backup 0 - - not_if "test -h /etc/init.d/php-fpm" -end - -# Create a symlink under init.d -link "/etc/init.d/php-fpm" do - to "/engineyard/bin/php-fpm" -end - -# get all applications with type PHP -apps = node.dna['applications'].select{ |app, data| data['recipes'].detect{ |r| r == 'php' } } -# collect just the app names -app_names = apps.collect{ |app, data| app } - -app_names.each do |app| - # create symlinks for each app, too. Required for deploy. - link "/engineyard/bin/app_#{app}" do - to "/engineyard/bin/php-fpm" + monit_service "php-fpm_#{app_name}" do + service_name "php-fpm_#{app_name}" + action :start end - + # Change ownership of app slowlog if set to root - check_fpm_log_owner(app) -end + check_fpm_log_owner(app_name) -# Create monitrc file (all apps) and restart monit -template "/etc/monit.d/php-fpm.monitrc" do - owner node["owner_name"] - group node["owner_name"] - mode 0600 - source "php-fpm.monitrc.erb" - variables( - :apps => app_names, - :user => node["owner_name"] - ) - backup 0 - - notifies :run, 'execute[restart-monit]' end - -# cookbooks/php/libraries/php_helpers.rb -restart_fpm diff --git a/cookbooks/php/resources/monit_service.rb b/cookbooks/php/resources/monit_service.rb new file mode 100755 index 00000000..3ba464dd --- /dev/null +++ b/cookbooks/php/resources/monit_service.rb @@ -0,0 +1,34 @@ +# +# Cookbook:: php +# Resource:: monit_service +# +# Author:: Jevgenij Sevostjanov + +resource_name :monit_service + +property :service_name, String, name_property: true + +action :start do + execute "monit start #{new_resource.service_name}" do + command "/usr/bin/monit start #{new_resource.service_name}" + not_if "/usr/bin/monit status #{new_resource.service_name} | grep -Eq 'Initializing|Running'" + end +end + +action :restart do + execute "monit restart #{new_resource.service_name}" do + command "/usr/bin/monit restart #{new_resource.service_name}" + end +end + +action :restartall do + execute "monit restart all services" do + command "/usr/bin/monit restart all" + end +end + +action :reload do + execute "monit reload" do + command "/usr/bin/monit reload && sleep 3" + end +end diff --git a/cookbooks/php/templates/default/fpm-global.conf.erb b/cookbooks/php/templates/default/fpm-global.conf.erb index b133a46b..d476e903 100644 --- a/cookbooks/php/templates/default/fpm-global.conf.erb +++ b/cookbooks/php/templates/default/fpm-global.conf.erb @@ -2,6 +2,8 @@ ; FPM Configuration ; ;;;;;;;;;;;;;;;;;;;;; +; For application <%= @app_name %> + ; All relative paths in this configuration file are relative to PHP's install ; prefix (/usr/lib64/php5.3). This prefix can be dynamicaly changed by using the ; '-p' argument from the command line. @@ -22,14 +24,14 @@ ; Pid file ; Note: the default prefix is /usr/lib64/php5.3/var ; Default Value: none -pid = /var/run/engineyard/php-fpm.pid +pid = /var/run/engineyard/php-fpm_<%= @app_name %>.pid ; Error log file ; If it's set to "syslog", log is sent to syslogd instead of being written ; in a local file. ; Note: the default prefix is /usr/lib64/php5.3/var ; Default Value: log/php-fpm.log -error_log = /var/log/engineyard/php-fpm/error.log +error_log = /var/log/engineyard/php-fpm/<%= @app_name %>_error.log ; syslog_facility is used to specify what type of program is logging the ; message. This lets syslogd specify that messages from different facilities @@ -103,6 +105,4 @@ error_log = /var/log/engineyard/php-fpm/error.log ; Pool Definitions ; ;;;;;;;;;;;;;;;;;;;; -<% @apps.each do |app| %> -include = /data/<%= app %>/shared/config/fpm-pool.conf -<% end %> \ No newline at end of file +include = /data/<%= @app_name %>/shared/config/fpm-pool.conf diff --git a/cookbooks/php/templates/default/fpm-pool.conf.erb b/cookbooks/php/templates/default/fpm-pool.conf.erb index 04da3f76..405e0aa8 100644 --- a/cookbooks/php/templates/default/fpm-pool.conf.erb +++ b/cookbooks/php/templates/default/fpm-pool.conf.erb @@ -1,8 +1,7 @@ +; PHP-FPM pool configuration for <%= @app_name %> [<%= @app_name %>] php_admin_value[error_log] = /data/<%= @app_name %>/current/log/error_log listen = /var/run/engineyard/php-fpm_<%= @app_name %>.sock -user = <%= @user %> -group = <%= @user %> listen.backlog = -1 pm = static diff --git a/cookbooks/php/templates/default/php-fpm-openrc.erb b/cookbooks/php/templates/default/php-fpm-openrc.erb new file mode 100644 index 00000000..6ef5e080 --- /dev/null +++ b/cookbooks/php/templates/default/php-fpm-openrc.erb @@ -0,0 +1,48 @@ +#!/sbin/openrc-run + +set_phpvars() { + PHP_FPM_CONF="/etc/php/php-fpm_<%= @app_name %>.conf" + PHP_FPM_PID="/var/run/engineyard/php-fpm_<%= @app_name %>.pid" + PHP_FPM_USER="<%= @user %>" + PHP_FPM_GROUP="<%= @group %>" +} + +extra_started_commands="reload" + +start() { + ebegin "Starting PHP FastCGI Process Manager for <%= @app_name %>" + set_phpvars + start-stop-daemon --start -u ${PHP_FPM_USER} -g ${PHP_FPM_GROUP} --pidfile ${PHP_FPM_PID} --exec \ + /usr/bin/php-fpm -- -y "${PHP_FPM_CONF}" -g "${PHP_FPM_PID}" + local i=0 + local timeout=5 + while [ ! -f ${PHP_FPM_PID} ] && [ $i -le $timeout ]; do + sleep 1 + i=$(($i + 1)) + done + + [ $timeout -gt $i ] + eend $? +} + +stop() { + ebegin "Stopping PHP FastCGI Process Manager for <%= @app_name %>" + set_phpvars + start-stop-daemon --signal QUIT --stop --exec /usr/bin/php-fpm --pidfile ${PHP_FPM_PID} + eend $? +} + +reload() { + ebegin "Reloading <%= @app_name %> PHP FastCGI Process Manager" + set_phpvars + if [ -f ${PHP_FPM_PID} ]; then + kill -USR2 $(cat ${PHP_FPM_PID}) + else + echo "<%= @app_name %> PHP-FPM process is not running restarting" + start + if [ $? == 0 ]; then + mark_service_started + fi + fi + eend $? +} diff --git a/cookbooks/php/templates/default/php-fpm.monitrc.erb b/cookbooks/php/templates/default/php-fpm.monitrc.erb index 52eb75c3..e5f7d906 100644 --- a/cookbooks/php/templates/default/php-fpm.monitrc.erb +++ b/cookbooks/php/templates/default/php-fpm.monitrc.erb @@ -1,10 +1,7 @@ -check process php-fpm - with pidfile /var/run/engineyard/php-fpm.pid - group php-fpm - start program = "/bin/bash -c '/etc/init.d/php-fpm start'" - as uid <%= @user %> and gid <%= @user %> - stop program = "/bin/bash -c '/etc/init.d/php-fpm stop'" - as uid <%= @user %> and gid <%= @user %> -<% @apps.each do |app| %> -if failed unixsocket /var/run/engineyard/php-fpm_<%= app %>.sock then restart -<% end %> \ No newline at end of file +check process php-fpm_<%= @app_name %> + with pidfile /var/run/engineyard/php-fpm_<%= @app_name %>.pid + group php-fpm_<%= @app_name %> + start program = "/bin/bash -c '/etc/init.d/php-fpm_<%= @app_name %> start'" + stop program = "/bin/bash -c '/etc/init.d/php-fpm_<%= @app_name %> stop'" + restart program = "/bin/bash -c '/etc/init.d/php-fpm_<%= @app_name %> reload'" +if failed unixsocket /var/run/engineyard/php-fpm_<%= @app_name %>.sock then restart \ No newline at end of file From b9035e79c7130ed2d554dbe99d3f1bb677f1283d Mon Sep 17 00:00:00 2001 From: Jevgenij Sevostjanov Date: Mon, 5 Mar 2018 14:44:35 +0000 Subject: [PATCH 2/3] php-fpm monit fix --- cookbooks/php/resources/monit_service.rb | 4 ++-- cookbooks/php/templates/default/php-fpm.monitrc.erb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cookbooks/php/resources/monit_service.rb b/cookbooks/php/resources/monit_service.rb index 3ba464dd..98c784a7 100755 --- a/cookbooks/php/resources/monit_service.rb +++ b/cookbooks/php/resources/monit_service.rb @@ -22,8 +22,8 @@ end action :restartall do - execute "monit restart all services" do - command "/usr/bin/monit restart all" + execute "monit restart all php-fpm services" do + command "/usr/bin/monit restart all -g php-fpm" end end diff --git a/cookbooks/php/templates/default/php-fpm.monitrc.erb b/cookbooks/php/templates/default/php-fpm.monitrc.erb index e5f7d906..faaa71a1 100644 --- a/cookbooks/php/templates/default/php-fpm.monitrc.erb +++ b/cookbooks/php/templates/default/php-fpm.monitrc.erb @@ -1,7 +1,7 @@ check process php-fpm_<%= @app_name %> with pidfile /var/run/engineyard/php-fpm_<%= @app_name %>.pid - group php-fpm_<%= @app_name %> + group php-fpm start program = "/bin/bash -c '/etc/init.d/php-fpm_<%= @app_name %> start'" stop program = "/bin/bash -c '/etc/init.d/php-fpm_<%= @app_name %> stop'" restart program = "/bin/bash -c '/etc/init.d/php-fpm_<%= @app_name %> reload'" -if failed unixsocket /var/run/engineyard/php-fpm_<%= @app_name %>.sock then restart \ No newline at end of file +if failed unixsocket /var/run/engineyard/php-fpm_<%= @app_name %>.sock then restart From 9d756163649bfeb5bc7ba3a715a2b8e7876b9eda Mon Sep 17 00:00:00 2001 From: Jevgenij Sevostjanov Date: Thu, 8 Mar 2018 22:07:45 +0000 Subject: [PATCH 3/3] openrc start/stop script fix --- cookbooks/php/templates/default/php-fpm-openrc.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookbooks/php/templates/default/php-fpm-openrc.erb b/cookbooks/php/templates/default/php-fpm-openrc.erb index 6ef5e080..43e47088 100644 --- a/cookbooks/php/templates/default/php-fpm-openrc.erb +++ b/cookbooks/php/templates/default/php-fpm-openrc.erb @@ -7,7 +7,7 @@ set_phpvars() { PHP_FPM_GROUP="<%= @group %>" } -extra_started_commands="reload" +extra_commands="reload" start() { ebegin "Starting PHP FastCGI Process Manager for <%= @app_name %>"