Takip et

Puma ve Foreman Kullanarak Sıfır Kesintiyle Rails Dağıtımları Nasıl Yapılır?

Puma ve Foreman Kullanarak Sıfır Kesintiyle Rails Dağıtımları Nasıl Yapılır? Sürekli gelişen web uygulamaları dünyasında, kullanıcı d

Puma ve Foreman Kullanarak Sıfır Kesintiyle Rails Dağıtımları Nasıl Yapılır?

Sürekli gelişen web uygulamaları dünyasında, kullanıcı deneyimini kesintiye uğratmadan yeni özellikler sunmak veya hata düzeltmeleri yapmak, modern yazılım geliştirme ekipleri için kritik bir gerekliliktir. Geleneksel dağıtım yöntemleri genellikle uygulamanın kısa bir süreliğine erişilemez olmasına neden olurken, “sıfır kesinti dağıtımı” (zero-downtime deployment) bu sorunu ortadan kaldırmayı hedefler. Özellikle Ruby on Rails gibi dinamik ve veritabanı odaklı uygulamalar için sıfır kesinti dağıtımı, iş sürekliliği ve kullanıcı memnuniyeti açısından vazgeçilmezdir. Bu makalede, popüler bir Rails uygulama sunucusu olan Puma ve süreç yöneticisi Foreman’ı kullanarak Rails uygulamalarınız için sıfır kesinti dağıtımlarını nasıl yapılandıracağınızı ayrıntılı bir şekilde inceleyeceğiz.

Sıfır Kesinti Dağıtımına Neden İhtiyaç Duyulur?

Günümüzün rekabetçi dijital pazarında, bir web uygulamasının birkaç saniye bile erişilemez olması ciddi sonuçlar doğurabilir. Kullanıcılar, hızlı ve kesintisiz hizmet beklerler. Bu beklentiyi karşılamak, sadece iyi bir kullanıcı deneyimi sunmakla kalmaz, aynı zamanda iş hedeflerine ulaşmak için de temel bir gerekliliktir.

Kullanıcı Deneyimi

Bir uygulamanın dağıtım sırasında bile kesintisiz çalışması, kullanıcıların güvenini artırır ve onlara sürekli erişilebilir bir hizmet sunduğunuzu gösterir. Kesintiler, kullanıcıların hayal kırıklığına uğramasına, sitenizden ayrılmasına ve hatta rakip platformlara yönelmesine neden olabilir. Sıfır kesinti dağıtımı, bu riski ortadan kaldırarak kullanıcı sadakatini pekiştirir.

İş Sürekliliği

E-ticaret siteleri, finansal uygulamalar veya kritik iş süreçlerini yöneten platformlar için her saniye önemlidir. Bir kesinti, doğrudan gelir kaybına, müşteri kaybına ve hatta yasal yükümlülüklere yol açabilir. Sıfır kesinti dağıtımı, iş süreçlerinizin aksamadan devam etmesini sağlayarak potansiyel zararları minimize eder.

Rekabet Avantajı

Pazar liderleri, genellikle en yeni özellikleri en hızlı ve en sorunsuz şekilde sunanlardır. Sıfır kesinti yeteneği, ekiplerin daha sık dağıtım yapmasına olanak tanır, bu da ürünün daha hızlı iterasyonunu ve pazar değişikliklerine daha çevik yanıt vermesini sağlar. Bu çeviklik, rakiplerinize karşı önemli bir avantaj sağlar.

SEO Etkisi

Arama motorları, bir sitenin kullanılabilirliğini sıralama faktörlerinden biri olarak değerlendirir. Sık yaşanan kesintiler veya uzun süreli erişilemezlik, arama motoru sıralamanızı olumsuz etkileyebilir. Sıfır kesinti dağıtımı, sitenizin sürekli olarak taranabilir ve erişilebilir olmasını sağlayarak SEO performansınızı korumanıza yardımcı olur.

Temel Bileşenler

Sıfır kesinti Rails dağıtımını mümkün kılmak için birkaç temel bileşenin uyumlu bir şekilde çalışması gerekir. Bu bileşenler, uygulamanın farklı katmanlarında görev alarak kesintisiz geçişi sağlar.

