Briswell Tech Blog

ブリスウェルのテックブログです

排他制御

Web基幹システム(その他でも)を構築しているとよく後勝ち問題に出くわす。

 

  • 後勝ち問題

f:id:Toshi_bw:20190312100234p:plain

後勝ち問題

上記図のように、Aさんが修正画面起動後にBさんが編集画面を起動、

後に修正画面を開いたBさんが先に保存を行い、Aさんが後で保存を行う。

すると、Bさんの修正をAさんは知らない状態なので、Bさんの修正はAさんによって上書きされてしまう。

Bさんは修正したのにされていないこととなってしまう。

 

Bさんは自分は修正できた!と思っているはずなので、何かしらで後々修正されていないことを知ることとなる。

 

業務的にこのようなことが発生する = AさんとBさんがやりたい業務が異なっており、画面の責務を分割すべき、というのももちろんあるが、一旦そこはおいておく。

(例えばAさんは顧客情報を修正しようとしており、Bさんは顧客ステータスのようなものを修正しようとしていたなど)

 

先ほどの図と同じだが、Aさんが保存をしようとした時に「Bさんが保存処理を行なったため、最初からやり直してください」 or 「Bさんが保存処理を行いました、強制的に保存を行うとBさんの修正を上書きしてしまいます」

といった処理。

具体的にはAさんが修正画面起動時に最終更新日時のようなデータを保持しておき、保存時に現在の最終更新日時と比べる。

異なっていればメッセージを表示することにより、知らずに上書きされることをある程度避けることが可能となる。

(ある程度、というのはAさんがいじわるで、強制保存を行い、Bさんに通達しないケース)

 

この処理が向いているのは、更新頻度が低く、更新者があまりいない、マスタ系に向いている。

 

f:id:Toshi_bw:20190312100904p:plain

悲観的排他制御

ほぼ一緒の図だが、今回はBさんは修正開始で終わっている。

Aさんが修正開始したタイミングで、データに編集中フラグのような物を更新する。

Bさんが修正開始しようとしたタイミングで「Aさんが何時何分から修正中です」

とメッセージを表示し、修正できないようにする方法。

Aさん保存時に編集中フラグをOFFに更新することによって、他のユーザが編集可能となる。

Aさんが途中で画面離脱するケースも想定し、何分以上保存されなかった場合は編集中フラグを自動でOFFにする、というJobも必要となる。

 

この処理が向いているのは割と更新頻度が高く、更新対象者も先ほどよりかは多くいるケース、トランザクション向き。

 

 

システム利用経験が少なかったりするユーザの場合、後勝ちを理解していない場合が多いので、システム利用前に予め説明を行い、何かしらの制御を入れるのが良いと思う。

 

 

です!

 

t1.micro サーバのお話

AWS EC2インスタンス

t1.micro

に対してメンテナンスが入ると通知があった

 

Amazon Web Services is performing a refresh on all Amazon EC2 T1.micro instances. The instance refresh will offer higher host reliability, better CPU performance and match the CPU burst experience of T1.micro instances to be consistent with T2 instances.

 」

t2インスタンス並みにCPUパフォーマンスがあがるよーと。

Starting February 1, 2019, you can stop and restart your Amazon EC2 T1.micro instances to take advantage of the instance refresh. After March 1, 2019, Amazon EC2 T1.micro instances that have not been stopped, will be scheduled for maintenance.

 」

3/1までに停止 → 開始をすることで反映されて、3/1までにやってないインスタンスは強制再起動されるよーと。

 

CPUパフォーマンスが向上するのは良いことなので、先にやってしまおうと。

結構古くから使ってるインスタンスで、社内ツールが配置されているもので対象が3台あった。

社内に通達して、停止 →  開始を3台行う、

内2台は確かにCPUの使用率は格段に下がった!!

ラッキー!

 

けど、うち1台は変わらず。。。

とりあえずAWSサポートに連絡してみると、その子はまだメンテナンス対象になってるよ、反映されてないよと言われる。

→もう一回停止 → 開始やってみる。CPUの向上は見受けられない。。

再度連絡してみる

→まだメンテナンス対象だよー、と。

 

やってるのに。。

もしこのまま対象から外れなかったら3/1 強制再起動??

手動で反映されないなら強制でも反映されなくない??

したら何回も再起動されまくるでしょ??

って連絡してみたら現状は不明ときた。

 

