Rails, Sidekiq: 전체 자습서

18394 단어 railssidekiqruby
기사 출처: https://www.bootrails.com/blog/rails-sidekiq-tutorial/
Sidekiq를 사용하면 Rails가 백그라운드에서 모든 작업을 시작할 수 있습니다.어떻게 제로에서 생산을 시작하는지 봅시다.

모티프
BootrAils에서, 우리는 창고를 가능한 한 간단하게 하려고 시도했다.
그러나 비즈니스 목적을 위해 새로운 Rails 프로그램을 만들 때, 배경 작업의 존재 수요가 곧 나타날 것이다.'비밀번호 까먹었어?'생각해봐.클로즈업이메일 한 통이 필요합니다.deliver_later는 매우 추천하는 방법으로 이런 방법은'백그라운드 작업'이 있어야만 정상적으로 일할 수 있다.
Ruby든 Rubyon Rails든 너는 이 점을 쉽게 할 수 없다.

Rails Q: handling a request, is there a good utility or idiom to run a block of code asynchronously so it doesn't block the response but also doesn't incur the overhead of a job/queue system?

do_later { fire_and_forget() }

Just have a one-off call & don't want the user to wait.

— Justin Searls (@searls)

이론적으로 ActiveJob은 모든 기본 Rails 응용 프로그램에 포함되어 있습니다.
하지만...설치, 의존 관계와 생산, 테스트와 개발 설정은 완전히 개발자가 책임진다.
이 공간에는 두 명의 거인이 있다. delayed_jobs(때로는'DJ'라고 부른다)와 Sidekiq.Sidekiq는 더욱 유명하고 유지보수되며 기록됩니다. 새로운 Rails 프로그램인 YMMV에서Sidekiq를 선택할 것을 권장합니다.
이 강좌는 응용 프로그램에 백엔드 작업을 설치하는 것에 대한 두려움을 없애는 데 목적을 둔다. 이 프로그램의 주요 목적은'그냥 MCV'이다.

선결 조건
다음은 이 자습서에서 사용할 도구입니다.
$> ruby -v  
ruby 3.1.0p0 // you need at least version 3 here  
$> bundle -v  
Bundler version 2.2.11  
$> npm -v  
8.3.0 // you need at least version 7.1 here  
$> yarn -v  
1.22.10
$> psql --version  
psql (PostgreSQL) 13.1 // let's use a production-ready database locally  
$> redis-cli ping // redis is a dependency of Sidekiq
PONG
$> foreman -v
0.87.2

새로운 Rails 애플리케이션 생성 - Sidekiq 우선 순위 없음
mkdir sidekiqrails && cd sidekiqrails  
echo "source 'https://rubygems.org'" > Gemfile  
echo "gem 'rails', '7.0.1'" >> Gemfile  
bundle install  
bundle exec rails new . --force -d=postgresql --minimal

# Create a default controller
echo "class WelcomeController < ApplicationController" > app/controllers/welcome_controller.rb
echo "end" >> app/controllers/welcome_controller.rb

# Create a default route
echo "Rails.application.routes.draw do" > config/routes.rb
echo '  get "welcome/index"' >> config/routes.rb
echo '  root to: "welcome#index"' >> config/routes.rb
echo 'end' >> config/routes.rb

# Create a default view
mkdir app/views/welcome
echo '<h1>This is h1 title</h1>' > app/views/welcome/index.html.erb


# Create database and schema.rb
bin/rails db:create
bin/rails db:migrate

그리고 프로그램을 엽니다.rb 및 주석 해제 6행은 다음과 같습니다.
# inside config/application.rb
require_relative "boot"

require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie" # <== Uncomment
# ... everything else remains the same
그런 다음 모든 작업의 상위 클래스를 작성합니다.
# inside app/jobs/application_job.rb
  class ApplicationJob < ActiveJob::Base
  end
방주: --minimal 로고가 있는 Rails 프로그램을 만들었습니다. 이로써 작업 실행에 필요한 것을 명확하게 발견할 수 있습니다.기본 설치에서 active_job/railtie 주석이 없고 모든 작업의 부류가 존재합니다.

