コピペコードで快適生活

明日使えるソースを自分のために

AWS NLBとコネクションプールについて

NLBの後ろに1台足してもそっちに全然クエリが流れてこなかった。
間違っているかもしれないけど、多分こういうことじゃないかな。

コネクションプールについて

接続確立は負荷を伴うので、一度確立した接続を維持して、その中でクエリ発行することで負荷を軽減する仕組み。

クライアントの実装によるが

・プール数上限設定があってそれ以上のクエリ発行をしようとすると待つ。
・接続断が発生したあと、再度クエリを発行すると再接続確立を試みる。
・一定時間使われていないコネクションがあると閉じる(ガベージコレクタに回収させたり)
・なので、クエリ発行が休みなく正常に続いているコネクションはずっと開いたまま。

AWS NLB

NLBは単にバランシングしているだけで、実際にはその後ろにあるサーバとコネクションが確立されている。
なので、
・クエリ発行が休みなく正常に続いているコネクションはずっと同じサーバとつながったまま。
・NLBの後ろに1台足しても、クエリ発行が休みなく続く限り、新しいサーバには通信はいかない。
・クライアント側を再起動してコネクションを再接続すると、新しいサーバにも通信がいくようになる。

シェルスクリプトで対話的に選択肢を選ばせる

よく忘れるのでメモしておく。

#
# 入力値チェック/セット
#
echo 'CloudFrontログを抽出します。'
echo '対象ドメインを番号で指定してください'
echo '
1) a.example.com
2) b.example.com
3) c.example.com
'
read num
case ${num} in
  1)
    DOMAIN='a.example.com'
    CF_ID='xxxxx'
    ;;
  2)
    DOMAIN='b.example.com'
    CF_ID='xxxxx'
    ;;
  3)
    DOMAIN='c.example.com'
    CF_ID='xxxxx'
    ;;
  *)
    echo '番号が不正です'
    exit
    ;;
esac

PostgreSQLでプロセスとロック状況を確認する

## 実行中のSQLを確認する。
SELECT * FROM pg_stat_activity;

## 実行中のSQLを確認する
## スロークエリとか主に見る分だけ
SELECT pid, query_start, substr(query, 0, 80) AS query FROM pg_stat_activity WHERE state='active' ORDER BY query_start;

## ロック状況の確認
SELECT l.pid, db.datname, c.relname, l.locktype, l.mode
FROM pg_locks l
LEFT JOIN pg_class c ON l.relation=c.relfilenode
LEFT JOIN pg_database db ON l.database = db.oid
ORDER BY l.pid;

## AccessExclusiveLockロックがかかっているか
SELECT l.pid, db.datname, c.relname, l.locktype, l.mode
FROM pg_locks l
LEFT JOIN pg_class c ON l.relation=c.relfilenode
LEFT JOIN pg_database db ON l.database = db.oid
WHERE l.mode = 'AccessExclusiveLock'
ORDER BY l.pid;

## Railsのマイグレーションでロックをかけない呪文
## デフォだとSELECTも通さないAccessExclusiveLockがかかる
class AddStatusToUsers < ActiveRecord::Migration
  disable_ddl_transaction!

  def up
    # 略
    Users.find_each do |user|
      user.update_columns(status: 'xxx')
    end
  end

  def down
    # 略
  end
end

## インデックス追加中にロックかけない
## (concurrentlyオプションを有効にする)
## https://thoughtbot.com/blog/how-to-create-postgres-indexes-concurrently-in
class AddIndexToAsksActive < ActiveRecord::Migration
  disable_ddl_transaction!

  def change
    add_index :asks, :active, algorithm: :concurrently
  end
end

メモ

PostgreSQL×Rails環境でのマイグレーションで、バカでかいテーブルに対して、add_column + eachまわしてupdate ということをやると、こうなる。

・add_columnsで、AccessExclusiveLockかかる。
・AccessExclusiveLockの中でeachでUPDATE走る。
・AccessExclusiveLockはSELECTも通さないロックなので、
 該当テーブルに対するSELECTがすべて待ちになる。
・待ちのSELECTでDBプロセス食い尽くす。
・DBが応答なくなる。
・障害発生 :unko:

Imagemagickコマンドメモ

## 黒塗り / 中央寄せ / リサイズせず正方形に整える
convert -background black -gravity center -extent 960x960 tamanegi.png _tamanegi.png

## 白色を透過に変える(transparent) / 白から5%くらいずれていても透過させる(fuzz)
convert input.png -fuzz 5% -transparent white output.png

## 複数の画像をマージする。
## 横につなげる
convert -append 01.png 02.png out.png

## 縦につなげる
convert +append 01.png 02.png out.png

## 横につなげる + 上下左右に30の余白を開けて連結する
convert -append -border 30x30 01.png 02.png out.png

## 文字画像を作る
convert -size "256x128" -background "#f5f5f5" -fill "#dc143c" caption:"image\nmagick\n" output.png

sidekiqをGracefulShutdownする

# >= 5.0.0
kill -TSTP [worker_pid]

# < 5.0.0
kill -USR1 [worker_pid]

# すると、
# 該当のworkerにキューが入らなくなる。
# psコマンドでみたときに stopping がつく。
sidekiq 4.2.10 app_name [0 of 8 busy] stopping

# busyが0になったら、-TERM送って終了
kill -TERM [worker_pid]

sidekiq を安全に止める - Qiita より

goenv環境でdepを使うメモ

QuickStart

まずはこれでgoenvをインストールする。
http://kinosuke.hatenablog.jp/entry/2019/04/11/104837

# depのインストール
# ※GOPATH以下にインストールされる
go get -u github.com/golang/dep/cmd/dep

# goenv環境でやるとdepコマンドのパスが通らないので、とりあえずパス指定で実行する。
# パスを通してもいいけど、goのバージョン切り替えるたびにパス変えるのめんどくさいかも。

# 現在の構成を解析して Gopkg.toml、Gopkg.lock を生成
"${GOPATH}/bin/dep" init

# パッケージをvendorディレクトリ以下にインストール
"${GOPATH}/bin/dep" ensure

# 新しいパッケージを追加
"${GOPATH}/bin/dep" ensure -add github/gin-gonic/gin

# パッケージをアップデート
"${GOPATH}/bin/dep" ensure -update github/gin-gonic/gin

# 現在の状態を出力する
"${GOPATH}/bin/dep" status

参考
Goオフィシャルチーム作成の依存関係管理ツール dep を試してみた | DevelopersIO

RspecでSQLやRailsのログを出力したい

こんな感じで

# spec/rails_helper.rb

# 略

Rails.logger = Logger.new(STDOUT) # Rails.loggerを出す
ActiveRecord::Base.logger = Logger.new(STDOUT) # SQLログ出す

RSpec.configure do |config|
  # 略
end

※STDOUTは組み込み変数

STDOUT.puts "hogehoge"

のようにすれば標準出力される。