Заметив странные исключения во время нашего развертывания (мы заметили, что новый код, основанный на миграциях, которые все еще выполнялись во время развертывания, уже обслуживались до того, как мы произвели перезапуск puma), мы могли подтвердить, что puma перезагружает код приложения, как только мы обновляем кодовая база через git pull
, даже несмотря на то, что мы работаем в рабочей среде ENV, и Puma должна дождаться перезапуска.
ОБНОВЛЕНИЕ : вот короткое 1-минутное видео о том, что происходит : https://www.loom.com/share/710d2d617f0746c8b418fc162a1c2016
ОС: Ubuntu 18.04 LTS
Версия Puma 4.3.0
Конфигурация Puma:
shared_dir = "/var/www/app/shared"
workers 25
threads 1, 1
bind "unix://#{shared_dir}/tmp/sockets/puma-app.sock"
environment "production"
stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true
pidfile "#{shared_dir}/tmp/pids/puma.pid"
preload_app!
before_fork do
ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord)
end
on_worker_boot do
ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
end
Сокет Puma (Мы используем активация сокета ):
[Unit]
Description=Puma HTTP Server Accept Sockets for app
[Socket]
SocketUser={{ param_user_name }}
SocketGroup={{ param_user_name }}
ListenStream=/var/www/app/shared/tmp/sockets/puma-app.sock
# Socket options matching Puma defaults
NoDelay=true
ReusePort=true
Backlog=1024
[Install]
WantedBy=sockets.target
Ожидаемое поведение - Puma не должна начинать обслуживать новый код сразу же после того, как мы обновим кодовую базу приложения с помощью тяги git. Нужно подождать, пока мы выдадим sudo systemctl restart puma-app.service.
Если мы вручную запустим git pull
в папке кодовой базы приложения, мы сможем подтвердить, что запросы начнут видеть новый код немедленно, даже если нет был произведен перезапуск пумы, и в puma.stdout.log перезапуск пумы не указан.
Обновление: вот мои Rails application.rb и production.rb
# application.rb
# Enables garbage colletion data for New Relic
GC::Profiler.enable
require_relative 'boot'
require 'rails/all'
require 'connection_pool'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module MyApp
class Application < Rails::Application
config.before_initialize do
::REDIS = ConnectionPool.new(size: ENV['WORKER_PROCESS'].to_i) { Redis.new }
end
config.autoload_paths += %W(
#{config.root}/lib
#{config.root}/lib/middleware
)
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
config.time_zone = 'Brasilia'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
config.i18n.default_locale = :'pt-br'
# dynamic and custom error pages
config.exceptions_app = self.routes
# ActiveJob
config.active_job.queue_adapter = :sidekiq
end
end
# production.rb
Rails.application.configure do
config.webpacker.check_yarn_integrity = false
# Code is not reloaded between requests.
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :sass
config.assets.compile = false
config.assets.digest = true
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
config.active_storage.service = :local
config.force_ssl = true
config.log_level = :info
Rails.application.routes.default_url_options = {host: 'example.com'}
config.action_mailer.asset_host = 'https://example.com'
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {...}
end