2019年のふりかえり

仕事

去年に引き続きメルペイに携わっていました。
アプリのリリースが今年の2月ですが、遠い昔のようであまり実感がないですね。
今年も去年と同様濃い1年だったなぁと感じます。仕事でもプライベートでも。

業務はというと、6月までCSツールや加盟店の登録・審査ツールのバックエンド開発をしていました。
前半は、ひとつのツールとして大きくなってしまったmicroserviceの分割をするためにgRPCのproxyを調べたり、protoで表現したオペレータの権限をAPI経由で伝搬するためにprotoreflectを調べたり、ちょこちょこやっていた気がします。
後半は、調査を活かしてゴリッとコードを書いて移行作業をしました。やっぱり何度やってもデータ移行はたいへんですね。

そして7月からアーキテクトというチームに移動しました。
これまでビジネスに沿ったプロダクト開発がメインでしたが、いまはプロダクティビティやクオリティの向上だったり下回りの整備をメインにやっています。
具体的には、かしこいリトライの仕組みを導入したり、最近だとgrpc-godns resolverに関するバグを見つけて報告したりしています。
英語を書く機会が増えたので、これを機にまじめに勉強しようかなと思ったりしています。

競技プログラミング

6月くらいに社内の競プロ部に参加して以来、すこしハマりました。
競プロといってもほとんどAtCoderのことを指しています。

僕は大学をでておらず高校の授業も寝て過ごしていた人間なので算数・数学力が赤ちゃんでした。
ですが、競プロをはじめたおかげで晴れて幼児に成長しました。

普段仕事で使う脳みそとは別の部分が働いている感じがして楽しいです。
レートはいまだに700あたりをふらふらしているのですが、気長にやろうと思ってます。

生活

今年はプライベートで大きな出来事がありました。

結婚

結婚しました。7月に。
理由はいろいろありますが割愛します。

2018年の年末に結婚しようと決意して、2019年1月に結婚相談所に登録、2月に初対面、4月にプロポーズして7月に入籍なので、スピード感ありますね。
たまたま運よくよいひとと出会えてよかったです。

一緒に暮らし始めてからは、以前より健康的な生活を送っています。
家でパソコンをさわる時間は減りましたが、かわりに一緒に散歩したり買い物にいったりしています。

結婚生活はいまのところとても良いです。

今年も一年おつかれさまでした。よいお年を。

Amazon ECSを試したメモ

雰囲気をつかむこと・動かすことを優先に考えてポチポチ。

方針

  • Nginx + PHP-FPM
  • GitHubリポジトリのmasterに変更があったら自動デプロイ
    • pull-req mergeでデプロイ
    • pull-req revertでロールバック
  • デプロイ時にシングルタスク(e.g. database migrate)を実行
  • ログはCloudWatch
  • なんとなく本番っぽいフロー

GitHubリポジトリのmasterを更新して、CodePipelineから自動デプロイされたら成功 :)

ソースコード

github.com

やったことメモ

リポジトリ作成

Elastic Container Service > Amazon ECR > リポジトリ
ポチポチするだけで、特に悩むことはない。
イメージの追加は、あとでCode Pipelineで行う。

ロググループ作成

CloudWatch > ログ > アクション
あとでコンテナで使用する。
ロググループ名はecstestにした。

ECSタスク定義作成

Elastic Container Service > Amazon ECS > タスク定義

ラベル
タスク定義名 ecstest
タスクロール なし
ネットワークモード default
タスクメモリ(MiB) 256
タスクCPU(単位) 256

コンテナの追加

PHPの設定。表に立たないのでポートマッピングはしない。 ヘルスチェックはいったんなし。
ログはawslogsを使用する。ロググループ名は前述で作成したものを指定する。

ラベル
コンテナ名 ecstest-php
イメージ XXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecstest-php:latest
メモリ制限(MB) ハード制限, 128
ログ設定 awslogs, awslogs-group:ecstest, awslogs-region:ap-northeast-1, awslogs-stream-prefix:php

Nginxの設定。ポートマッピングをする。
ecstest-phpをリンクする。aliasはNginxの設定に合わせてphpfpm。
ログはawslogsを使用する。prefixだけPHPの設定と違うものにする。

ラベル
コンテナ名 ecstest-nginx
イメージ XXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecstest-nginx:latest
メモリ制限(MB) ハード制限, 128
ポートマッピング ホストポート:なし, コンテナポート:80, tcp
リンク ecstest-php:phpfpm
ログ設定 awslogs, awslogs-group:ecstest, awslogs-region:ap-northeast-1, awslogs-stream-prefix:nginx

ロードバランサー作成

EC2 > ロードバランサー
ECSサービスで使用する。

Application Load Balancerを選択。

ラベル
名前 ecstest
スキーム インターネット向け
IPアドレスタイプ ipv4
リスナー プロトコル:HTTP, ポート:80

VPC, アベイラビリティゾーン, セキュリティグループはよしなに。

ラベル
ターゲットグループ 新しいターゲットグループ
名前 ecstest
以下略 デフォルト値

ターゲットの登録では何も選択しない。

ECSクラスター作成

Elastic Container Service > Amazon ECS > クラスター

EC2 Linux + ネットワーキングを選択。

ラベル
クラスター名 ecstest
プロビジョニングモデル オンデマンドインスタンス
EC2 インスタンスタイプ t2.micro
インスタンス数 1
EBSストレージ(GiB) 22
キーペア なし
コンテナインスタンスIAMロール ecsInstanceRole(default)

