Puma перезагружает код приложения Rails до того, как в производственной среде выдается перезагрузка - PullRequest
0 голосов
/ 07 января 2020

Заметив странные исключения во время нашего развертывания (мы заметили, что новый код, основанный на миграциях, которые все еще выполнялись во время развертывания, уже обслуживались до того, как мы произвели перезапуск 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

1 Ответ

0 голосов
/ 07 января 2020

В зависимости от того, где находится ваше изменение (например, возможно, это часть пути, который загружается лениво и не был загружен в то время, возможно, автозагрузка / кэширование для конкретного c случая не работает должным образом ...), но также то, как вы сконфигурировали rails на своих env/production.rb или application.rb, Puma или других серверах rails, могут «забрать» ваши изменения даже без перезапуска. затем код, который их использует (ie имеет двухступенчатое развертывание) ...

EDIT : Чтобы быть уверенным, что происходит, вы можете выполнить это:

# does below command returns a list containing use ActionDispatch::Reloader ?
bundle exec rake middleware RAILS_ENV=production
...