AWSのELBとNginxとUnicornと
クライアントからのリクエストをELBで2台のEC2(Nginx+Unicorn)に振り分ける構成を構築をしていた時に,
ヘルスチェックが想定通りに動作しない問題が発生した.
Unicornが停止していてもNginxが起動していればHealthy状態とされてしまい,そのEC2にもリクエストの振り分けが続いてしまった.
原因はNginx設定ファイルの不備.
ELBはプライベートIPアドレスによりヘルスチェックを行っていたが,その場合の設定を追記していなかった.
そのためデフォルトの設定が適用され,ドキュメントルートが指定したパスではなく/usr/share/nginx/html/
となっており,
そちらに対しヘルスチェックが行われ続けていた.
以下の設定ファイルを適用することで解決.
upstream sample_app { server unix:///opt/sample_app/tmp/sockets/unicorn.sock fail_timeout=0; } server { listen 80; server_name {ELBのDNS名}; root /opt/sample_app/public; try_files $uri/index.html $uri @sample_app; location @sample_app { proxy_pass http://sample_app; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; } } server { listen 80; server_name {EC2のプライベートIPアドレス}; root /opt/sample_app/public; try_files $uri/index.html $uri @sample_app; location @sample_app { proxy_pass http://sample_app; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; } }
Railsのbefore_createで気になったこと
Railsチュートリアル
の第11章でUserモデルにbefore_createコールバックを追加したが,User.create
メソッドは使用せずUser.new
メソッドとuser.save
メソッドを使用しているのにこのコールバックを使用する意味はあるのかと思った.(UsersController.create
の中でUser.new
メソッドとuser.save
メソッドが呼ばれる.)
class User < ApplicationRecord attr_accessor :remember_token, :activation_token before_save :downcase_email before_create :create_activation_digest validates :name, presence: true, length: { maximum: 50 } ~ end
class UsersController < ApplicationController ~ def create @user = User.new(user_params) if @user.save @user.send_activation_email flash[:info] = "Please check your email to activate your account." redirect_to root_url else render 'new', status: :unprocessable_entity end end ~ end
調べると,どのメソッドを使用するかにかかわらずuser.new_record? == true
の状態でDBに登録される時に適用されるみたい.
www.techscore.com
確かに,レコードが作成される前に,となっていて,createメソッドが呼ばれたときに,とはなっていない.
api.rubyonrails.org
Google ColabでSeleniumを使うとき
Google ColabでSeleniumを使ってWebスクレイピングをしようとしたところ,以下のコードでwebdriverのエラーが発生した.
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager options = Options() options.add_argument('--headless') options.add_argument("--no-sandbox") options.add_argument('--disable-dev-shm-usage') driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
WebDriverException: Message: Service /root/.wdm/drivers/chromedriver/linux64/108.0.5359/chromedriver unexpectedly exited. Status code was: -6
以下のようにchromedriverのパスを直接指定すると正常に動作した.
driver = webdriver.Chrome("/usr/lib/chromium-browser/chromedriver",options=options)
Google ColabではChromeDriverManagerが使えないのか調査すると,以下の記事を発見した. メモリ割り当てチェッカーを無効にする必要があるらしい. ja.stackoverflow.com
記事に倣い以下のようにコードを追加したところ,正常に動作した.
import os if 'LD_PRELOAD' in os.environ: ld_preload = os.environ['LD_PRELOAD'] del os.environ['LD_PRELOAD'] driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) if 'ld_preload' in locals(): os.environ['LD_PRELOAD'] = ld_preload