Puma

Puma, Ruby on Rails uygulamaları için yüksek performanslı, çok iş parçacıklı ve çok işlemli bir HTTP sunucusudur. Özellikle “cluster mode” adı verilen çok işlemli çalışma yeteneği, sıfır kesinti dağıtımları için kilit bir rol oynar. Puma, yeni kod dağıtıldığında eski uygulama örneklerini zarif bir şekilde kapatırken yeni örnekleri başlatma yeteneğine sahiptir. Bu “hot restart” veya “phased restart” özelliği, mevcut istekleri tamamlamasına izin verirken yeni gelen istekleri yeni kod tabanına yönlendirir.

Foreman

Foreman, Procfile tabanlı uygulamaları yönetmek için kullanılan bir araçtır. Bir Procfile, uygulamanızın farklı süreçlerini (web sunucusu, worker’lar, zamanlanmış görevler vb.) tanımlayan basit bir metin dosyasıdır. Foreman, bu süreçleri yerel geliştirme ortamında veya üretimde başlatmanıza, durdurmanıza ve izlemenize olanak tanır. Sıfır kesinti dağıtım senaryolarında, Foreman veya onun üretim ortamındaki karşılıkları (systemd, monit, god) Puma süreçlerini doğru sinyallerle yönetmek için kullanılır.

Reverse Proxy (Nginx/Apache)

Bir ters proxy (reverse proxy), istemciden gelen istekleri alır ve bunları arka uçtaki uygulama sunucularına (bizim durumumuzda Puma) iletir. Nginx veya Apache gibi popüler ters proxy’ler, yük dengeleme, SSL sonlandırma, statik dosya sunumu ve en önemlisi, dağıtım sırasında arka uç uygulama sunucularını değiştirmek için kullanılır. Nginx, yeni bir uygulama sürümü dağıtıldığında, eski Puma örnekleri kapanırken yeni başlatılan Puma örneklerine sorunsuz bir şekilde trafik yönlendirme yeteneği sayesinde sıfır kesinti dağıtımlarının kritik bir parçasıdır.

Capistrano (veya Benzeri Bir Dağıtım Aracı)

Capistrano, sunuculara otomatik olarak kod dağıtmak için kullanılan popüler bir uzaktan sunucu otomasyon aracıdır. Karmaşık dağıtım adımlarını (kod çekme, bağımlılıkları yükleme, veritabanı migrasyonları, sunucu yeniden başlatma) otomatikleştirmeyi sağlar. Sıfır kesinti dağıtımı, manuel adımlarla yönetilemeyecek kadar karmaşık olduğundan, Capistrano gibi bir aracın kullanılması zorunludur. Capistrano, özellikle Puma’nın yeniden başlatma sinyallerini doğru zamanda göndermek ve Nginx yapılandırmasını güncelleyerek trafiği yeni uygulama örneğine yönlendirmek için özelleştirilebilir.

Sıfır Kesinti Dağıtım Mimarisi

Sıfır kesinti dağıtım mimarisi, uygulamanızın kesintisiz çalışmasını sağlamak için katmanlı bir yaklaşıma dayanır. Bu mimarinin kalbinde, istemci isteklerini uygulama sunucularına yönlendiren bir ters proxy ve uygulamanın kendisini barındıran çok işlemli bir uygulama sunucusu bulunur.

Genel olarak, bir istemci (kullanıcı web tarayıcısı), uygulamanıza bir istek gönderdiğinde, bu istek önce ters proxy sunucusuna (örneğin Nginx) ulaşır. Nginx, bu isteği alır ve önceden yapılandırılmış kurallara göre arka uçtaki uygulama sunucularından birine (Puma) iletir. Puma, Rails uygulamasını çalıştırır, isteği işler ve yanıtı Nginx aracılığıyla istemciye geri gönderir.

