AWS で ISUCON9 予選の練習環境を構築する

自分用のメモをそのまま貼り付けているので雑です。

参考ページ

サーバーのセットアップ

  • 構成
    • webapp 1台、bench 1台の2台構成で始める (あとで webapp を増やす)
    • 外部サービス (shipment/payment) は bench に同居させる
  • EC2 インスタンスを立てる
    • webapp, bench 用の2台
    • OS は Ubuntu 18.04
    • インスタンスタイプは c5.large (2vCPU, 4GB RAM)
    • EBS は gp2 40GB
    • webapp のホスト名は webapp1 とする
    • webapp1, bench にそれぞれ EIP を割り当てておく
  • SSH 接続するための設定を書く
    • 初期ユーザー名は ubuntu
  • root ユーザーの SSH 設定変更
    • 初期状態だと root ユーザーで直接ログインできないようになっている
      • Please login as the user "ubuntu" rather than the user "root". というメッセージが出て接続が切られる
    • webapp, bench にログインし、root の authorized_keys を書き換える
    • 面倒なので ubuntu ユーザーのをコピーした
$ sudo su -
# cd .ssh
# mv authorized_keys{,.bak}
# cp /home/ubuntu/.ssh/authorized_keys .
cd initial-data
make
  • provisioning/inventory/hosts を編集し、webapp と bench のホスト名を入れる
    • このとき、bench のホスト名がグループ名と一緒だと ansible 実行時に warning が出たので isucon-bench とした
[webapp]
webapp1

[dev]
isucon-bench

[bench]
isucon-bench
  • プロビジョニングの時間短縮のため、provisioning/webapp.yml の roles から使わない言語をコメントアウトする
  • provisioning ディレクトリに移動して、ansible を実行する
    • webapp は4分、bench は2分、dev も2分ぐらいで終わった
ansible-playbook webapp.yml -i inventory/hosts
ansible-playbook bench.yml -i inventory/hosts
ansible-playbook dev.yml -i inventory/hosts
  • ここで一旦 webapp, bench の AMI を作成した

SSL の設定

  • 今回は雑に無料ドメインを取得した
  • Route53 で以下のようにレコードを作成する
  • DNS 認証で Lets' Encrypt の証明書を取得して以下に配置
    • /etc/nginx/ssl/fullchain.pem
    • /etc/nginx/ssl/privkey.pem
  • nginx の server_name も修正して reload する
  • 設定したドメインでアクセスできればOK
  • ここで再度 AMI を作成しておく

画像データのダウンロード

webapp で以下を実行し、画像データをダウンロードする。

sudo su - isucon
cd isucari/webapp/public

# 注意: 1.5GBくらいあるので時間がかかります
wget https://github.com/isucon/isucon9-qualify/releases/download/v2/initial.zip

sudo apt install unzip
unzip initial.zip
rm -rf upload
mv v3_initial_data upload

bench で以下を実行し、画像データをダウンロードする。

sudo su - isucon
cd isucari/initial-data

# 注意: 1.5GBくらいあるので時間がかかります
wget https://github.com/isucon/isucon9-qualify/releases/download/v2/bench1.zip

sudo apt install unzip
unzip bench1.zip
rm -rf images
mv v3_bench1 images

ベンチマーカーの実行

ここまでくればいよいよ benchmarker を実行できる。

benchmarker 実行時、shipment/payment がすでに起動しているとエラーになってしまう。
provisioning 直後だと shipment と payment が自動的に起動しているので、手動で stop してから benchmarker を実行する。

sudo systemctl stop shipment
sudo systemctl stop payment

cd isucari
./bin/benchmarker \
  -payment-url https://payment.example.com \ 
  -shipment-url https://shipment.example.com \ 
  -target-host webapp1.example.com \
  -target-url https://webapp1.example.com

verify が通ってスコアが出ているのでよさそう!

2020/09/06 07:31:02 main.go:180: === final check ===
2020/09/06 07:31:02 main.go:212: 2510 0
{"pass":true,"score":2510,"campaign":0,"language":"Go","messages":[]}

ハマったところ

  • benchmarker の verify が通らない (1)
    • failed to requst to shipment service が出る
    • benchmarker の -payment-url-shipment-url にポート番号を含めていたのを消したら解消した
    • benchmarker -help を見るとポート番号がついてるのに…
  • benchmarker の verify が通らない (2)
    • アプリレイヤーの謎エラーが出る
    • bench を provisioning したあと、同居させるつもりだった shipment, payment の provisioning を忘れていた
    • あとから ansible で dev.yml を実行したが、その際に手元の initial.sql が変更されていた
      • たぶんなんとなく cd initial-data; make してしまったのだと思う
    • そのせいで webapp, bench で initial.sql の内容が異なった状態になり、benchmarker 実行でエラーになっていた
    • initial.sql を同じ状態にして解消