Rails 애플리케이션에 redis 및 sidekiq gems 추가
파일을 열고 맨 밑에 추가하기
gem 'redis'
gem 'sidekiq'
너의 종착역에서 빨리 뛰어라
bundle install
그리고 응용 프로그램에 다음 줄을 추가합니다.rb
# inside config/application.rb
# ...
class Application < Rails::Application
    config.active_job.queue_adapter = :sidekiq
# ...

Hello World 작업 만들기
app/jobs/hello world job 아래에 새 파일을 생성합니다.rb
# inside app/jobs/hello_world_job.rb
class HelloWorldJob < ApplicationJob
  queue_as :default

  def perform(*args)
    # Simulates a long, time-consuming task
    sleep 5
    # Will display current time, milliseconds included
    p "hello from HelloWorldJob #{Time.now().strftime('%F - %H:%M:%S.%L')}"
  end

end
별거 아니야.이 작업의 목적은 호출할 때 비동기적으로 실행하는 것이다.고전적인 HTTP 요청/응답은 유일하게 사용할 수 있는 루트에서 처리됩니다.그러나 HelloWorldJob에 대한 모든 액세스는 처음에 HTTP 요청에서 트리거할 수 있습니다.어떠신지 한번 봅시다.

보기에서 Hello World 작업 호출
노선을 수정하다.rb는 다음과 같습니다.
# inside config/routes.rb
Rails.application.routes.draw do
  get "welcome/index"

  # route where any visitor require the helloWorldJob to be triggered
  post "welcome/trigger_job"

  # where visitor are redirected once job has been called
  get "other/job_done"

  root to: "welcome#index"
end
애플리케이션/디렉터/기타 디렉터를 생성합니다.rb
# inside app/controllers/other_controller.rb
class OtherController < ApplicationController

  def job_done
  end

end
응용 프로그램/보기/기타/작업이 완료되었습니다.html.직원 재교육국
<!-- inside app/views/other/job_done.html.erb -->
<h1>Job was called</h1>
현재, 우리의 업무는 최초의 각도에서 호출할 준비가 되어 있다.
<%# inside app/views/welcome/index.html.erb %>
<h1>This is h1 title</h1>

<%= form_with url: welcome_trigger_job_path do |f| %>
 <%= f.submit 'Launch job' %>
<% end %>
다음과 같이 디렉터 내부에서 호출이 수행됩니다.
# inside app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController

  def trigger_job
    HelloWorldJob.perform_later
    redirect_to other_job_done_path
  end

end

파일을 추가합니다.덕부
지금 모든 작업을 시도하고 싶을 수도 있지만, 잠시만 기다려 주십시오. 우리의 작업은 다른 라인에서 보내야 합니다.프로젝트 루트에 Procfile.dev 파일을 추가하여 로컬에서 수행합니다.
web: bin/rails s
worker: bundle exec sidekiq -C config/sidekiq.yml
config/sidekiq를 추가합니다.yml
# inside config/sidekiq.yml
development:
  :concurrency: 5

production:
  :concurrency: 10

:max_retries: 1

:queues:
  - default
마지막으로 여기에sidekiq 초기값 설정 항목을 추가합니다:config/initializers/sidekiq.rb
# inside config/initializers/sidekiq.rb

Sidekiq.configure_server do |config|
  config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/1') }
end
Sidekiq.configure_client do |config|
  config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/1') }
end
redis://localhost:6379/1는 로컬에 설치된 Redis 데이터베이스의 기본 URL입니다.여기서 사용할 수 없으면 REDIS URL이 환경 변수가 됩니다.