Dağıtım sırasında, bu akış kritik bir dönüşüme uğrar. Yeni kod sunucuya çekilir, bağımlılıklar yüklenir ve yeni uygulama sürümü hazırlanır. Ancak bu yeni sürüm hemen eski sürümün yerini almaz. Bunun yerine, Puma’nın “hot restart” yeteneği devreye girer. Eski Puma işlemleri hala çalışır durumdayken, yeni kodla birlikte yeni Puma işlemleri başlatılır. Nginx, eski Puma’nın soketine bağlı kalmaya devam ederken, yeni Puma işlemleri kendi yeni soketlerinde dinlemeye başlar. Puma’nın yeniden başlatma sinyali (SIGUSR2) alındığında, Nginx’e yeni soket bilgisi bildirilir ve Nginx yavaşça yeni Puma soketine trafik yönlendirmeye başlar. Eski Puma işlemleri, mevcut isteklerini tamamladıktan sonra zarif bir şekilde kapanır. Bu geçiş, kullanıcılar için tamamen şeffaf bir şekilde gerçekleşir, böylece herhangi bir kesinti yaşanmaz.

Puma ile Sıfır Kesinti Nasıl Sağlanır?

Puma’nın sıfır kesinti dağıtımlarındaki rolü, onun çoklu işlem yeteneklerine ve sinyal işleme mekanizmasına dayanır. Bu özellikler, yeni bir kod sürümünü etkinleştirirken eski sürümün hala aktif istekleri işlemesine olanak tanır.

Puma’nın Çoklu İşlem Modu (Cluster Mode)

Puma, birden fazla worker işlemi çalıştırarak Rails uygulamanızın performansını ve kararlılığını artırır. Her worker işlemi, kendi Rails uygulama örneğini barındırır ve birden fazla iş parçacığı (thread) ile eşzamanlı istekleri işleyebilir. Cluster mode, bu worker’ların ana bir Puma master işlemi tarafından yönetilmesini sağlar. Master işlem, worker’ları başlatmaktan, izlemekten ve gerektiğinde yeniden başlatmaktan sorumludur. Sıfır kesinti dağıtımında, bu master işlem, yeni kod dağıtıldığında worker’ları güvenli bir şekilde güncellemeyi koordine eder.

Puma’nın Hot Restart Mekanizması

Puma’nın “hot restart” veya “phased restart” mekanizması, sıfır kesintinin anahtarıdır. Bu mekanizma, aşağıdaki sinyaller aracılığıyla tetiklenir:

* SIGTERM: Bu sinyal, Puma’ya mevcut istekleri tamamladıktan sonra zarif bir şekilde kapanmasını söyler. Genellikle uygulamanın tamamen durdurulması gerektiğinde kullanılır.
* SIGUSR2: Bu sinyal, Puma master işlemine “hot restart” yapmasını emreder. Master işlem bu sinyali aldığında:
1. Yeni kod tabanıyla yeni worker işlemleri başlatır.
2. Yeni worker’lar başlatılıp hazır hale geldiğinde, master işlem eski worker’lara SIGTERM sinyali gönderir.
3. Eski worker’lar, mevcut isteklerini tamamladıktan sonra kapanır.
4. Nginx gibi ters proxy’ler, bu süreçte yeni Puma soketine yönlendirilerek trafiği kesintisiz bir şekilde yeni worker’lara aktarır.

Bu süreç sayesinde, uygulamanızın her zaman en az bir worker kümesi tarafından hizmet verilmesi sağlanır. Kullanıcılar, dağıtımın gerçekleştiğini fark etmezler çünkü istekleri her zaman aktif ve doğru bir uygulama örneği tarafından karşılanır.

Foreman ile Süreç Yönetimi

Foreman, geliştirme ortamında Procfile tabanlı uygulamaları yönetmek için tasarlanmış olsa da, üretim ortamında da benzer bir işlevsellik sağlayan araçlarla birlikte kullanılabilir.

Procfile Nedir ve Nasıl Oluşturulur?

Bir Procfile, uygulamanızın hangi süreçlerden oluştuğunu ve bu süreçlerin nasıl başlatılması gerektiğini tanımlayan basit bir metin dosyasıdır. Genellikle uygulamanızın kök dizininde bulunur.