ってことでもうt2インスタンスに入れ替えを行なった。

というお話。

 

いつかはt1 → t2にしといた方がよかったので良いタイミングではあったが、

たまたま社内用で助かった。

 

反省点

・忙しさを理由にギリギリまで放置してた

・もっと早くやってれば計画性を持って入れ替えを行えた

・社内AWS管理が個人依存になっている

 

以上!

 

GitLab CI AWS Elastic Beanstalkとの連携

GitLab CiからAWS Elastic Beanstalk へ更新をかけてみた。

 

ソース直下に

.elasticbeanstalk

フォルダを追加し、config.ymlを作成

内容は公式ドキュメント参照

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/environment-configuration-methods-before.html

 

続いて、GitLabCIからAWSにアクセスできるように、ソース直下に

.eb-config.sh

ファイルを追加

内容は

--

#!/usr/bin/env bash
set -x
set -e

{
AWS_CONFIG_FILE=~/.aws/config

mkdir ~/.aws
touch $AWS_CONFIG_FILE
chmod 600 $AWS_CONFIG_FILE

echo "[profile bw_package]" >> $AWS_CONFIG_FILE
echo "aws_access_key_id=${AWS_ACCESS_KEY_ID}" >> $AWS_CONFIG_FILE
echo "aws_secret_access_key=${AWS_SECRET_ACCESS_KEY}" >> $AWS_CONFIG_FILE
} &> /dev/null

--

こんな感じで、GitLab CIの環境変数にIAMのアクセスキーとシークレットアクセスキーを設定しておく。

 

後は.gitlab-ci.ymlの設定

今回は下記のような感じにしてみている。

-- 

stages:
- test
- deploy

test:
image: node:latest
stage: test
script:
- npm install
 - npm run build

deploy_aws:
stage: deploy
image: python:3.6-stretch
before_script:
- pip install awsebcli --upgrade --user
- git checkout master
- chmod +x .eb-config.sh
- ./.eb-config.sh
- export PATH=~/.local/bin:$PATH
- eb --version
script:
- eb deploy

--

 

後は便利なところとして、.ebextensions

を同じくソース直下にフォルダ作成して、色々設定してあげるとenv設定とか、ロードバランサー設定とか、様々な設定系が管理できる。

万が一アプリケーション削除などを行ってしまっても、時間経過以外は問題がなくなる。

 

次はLambdaへの試してみた感じを書きます!

 

※様々な記事を参考にさせていただき、ここにたどり着きました。

GitLab CI 触ってみた

最近弊社ではソース管理にGitLabを使い始めた。

折角なので、GitLab CIを使ってみた。

まだまだ初心者中の初心者なので、ご指摘等ございましたらぜひお願いします。

 

やってみたのは下記内容

・サーバにGitLab Runnerを仕込み単純にGitから最新ソースを取得する

・Doker imageからAWS Elastic Beanstalkに更新をかける

・Doker imageからAWS S3経由でLambdaに更新をかける

 

・サーバにGitLab Runnerを仕込み単純にGitから最新ソースを取得する

CentOSにて実行

curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
yum install -y gitlab-runner

でGitLab runnerを最新ソースを取得したいサーバにinstall

gitlab-runner register

で、いくつか質問されるので、順番に回答する

 

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/)

→GitLabのURL

Please enter the gitlab-ci token for this runner:

→GitLab画面

プロジェクト → CI/CD → Runner

画面に記載されているTokenを入力

Please enter the gitlab-ci description for this runner:

[ip-172-31-43-84.ap-northeast-1.compute.internal]:

→なんか、一意の判断

Please enter the gitlab-ci tags for this runner (comma separated):

→tagが必要であれば入れる

Please enter the executor: ssh, docker+machine, kubernetes, docker, docker-ssh, parallels, shell, virtualbox, docker-ssh+machine

→種類を入力、今回はshellで作成

 

ps aux | grep gitlab
→このコマンドで、GitLab CIがどのユーザで実行されるかを確認する

今回はrootで強制的に実行したかったので、

gitlab-runner uninstall
gitlab-runner install -user root
gitlab-runner restart

の3つを実行し、再度ユーザ確認すると、rootに変わっている

 

SSHログイン時に実行するコマンドを定義

yum install expect

→installを行う
vi ~/.bash_profile

→でファイル編集

記載内容

eval `ssh-agent`