로컬 응용 프로그램 시작
이제 모든 것이 순조롭게 진행되었는지 볼 때가 되었다.
로컬 서버를 다음과 같이 시작합니다.
foreman start -f Procfile.dev
로컬에 표시되는 내용을 살펴보겠습니다.
localhost
로컬 서버
"작업 시작"단추를 누르면 터미널에 로그를 표시합니다.
18:43:31 web.1    | Started POST "/welcome/trigger_job" for ::1 at 2022-01-22 18:43:31 +0100
18:43:31 web.1    | Processing by WelcomeController#trigger_job as HTML
18:43:31 web.1    | [ActiveJob] Enqueued HelloWorldJob (Job ID: 9b9aa325-d118-45ff-a74b-99cad73ecda8) to Sidekiq(default)
18:43:31 web.1    | Redirected to http://localhost:5000/other/job_done
18:43:31 web.1    | 
18:43:31 web.1    | Started GET "/other/job_done" for ::1 at 2022-01-22 18:43:31 +0100
18:43:31 web.1    | Completed 200 OK in 4ms (Views: 3.3ms | ActiveRecord: 0.0ms | Allocations: 2644)
18:43:31 web.1    | 
18:43:31 worker.1 | 2022-01-22T17:43:31.776Z pid=3002 tid=3ze class=HelloWorldJob jid=166d945e2b7cd15e37addc7c INFO: Performing HelloWorldJob (Job ID: 9b9aa325-d118-45ff-a74b-99cad73ecda8) from Sidekiq(default) enqueued at 2022-01-22T17:43:31Z
18:43:36 worker.1 | "hello from HelloWorldJob 2022-01-22 - 18:43:36.784"
18:43:36 worker.1 | 2022-01-22T17:43:36.785Z pid=3002 tid=3ze class=HelloWorldJob jid=166d945e2b7cd15e37addc7c INFO: Performed HelloWorldJob (Job ID: 9b9aa325-d118-45ff-a74b-99cad73ecda8) from Sidekiq(default) in 5008.15ms
18:43:36 worker.1 | 2022-01-22T17:43:36.786Z pid=3002 tid=3ze class=HelloWorldJob jid=166d945e2b7cd15e37addc7c elapsed=5.47 INFO: done
실제 상황을 볼 수 있도록 간단한 버전의 로그를 복사하거나 붙여 넣었습니다.GET "/other/job_done"에서 즉시 촉발18:43:31;실제로 이 작업은 5초 뒤에 호출된다18:43:36.이른바'배경 작업'이다.

레일과 측면 벽을 생산 라인으로 밀어냄
다음 단계를 따르십시오.
# heroku is connected
heroku login  
heroku create  

# This will modify local files
echo "web: bundle exec puma -C config/puma.rb" > Procfile  
echo "worker: bundle exec sidekiq -e production -C config/sidekiq.yml" >> Procfile  
bundle lock --add-platform x86_64-linux  

# This will modify you heroku app
heroku addons:create heroku-postgresql:hobby-dev  
heroku addons:create heroku-redis:hobby-dev
heroku buildpacks:add heroku/ruby  

git add . && git commit -m 'ready for prod'  
git push heroku main  

# app works, but worker (for background jobs) is missing
heroku ps:scale worker=1

지금까지는 모든 것이 정상적으로 일해야 한다.
각 Heroku 의존 항목을 올바르게 설정하려면 1분(최대 2분)을 기다립니다.
브라우저에서 프로그램을 엽니다. (URL은heroku.com을 포함해야 하기 때문에 이번에localhost를 시도하지 않습니다.)
"시작"단추를 다시 누르고 입력을 통해 로그를 검사합니다
heroku logs
"Hello World"를 정확하게 인쇄한 일꾼을 볼 수 있습니까?Sidekiq 유효합니다!

마지막 한마디(경고)
배경 작업은 종종 예외적인 상황을 아무런 원망도 없이 받아들인다.Redis 데이터베이스에 연결할 수 없습니까?그것은 너에게 알려주지 않을 것이다.벌레가 나타났어?이 가능하다, ~할 수 있다,...따라서 HelloWorldJob이 사용할 수 있도록 유지(Sidekiq가 작동하는지 빠르게 수동으로 검사)를 통해 모든 정상적인 작업을 확보하고 처음부터 Sidekiq 웹 UI를 설치하는 것이 좋습니다.

좋은 웹페이지 즐겨찾기