Örnek bir Procfile:

web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq -c 5 -q default -q mailers

Bu örnekte:
* web: Puma web sunucusunu config/puma.rb yapılandırma dosyasıyla başlatır.
* worker: Sidekiq arka plan işleme worker’ını başlatır.

Foreman’ın Görevi

Foreman, Procfile‘ı okur ve tanımlanan her süreç için ayrı bir işlem başlatır. Bu, özellikle yerel geliştirme ortamında uygulamanızın tüm bileşenlerini tek bir komutla (örneğin foreman start) başlatmanıza olanak tanır. Her sürecin çıktısını ayrı pencerelerde veya tek bir konsolda birleştirerek izlemeyi kolaylaştırır.

Üretim Ortamında Foreman Kullanımı

Doğrudan Foreman’ı üretimde kullanmak yerine, genellikle Procfile‘ı okuyup sisteminize özel süreç yöneticisi yapılandırmaları üreten araçlar tercih edilir. Örneğin:

* systemd: Linux sistemlerinde birincil init sistemi ve servis yöneticisidir. systemd servis dosyaları, Procfile‘daki her bir süreç için oluşturularak Puma ve diğer uygulama bileşenlerinin sistem başlangıcında otomatik olarak başlatılmasını ve izlenmesini sağlar. systemd-foreman veya foreman export systemd gibi araçlar bu dönüşümü yapabilir.
* monit / god: Bu araçlar, süreçleri izlemek, çöktüklerinde otomatik olarak yeniden başlatmak ve belirli koşullar altında bildirimler göndermek için kullanılır. Puma gibi kritik süreçlerin her zaman çalışır durumda kalmasını sağlamak için faydalıdırlar.

Sıfır kesinti dağıtımında, bu üretim süreç yöneticileri, Capistrano gibi dağıtım araçlarından gelen sinyallere yanıt vererek Puma’nın hot restart mekanizmasını doğru bir şekilde tetiklemekten sorumludur.

Dağıtım Süreci Adım Adım (Capistrano ile Örnek)

Capistrano ile sıfır kesinti dağıtımı, bir dizi dikkatlice orkestrasyon edilmiş adımdan oluşur. Bu adımlar, yeni kodun güvenli bir şekilde sunucuya aktarılmasını ve uygulamanın kesintisiz bir şekilde güncellenmesini sağlar.

Ön Gereksinimler

Dağıtıma başlamadan önce sunucunuzun hazır olduğundan emin olmalısınız:

* Sunucu İşletim Sistemi: Ubuntu, CentOS gibi Linux dağıtımları.
* SSH Anahtarları: Capistrano’nun sunucuya güvenli bir şekilde bağlanabilmesi için SSH anahtar tabanlı kimlik doğrulama.
* Ruby ve Rails Ortamı: rbenv veya rvm ile doğru Ruby sürümü ve Bundler.
* Veritabanı: PostgreSQL veya MySQL kurulu ve yapılandırılmış olmalı.
* Ters Proxy: Nginx kurulu ve yapılandırılmış olmalı.
* Uygulama Bağımlılıkları: git, nodejs, yarn (asset derleme için).

Capistrano Kurulumu ve Yapılandırması

1. Gemfile‘a Ekleme:

group :development do
      gem 'capistrano', '~> 3.17'
      gem 'capistrano-rails'
      gem 'capistrano-rbenv', '~> 2.1' # rbenv kullanıyorsanız
      gem 'capistrano-puma', '~> 6.0' # Puma için
      gem 'capistrano-nginx', '~> 2.0' # Nginx için (isteğe bağlı, manuel konfigürasyon da mümkün)
    end

Ardından bundle install çalıştırın.

2. cap install: Bu komut, Capistrano’nun temel yapılandırma dosyalarını (örneğin Capfile, config/deploy.rb, config/deploy/production.rb) oluşturur.

3. config/deploy.rb Yapılandırması: Bu dosya, tüm dağıtım ortamları için ortak ayarları içerir.