# 秘密鍵ファイル
KEY_FILENAME='id_rsa'
# パスフレーズ
PASSPHRASE='password'

expect -c "
set timeout -1
spawn ssh-add $HOME/.ssh/$KEY_FILENAME
expect {
\"Enter passphrase for\" {
send \"$PASSPHRASE\r\"
}
}
expect {
\"denied\" { exit 1 }
eof { exit 0 }
}
"

 

で、該当プロジェクトの直下に

.gitlab-ci.yml

を作成

—pullの場合—
stages:
- deploy

deploy:
stage: deploy
script:
- id
- ssh-add -l
- ssh -vT git@gitlab.com
- cd /var/www/html/

git pull origin master:master
only:
- master
tags:
- tags_name

 

で、とりあえずmaster Push時にだけ反応するように設定

developだけであればdevelopに変更すればOK

次回は
・Doker imageからAWS Elastic Beanstalkに更新をかける
・Doker imageからAWS S3経由でLambdaに更新をかける

を書きます

 

Elastic Beanstalk触ってみた感想

元々はEC2などは自前で立てて、開発や本番運用を行なっていた。

今回自社のパッケージを作成することになり、ElasticBeanstalkで構築することとした。

感想としては

・作成は全て勝手にやってくれるので、簡単

・環境をスワップできるので、stg prodみたいな環境があれば便利

・RDSは別で立てたほうが良さそう(アプリケーション、環境を削除してしまった場合データベースまで削除されてしまう、リスク排除のため)

・.ebextensions にconfigファイル追加していけば eb create コマンドだけで環境が作れる

・今回言語はnodejsなので、ローカルから eb deploy コマンドやるだけでnpm installとかは勝手にやってくれる

・pemキー発行しなければコンソールに入れない、不要なリスク排除

 

思いついたら追記

 

ただ、過去に全て自前で構築していじいじしていた経験は割と生きてる感じがする。

知ってると知っていない、の差だと思うが。

 

これならサーバ依存というのはなく、簡単にインスタンス入れ替えも可能だなー。

2019年

2019年

あけましておめでとうございます!!

 

このブログも中々更新できていませんが、本年はもう少し頻度と詳細度をあげて更新していきたいと思ってます。

 

今年もよろしくお願いします。

GitLab master Push エラー解決

最近弊社ではソース管理をGitLabに移行してまして。

ちょっと多く悩まされたのが、

"Please make sure you have the correct access rights"

この子。

 

アクセス権限確認してねって言ってるんだが、権限はしっかりある。

プロジェクトオーナーなので問題ないはず。

 

......

 

なんだろう。

 

...

 

とりあえず、protect リポジトリでmaster削除してみる

 

...

 

関係ない。

 

結果の解決策とりあえずKeyファイル作成し直し。

 

ssh-keygen -t rsa -C "GitLabのメアド" -b 4096

 

で、pub コピってGitLabに貼り付け

 

その後ローカルで

ssh-add ~/.ssh/id_rsa

 

ってやってmaster Pushでいけた。

 

無駄に悩まされた!

GitLabとAWS Codecommitの連携

GitLabでソース管理している物を、AWSのCodebuild + CodeDeploy + CodePipeline

でもろもろ自動化がしたかった。

 

GitLabをAWS上からは選べなかったので、GitLab -> Codecommit を自動連携するようにしてみた。

結構簡単で、

Codecommit、GitLabでプロジェクト作成、

AWS IAM ユーザ作成、Codecommit Fullアクセス権限を付与し、作成

 

IAMユーザ画面の認証情報タブ内、一番下の「AWS CodeCommit のHTTPS Git 認証情報」というところの生成ボタンを押してユーザ名、パスワードを取得する

 

GitLab、プロジェクト内設定 -> リポジトリから「Mirroring repositories」を選択

Push設定にして、パスワードを選択、ユーザ名入れるところなかったので、

https://"ユーザ名"@...

という形でセット

 

これでGitLabにPushしたソースは自動でCodeCommitにもあがる

 

AWS ELB スティッキーセッション

仮リリースしてたAPI サーバー冗長化するために、セッション管理をどうしようかなと思った。

CakePHP3 で構築してたので、DB管理にしてもよかったが、AWS ELB置いといたのでスティッキーセッションというのを試してみた。

 

こんな簡単なの?ってほど設定は簡単で、

ターゲットグループの維持設定を有効化するだけ。

 

後はよしなにAWS君がやってくれる。

簡単。