VPC, サブネット, セキュリティグループはよしなに。

サービス作成

ecstestクラスター > サービス
リポジトリにイメージを追加していないので、タスクは立ち上がらないけど、いったん気にしない。

ステップ1: サービスの設定

最大率200は指定タスク数の200%まで許容する。
うっかりインスタンスのメモリ上限を超えるとデプロイに失敗したりする。

ラベル
タスク定義 ecstest:1
クラスター ecstest
サービス名 ecstest
タスク数 1
最小ヘルス率 50
最大率 200
配置テンプレート AZ バランススプレッド

ステップ2: ネットワーク構成

ラベル
ELBタイプ Application Load Balancer
サービス用IAMロールの選択 AWSServiceRoleForECS
ELB名 ecstest

コンテナの選択からecstest-nginx:0:80を追加。

ラベル
リスナーポート 80:HTTP
ターゲットグループ名 ecstest

ステップ3: Auto Scaling

デフォルトのまま。

CodePipeline作成

AWS CodePipeline

ステップ1: 名前

ラベル
パイプライン名 ecstest

ステップ2: ソース

ラベル
ソースプロバイダ GitHub
リポジトリ utahta/php-ecs-sample
ブランチ master

ステップ3: ビルド

CodeBuildプロジェクトを作成して保存する。

ラベル
ビルドプロバイダ AWS CodeBuild
プロジェクトの設定 新しいビルドプロジェクトを作成
プロジェクト名 ecstest
環境の設定
環境イメージ AWS CodeBuildマネージド型イメージの使用
OS Ubuntu
ランタイム Docker
バージョン aws/codebuild/docker:17.09.0
ビルド仕様 ソースコードのルートディレクトリのbuildspec.ymlを使用
キャッシュ_
タイプ なし
CodeBuildサービスロール アカウントで新しいロールを作成します
ロール名 code-build-ecstest-service-role

VPC, サブネット, セキュリティグループはよしなに。

アドバンストの環境変数を設定。buildspec.ymlで使用する。

Key Value
AWS_ACCOUNT_ID XXXXXXXXX
AWS_DEFAULT_REGION ap-northeast-1

ステップ4: デプロイ

ラベル
デプロイプロバイダ Amazon ECS
クラスター名 ecstest
サービス名 ecstest

ステップ5: サービスロール

ラベル
ロール名 AWS-CodePipeline-Service

IAM編集

IAM > ロール > code-build-ecstest-service-role

AmazonEC2ContainerRegistryFullAccessをアタッチ。
イメージの追加に必要。

AmazonEC2ContainerServiceFullAccessをアタッチ。
ECSのタスク実行に必要。本当はタスク実行のみ許可するポリシーを作成してアタッチした方が良いけど省略。

ECSタスク定義作成(シングルタスク)

Elastic Container Service > Amazon ECS > タスク定義

デプロイするときに合わせて実行するタスク(仮)の作成。
ここではdatabase migrateを想定したタスクを作る。
メモリ・CPUは適当。

ラベル
タスク定義名 ecstest-migrate
タスクロール なし
ネットワークモード default
タスクメモリ(MiB) 256
タスクCPU(単位) 256

コンテナの追加

コマンドの設定。ヘルスチェックはなし。ログはawslogsを使用する。
コマンドにmigrateコマンド(仮)を指定する。

ラベル
コンテナ名 ecstest-migrate
イメージ XXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecstest-php:latest
メモリ制限(MB) ハード制限, 128
コマンド php,worker.php
ログ設定 awslogs, awslogs-group:ecstest, awslogs-region:ap-northeast-1, awslogs-stream-prefix:migrate

おわり

ECSよりもNginxの設定でハマった。

参考

Amazon ECS
AWS CodePipeline
Twelve-Factor App

Neovimに移行したしせっかくなのでGoでプラグインを書いてみた

github.com

Google翻訳APIを使ってテキストを翻訳するプラグイン。
作ったあとにVim & Go界隈で著名なhaya14busaさんがほぼ同じプラグインを作ってることに気づきました。

trans_nvim_previe_log

neovim/go-clientを使っていてNeovimでしか動きません。
(python-clientの方だとNeovim/Vim8で手軽に両立するやり方がある模様)
プラグインのインストールにGoが必要です。

サンプルが手薄だったり実装の参考になりそうな他のプラグインがzchee/nvim-goくらいしかみつからなかった(とはいえめっちゃ参考になった)ので、わりとneovim/go-clientのコードとにらめっこしながら書きました。

苦労したところは、previewってどうやってつくるんだろう?とかvim的な知識の足りなさ。一体何をどうするのが正解なのか未だによく分からんです。
ちなみに自分の行き着いたpreviewの作り方は次のとおり。

trans.go#L175:L203

  1. silent pclose
    • previewをとりあえず閉じる
  2. silent pedit +set noswapfile buftype=nofile translated
    • ファイルなしでpreviewを開く
  3. wincmd P
    • previewに移動する
  4. neovim/go-clientのメソッドを使って文字列をクリアして書き込む
  5. wincmd p
    • previewから抜ける

果たしてこれで合っているのか...?という気持ちですが、今のところ動いてるので良し。もしダメだったらpull-reqください。
あと誰かこの泥臭い部分を隠蔽するいい感じのラッパー作ってください!

おわり

Goだけで完結できるわけではない(vimのコマンドを直接叩いたりする)
それでもvim scriptを書くより敷居は低いし楽しい。