# config/deploy.rb
    lock "~> 3.17.3"

    set :application, "your_app_name"
    set :repo_url, "git@github.com:your_user/your_app_name.git"

    # Default branch is :master
    # ask :branch, git rev-parse --abbrev-ref HEAD.chomp
    set :branch, ENV['BRANCH'] || 'master'

    # Default deploy_to directory is /var/www/my_app_name
    set :deploy_to, "/var/www/#{fetch(:application)}"

    # Default value for :format is :airbrussh.
    # set :format, :airbrussh

    # You can configure the Airbrussh format using :format_options.
    # These are the defaults.
    # set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto

    # Default value for :pty is false
    set :pty, true

    # Default value for :linked_files is []
    append :linked_files, "config/database.yml", "config/master.key" # master.key Rails 5.2+ için
    # append :linked_files, "config/credentials/#{fetch(:stage)}.yml.enc" # Rails 6+ için

    # Default value for linked_dirs is []
    append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system", "vendor/bundle", "public/uploads"

    # Default value for default_env is {}
    # set :default_env, { path: "/opt/ruby/bin:$PATH" }

    # Default value for local_user is ENV['USER']
    # set :local_user, -> { git config user.name.chomp }

    # Default value for keep_releases is 5
    set :keep_releases, 5

    # Uncomment the following to require manually confirming clear/revert actions when running deploy:clear_cache or deploy:revert.
    # set :confirm_clear, true

    # rbenv configuration
    set :rbenv_type, :user # or :system, depends on your rbenv installation
    set :rbenv_ruby, '3.2.2' # Your Ruby version
    set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
    set :rbenv_map_bins, %w{rake gem bundle ruby rails puma pumactl sidekiq sidekiqctl}
    set :rbenv_roles, :all # default value

    # Puma configuration
    set :puma_init_active_record, true # For phased restart, ensures DB connection is handled gracefully

linked_files ve linked_dirs, her dağıtımda sembolik olarak bağlanan dosyaları ve dizinleri belirtir. Bu, dağıtımlar arasında kalıcı olması gereken veriler (veritabanı yapılandırması, loglar, yüklemeler) için önemlidir.

4. config/deploy/production.rb Yapılandırması: Ortama özel ayarlar buraya yazılır.

# config/deploy/production.rb
    server 'your_server_ip_or_hostname', user: 'deploy_user', roles: %w{web app db}

    set :rails_env, :production
    set :stage, :production

5. shared Dizini: Capistrano, deploy_to dizini altında releases ve shared adında iki ana dizin oluşturur. releases dizini, uygulamanızın her yeni sürümünü içerirken, shared dizini, tüm sürümler arasında paylaşılması gereken kalıcı dosyaları ve dizinleri (örneğin config/database.yml, log, tmp/pids) barındırır. Dağıtım sırasında, Capistrano shared dizinindeki bu dosya ve dizinlere sembolik bağlantılar oluşturur.

Puma Yapılandırması (Capistrano ile)

Capistrano’nun capistrano-puma gem’i, Puma’nın dağıtımını ve yönetimini kolaylaştırır.

1. config/puma.rb (Uygulama İçin): Bu dosya, Puma’nın nasıl çalışacağını tanımlar.

# config/puma.rb
    workers Integer(ENV['WEB_CONCURRENCY'] || 2) # Worker sayısı, genellikle CPU çekirdek sayısına göre ayarlanır
    threads Integer(ENV['MIN_THREADS']  || 1), Integer(ENV['MAX_THREADS'] || 16) # İş parçacığı sayısı

    preload_app! # Uygulamayı worker'lar fork edilmeden önce yükle (daha hızlı restart)

    rackup      DefaultRackup
    port        ENV['PORT']     || 3000
    environment ENV['RACK_ENV'] || 'development'

    on_worker_boot do
      # Worker başlatıldığında ActiveRecord bağlantılarını yeniden kur
      ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
    end

    # production ortamı için socket bağlantısı
    # Capistrano-puma otomatik olarak bu dosyayı oluşturur ve yönetir.
    # set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"
    # set :puma_state, "#{shared_path}/tmp/pids/puma.state"
    # set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"

