リモートワーカーにpovo2.0はオススメできそう
満を持してiPhone13にした。
— shmokmt (@shmokmt) January 11, 2022
5年前に比べてiPhoneもLINEも移行が簡単になっててすごい。 https://t.co/OcLDMNatF4
先日、iPhone8からiPhone13に変えるついでにキャリアも見直してUQ Mobileからpovo2.0に変更しました。
UQ Mobileを使っていたときは毎月1980円ぐらい払っていたのですが、 povo2.0に切り替えてからは毎月990円ぐらいに落ち着きそうです。
povo2.0は基本料0円で都度購入する形なので、 リモートワーカーはかなり安上がりになるんじゃないかなーと思っています。*1
*1:自分はデータ追加3GB(30日間)税込990円/回を月に1回の頻度でしています
AWS Certified Solutions Architect – Associate に合格した
自信をつける意味合いを込めて、AWS SAAを受験したところ合格できました。 資格試験は3年ぶりぐらいだったので、緊張しました。
ITベンダー系の資格は合格すると、Credlyというサービスで合格した証のバッジがもらえるようです。 www.credly.com
まあなんとかなるだろうというすごく楽観的な気持ちでUdemyの模擬試験を受けたら、正答率が60%ぐらいだったので 1週間ぐらいちゃんと勉強しました。
やったこと
基本的にこの2つだけです。個人的にはテキストだけだと模擬試験の問題数が少ないため、試験対策としては不十分だと感じました。 Udemyの模擬試験を中心に対策することで合格にはかなり近づけるとは思うのですが、 付け焼き刃感は否めません。時間がある方は実際にAWSのコンソール上で主要なサービスを触ってみるのが良さそうです。
備考
今回はテストセンター秋葉原昭和通り口 で受験しました。 係員の方の案内がスムーズでとてもよかったので、また機会があればこちらの会場を利用したいです。
2022年になった
2021年の振り返り
仕事
転職した。 バックエンドエンジニアという枠で採用されたものの1on1で「インフラも実は興味があって、チャンスがあればやらせて欲しい」という旨を上司に伝えたところいつの間にかSREになっていた。まだまだスキルは乏しいため、自らSREと名乗るのは若干抵抗がある。 リモートワーク中心のスタイルで新しい会社のカルチャーに慣れながら、 新しい職種としてキャッチアップしていった1年だった。 今年もチームの一員として頑張りたい。
生活
入籍した。引っ越した。車買った。 ほぼ入籍と同時期に同棲を開始したため、生活環境を整えたり、それに慣れていたりした1年だった。 新型コロナウイルスの影響でバカンス的な何かはほとんどできてないのが残念。 あとはお金の勉強の一環で積立NISAとふるさと納税を始めてみた。
2022年やりたい
2021年はプライベートが忙しくて、あんまりオープンな活動ができなかった。 2022年は一つぐらい何かアウトプットしたい。
nginxのシグナルについて
nginxのドキュメントを読んでいて気づいたのですが、 nginxのmaster processおよびworker processはTERMを受信するとgraceful shutdownしてくれないみたいです。 なんでnginxのDockerコンテナでエラーが起きないんだろうと思っていたところ、 Dockerイメージ側でgraceful shutdownの対応がされているようでした。
Nginx の Docker コンテナがデフォルトで graceful shutdown になってちょっと幸せ - Qiita
Use TERM as STOPSIGNAL. · nginxinc/docker-nginx@16ec71e · GitHub
2021/12/25:訂正 コミットのURLを間違えて掲載していました。 graceful shutdown対応のコミットは下記のURLになります。 @shogo82148さんに指摘をいただきました。ありがとうございます!
日頃あまり読まないドキュメントに目を通すと新たな発見があって、面白いですね。
actions-setup-tfcmtを作ってみた
suzuki-shunsuke/tfcmtをsetupするアクションを書いてみました。
tfnotify はメンテされていないので、tfcmt と比較する。tfcmt は Terraform での通知に特化しているので多くの優位点がある。その内容は tfcmt の README にある通りだが、 * 結果がより見やすい * 削除時に警告される * PR にラベルが付与される * terraform 以外での変更が行われた部分をわけて表示する * github-comment と連携し、過去の comment を hide する
tfcmtは上記のようにPRがコメントで荒れにくい!差分が見やすい!といった本当に顧客が求めていた機能が備わっています。 今回は初めてのActionの公開だったため他のAction*1の実装を参考にしながら、 とりあえず動くという状態まで頑張ってもっていってみました。
トランザクション中にMySQLに再接続するということについて
問題
Ruby on Railsではコネクションプーリングが基本的に有効になっていて、コネクションが使い回されるという仕組みになっています。 Auroraにフェイルオーバーが発生し、マスターがレプリカに降格した場合は コネクションがレプリカに向き続けてしまってWriteを発行したらエラーが発生してしまうという問題があります。 この問題に対処するためにアプリケーション側でよしなにフェイルオーバーに気づき、再接続する仕組みを入れないといけないのです。
一般的に ActiveRecord::StatementInvalid
や Mysql2::Error
をキャッチして、--read-only
なエラーだったら
コネクションを再接続するというgemを使ったアプローチが取られることが多いようですが、これは本当に適切なのでしょうか? :thinking_face:
トランザクション内で再接続された場合はどうなるんだろうと思い、調べてみました。
ActiveRecord::Base.transaction do foo = User.new(name: "foo") foo.save! ActiveRecord::Base.connection.reconnect! // 状況を再現しやすいようにわざと再接続してみる bar = User.new(name: "bar") bar.save! end puts User.count # 2か0を期待したいが、1が返ってくる
上記の場合ですと、コネクションが切断された段階でデータベースはロールバックされ、ロックが解除されたりします。
しかし、ActiveRecord::Base.transaction
は例外を検知しているわけではないので、後続の処理が実行されます。
後続の処理はauto-commit modeで実施されるため、不整合が発生する可能性があります。
これはおそらくdatabase.yml
に書く reconnect
のオプションと実質同じなんじゃないかと思っています。
解決策
- トランザクション外のどこかのライフサイクルでフェイルオーバーを検知し、再接続する機構を入れる(トランザクション内の場合なら切断して、例外を上げる)
- トランザクションが失敗した場合は抜けて再びトランザクションを貼り直して再試行する
が正しいと思っています。
前者の仕組みとして、active_record_mysql_xverify
というgemがあるようです。
active_record_mysql_xverify - so what
GitHub - winebarrel/active_record_mysql_xverify
このgemはコネクションをプールからcheckoutするときに
前回エラーが発生したというフラグを持っているかつinnodb_read_only
が有効だったら、再接続するというアプローチを取っています。
むやみに毎回チェックするわけではないのが良いですね。
ですが、unicornみたいなprefork型のサーバーだと1つのプロセスに対して、1つのコネクションが使われ、そもそもプールに返却されることがないっぽい(?)ので
上記のgemは効果的な解決策にならないみたいです。
また、Delayed JobのバックエンドとしてActive Recordを使っている場合はどこかで再接続する仕組みを用意しなければならず面倒ですね。
Delayed Jobにはlifecycleというフックポイントがいくつか用意されており、これを活用するといいんじゃないかという結論に至りました。
lifecycle.before(:error)
と書くことでジョブが再試行される前にコネクションが再接続されると思います。
class Delayed::Plugins::ClearConnectionsOnError < Delayed::Plugin callbacks do |lifecycle| lifecycle.before(:error) do |_worker, _job| is_read_only = ActiveRecord::Base.connection.execute('SHOW GLOBAL VARIABLES LIKE "innodb_read_only"').first.fetch(1) == "ON" if is_read_only ActiveRecord::Base.clear_all_connections! end end end end Delayed::Worker.plugins << Delayed::Plugins::ClearConnectionsOnError
終わりに
Railsノウハウ難しい・・・ 間違っていることを書いていたら、教えていただけると助かります。
合わせて読みたい
MySQL :: MySQL 5.6 リファレンスマニュアル :: 23.7.16 自動再接続動作の制御
mysql等の接続を司る下層のクラスオブジェクトは自動再接続をしちゃいけない。それを利用するトランザクション管理クラスが困る。切れても再接続して切れてないように見せ掛けたければ、その上層で別途用意すればいい。
— s/v (@sockety_v) 2011年11月30日
良い子のみんなは、MySQL Connector/Jで意味も解らずautoReconnectを使っちゃイケないよ!!切断時の例外処理をちゃんと実装するんだ!!
— Mikiya Okuno (@nippondanji) 2019年3月20日