fysh blog

備忘録とかにする予定

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