preload_app! direktifi, master Puma işleminin uygulamayı yüklemesini sağlar, böylece worker’lar fork edildiğinde uygulama kodu zaten bellekte olur. Bu, hot restart sırasında daha hızlı başlangıç sağlar.

2. capistrano-puma Ayarları: deploy.rb içinde Capistrano-Puma için ek ayarlar yapabilirsiniz.

# config/deploy.rb
    # ...
    set :puma_user, fetch(:user) # Puma'nın çalışacağı kullanıcı
    set :puma_rackup, -> { File.join(current_path, 'config.ru') }
    set :puma_state, "#{shared_path}/tmp/pids/puma.state"
    set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
    set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock" # Nginx'in bağlanacağı soket
    set :puma_default_control_app, "unix://#{shared_path}/tmp/sockets/pumactl.sock"
    set :puma_access_log, "#{shared_path}/log/puma_access.log"
    set :puma_error_log, "#{shared_path}/log/puma_error.log"
    set :puma_worker_timeout, nil # Puma worker'larının zaman aşımı
    set :puma_preload_app, true # preload_app! kullanıyorsanız true yapın
    set :puma_init_active_record, true # hot restart sırasında ActiveRecord bağlantılarını yeniler
    # ...

Nginx Yapılandırması

Nginx, istemci isteklerini Puma’ya yönlendiren ters proxy görevi görür. capistrano-nginx gem’i, Nginx yapılandırmasını otomatik olarak oluşturabilir, ancak manuel olarak da yapabilirsiniz.

# /etc/nginx/sites-available/your_app_name.conf
upstream puma {
  server unix:/var/www/your_app_name/shared/tmp/sockets/puma.sock fail_timeout=0;
}

server {
  listen 80;
  listen [::]:80;
  server_name your_domain.com www.your_domain.com;

  root /var/www/your_app_name/current/public;

  try_files $uri/index.html $uri @puma;

  location @puma {
    proxy_pass http://puma;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 10M;
  keepalive_timeout 10;
}

Bu yapılandırma, Nginx’in /var/www/your_app_name/shared/tmp/sockets/puma.sock adresindeki Puma soketine bağlanmasını sağlar. Capistrano, her dağıtımda current sembolik bağlantısını güncellediği için Nginx’in bu yapılandırmayı yeniden yüklemesi gerekir. capistrano-nginx gem’i bunu otomatik olarak yapar.

Dağıtım Komutları ve İşleyişi

Tüm yapılandırmalar tamamlandıktan sonra, dağıtımı başlatmak için aşağıdaki komutu kullanırsınız:

cap production deploy

Bu komutun arkasında Capistrano, bir dizi görevi belirli bir sırayla çalıştırır:

1. deploy:starting: Dağıtım başlamadan önce bazı hazırlıklar yapılır.
2. git:check: Git deposuna erişimin kontrolü.
3. git:clone: Yeni kodun sunucudaki releases dizinine kopyalanması. Her dağıtım için yeni bir dizin oluşturulur (örn. 20231027123456).
4. deploy:updating: linked_files ve linked_dirs için sembolik bağlantılar oluşturulur.
5. bundle:install: Uygulama bağımlılıkları (gem’ler) vendor/bundle dizinine yüklenir.
6. rails:db_migrate: Veritabanı migrasyonları çalıştırılır. Bu adım kritik önem taşır. Sıfır kesinti için migrasyonların non-blocking ve geriye dönük uyumlu olması gerekir. Yeni kodun gerektirdiği migrasyonlar, eski kodun hala çalıştığı bir ortamda çalışır.
7. rails:assets_precompile: Frontend assetleri (CSS, JavaScript) derlenir.
8. deploy:publishing: current sembolik bağlantısı, yeni dağıtılan sürüm dizinini işaret edecek şekilde güncellenir. Bu, Nginx’in artık yeni kodun public dizinindeki statik dosyalara erişebileceği anlamına gelir.
9. puma:phased-restart: Bu, sıfır kesinti dağıtımının kalbidir. Capistrano, Puma master işlemine SIGUSR2 sinyali gönderir.
* Puma master, yeni kodla yeni worker işlemleri başlatır.
* Yeni worker’lar hazır olduğunda, master eski worker’lara SIGTERM gönderir.
* Eski worker’lar, mevcut isteklerini tamamlar ve kapanır.
* Nginx, otomatik olarak yeni Puma soketine yönlendirilmeye başlar.
10. nginx:restart (Eğer capistrano-nginx kullanılıyorsa): Nginx yapılandırmasını yeniden yükleyerek yeni current sembolik bağlantısını ve soket yolunu tanımasını sağlar.
11. deploy:cleanup: Eski sürümlerden belirlenen sayıdan fazlası (örn. keep_releases ile 5) silinir.
12. deploy:finished: Dağıtım tamamlanır.

Bu süreç boyunca, Nginx her zaman çalışan bir Puma örneğine trafik yönlendirdiği için kullanıcılar herhangi bir kesinti yaşamazlar.

Veritabanı Migrasyonları ve Sıfır Kesinti

Veritabanı migrasyonları, sıfır kesinti dağıtımlarının en zorlu kısımlarından biridir. Yeni kod dağıtılırken, eski kod hala aktif olduğundan, migrasyonların her iki kod sürümüyle de uyumlu olması gerekir.

* Non-blocking Migrasyonlar: Uzun süren ALTER TABLE işlemleri (örneğin, büyük bir tabloya yeni bir sütun ekleme), tabloyu kilitler ve uygulamanın o tabloya erişimini engeller. Bu, dağıtım sırasında kesintiye yol açar. Bu tür migrasyonlar için pt-online-schema-change (MySQL için) veya strong_migrations gem’i gibi araçlar kullanılmalıdır. Bu araçlar, tabloyu kilitlemeden şema değişiklikleri yapmanıza olanak tanır.
* Geriye Dönük Uyumluluk: Yeni kodunuzun gerektirdiği bir veritabanı şema değişikliği yaptığınızda, bu değişikliğin eski kodunuz tarafından da sorunsuz bir şekilde işlenebilir olması gerekir. Örneğin, bir sütunu yeniden adlandırıyorsanız, önce yeni sütunu eklemeli, veriyi taşımalı, her iki sütunu da okuyup yazacak şekilde kodu dağıtmalı, ardından eski sütunu kaldıracak migrasyonu ayrı bir dağıtımda yapmalısınız. Bu, “iki aşamalı migrasyon” olarak bilinir.
* release ile Durum: Dağıtımın db_migrate adımı, current sembolik linki güncellenmeden önce çalıştırılır. Bu, migrasyonların eski kodun hala aktif olduğu bir ortamda gerçekleştiği anlamına gelir. Bu nedenle, migrasyonlar asla eski kodu bozmamalıdır.

Potansiyel Sorunlar ve Çözümler

Sıfır kesinti dağıtımları, birçok avantaj sunsa da, dikkatli planlama ve uygulama gerektiren potansiyel sorunlara sahiptir.

* Uzun Süren Veritabanı Migrasyonları: Yukarıda belirtildiği gibi, uzun süren migrasyonlar tablo kilitlenmelerine ve kesintiye yol açabilir. Çözüm, strong_migrations gibi gem’ler veya online schema change araçları kullanmak, migrasyonları küçük adımlara bölmek ve geriye dönük uyumluluğu sağlamaktır.
* Yetersiz Kaynaklar (CPU, RAM): Yeni Puma worker’ları başlatılırken, sunucunun yeterli CPU ve RAM’e sahip olması gerekir. Aksi takdirde, yeni worker’lar başlamakta zorlanabilir veya mevcut worker’lar yavaşlayabilir. Sunucu kaynaklarını izlemek ve gerektiğinde ölçeklendirmek önemlidir.
* Bağımlılık Çakışmaları: Yeni kod, eski kodla uyumsuz gem sürümleri gerektirebilir. Gemfile.lock dosyasının doğru bir şekilde yönetildiğinden ve bundle install adımının her dağıtımda doğru bir şekilde çalıştığından emin olun.
* Cache Invalidasyonu: Dağıtım sonrası önbelleklerin (Redis, Memcached) doğru bir şekilde temizlenmesi veya güncellenmesi gerekebilir. Aksi takdirde, kullanıcılar eski verileri görmeye devam edebilir.
* Rollback Stratejileri: Bir dağıtım başarısız olursa veya hatalar içerirse, hızlı bir şekilde önceki sürüme geri dönebilmek kritik öneme sahiptir. Capistrano’nun cap production deploy:revert komutu, current sembolik bağlantısını önceki kararlı sürüme çevirerek hızlı bir geri dönüş sağlar. Ancak veritabanı migrasyonları geriye alınırken dikkatli olunmalıdır. Geriye dönük uyumlu migrasyonlar, rollback’i kolaylaştırır.

Alternatif Yaklaşımlar ve Araçlar

Puma ve Capistrano ile sıfır kesinti dağıtımı yaygın bir yöntem olsa da, başka güçlü alternatifler de mevcuttur:

* Docker ve Kubernetes: Konteyner teknolojileri, uygulamaları izole edilmiş ortamlarda çalıştırmayı ve ölçeklendirmeyi kolaylaştırır. Kubernetes, dağıtımları, ölçeklendirmeyi ve hizmet keşfini otomatikleştiren bir konteyner orkestrasyon platformudur. Blue/Green veya Canary dağıtımları gibi gelişmiş sıfır kesinti stratejilerini Kubernetes üzerinde uygulamak daha kolaydır.
* Mevcut PaaS Çözümleri (Heroku, AWS Elastic Beanstalk): Bu platformlar, sıfır kesinti dağıtım mekanizmalarını genellikle kendi içlerinde sunar. Geliştiriciler, altyapı yönetimiyle uğraşmak zorunda kalmadan kodlarını dağıtabilirler.
* Blue/Green Deployments: Bu stratejide, uygulamanın iki tamamen ayrı, özdeş ortamı (Blue ve Green) bulunur. Yeni sürüm Green ortamına dağıtılır ve test edilir. Her şey yolunda gittiğinde, trafik yönlendiricisi (load balancer) Blue ortamından Green ortamına geçirilir. Eski Blue ortamı, olası bir geri dönüş için hazır bekletilir veya kapatılır.
* Canary Deployments: Yeni sürüm, başlangıçta kullanıcıların küçük bir yüzdesine (kanarya grubu) dağıtılır. Bu kullanıcı grubundan gelen geri bildirimler izlenir. Herhangi bir sorun olmazsa, yeni sürüm kademeli olarak daha fazla kullanıcıya yayılır.

Sonuç

Sıfır kesinti Rails dağıtımları, modern web uygulamaları için vazgeçilmez bir uygulamadır. Kullanıcı deneyimini iyileştirir, iş sürekliliğini sağlar ve ekiplerin daha çevik olmasına olanak tanır. Puma’nın hot restart yetenekleri, Foreman’ın süreç yönetimi ve Capistrano’nun otomasyon gücü bir araya geldiğinde, Rails uygulamalarınızı kesintisiz bir şekilde güncelleyebileceğiniz sağlam bir mekanizma oluşturur.

Bu süreç, doğru yapılandırma ve veritabanı migrasyonlarına özel dikkat gerektirse de, uzun vadede uygulamanızın kararlılığı ve kullanıcı memnuniyeti için yapılan yatırımın karşılığını fazlasıyla verir. Alternatif teknolojiler ve stratejiler de mevcut olsa da, Puma ve Capistrano kombinasyonu, birçok Rails geliştiricisi için erişilebilir ve güçlü bir sıfır kesinti dağıtım çözümü sunmaya devam etmektedir. Uygulamanızın ve ekibinizin ihtiyaçlarına en uygun yaklaşımı seçmek, başarılı bir sıfır kesinti dağıtım stratejisinin anahtarıdır.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.
Exit mobile version