SQS メッセージ送受信 & SES メール送信 (PHP)

いきなり余談ですけど、以前購入したまま中途半端になってた AWS のオンライン講座を改めて見直してみました。マネジメントコンソールとか設定できるパラメータはいろいろ変わってるところはあっても、基礎的なところはあまり変わってなくて、オンライン講座のコンテンツとしてまだ全然有用そうな印象を受けました。

そのオンライン講座の中で、SQS と SES を組み合わせるちょっとした課題があったので備忘録。初めて PHP を書きました。

  1. SQS メッセージ送信 (メッセージに送信元/送信先/タイトル/本文を含む)
  2. SQS メッセージ受信 & メール送信 (メール送信したらメッセージを削除)

SQS メッセージ送信

gist.github.com

SQS メッセージ受信 & メール送信

gist.github.com

JSUG勉強会 2020 その3 Spring Cloud without Netflix OSS に行ってきた #jsug

JSUG勉強会 2020 その3 Spring Cloud without Netflix OSS に参加しました。今回はオンライン開催。簡単に所感をまとめます。

jsug.doorkeeper.jp

所感

Spring Cloud やマイクロサービスはあまり知識がないため、自分にはなかなかハイレベルな内容でした...。後半2つのセッションは若干内容が被ってたけど、特に最後のセッションは Kubernetes 絡みの事例で貴重な内容だったかも。こういうのをしっかり理解できるようになりたいものです。

ところどころ、Spring Cloud 関連は EOL が短い傾向あり?という話が出てたのが気になる。そんなに困らないということだったけど、後方互換はちゃんと考慮されてる感じなんだろうか。

Spring Cloud のようなマイクロサービス向けのライブラリは、アーキテクチャや設定などがサービスやライブラリ間で疎結合になるように工夫されてるような印象があります。最初は覚えるのが大変そうだけど簡単に運用できるようになってるんだろうと思います。

以下、メモから抜粋。

Introduction to Resilience4j

  • フォールトトレランスライブラリ
    • サーキットブレイカ
  • Netflix OSS
    • Eureka, Zuul 以外は保守モードに移行
    • Spring Cloud Netflix も同様
  • Hystrix の代替の1つとして Resilience4j
  • 関数型プログラミングモデル
  • コアモジュール☆
  • アドオンモジュール☆
  • recover に代替処理を記述
  • サーキットブレイカーの状態遷移☆
    • CLOSED, OPEN, HALF_OPEN
    • Resilience4j にはもう2つの状態がある
    • OPEN から一定時間経過すると HALF_OPEN
  • スライディングウィンドウ (呼び出し結果を保存する配列)
    • 回数ベース (N個の循環配列) ※デフォルト
    • 時間ベース (1秒ごとの部分集約のN個の循環配列)
  • 最小呼び出し回数に満たない場合は失敗率や遅延率は計算されない
    • 回数未満の間は状態遷移しない
  • HALF_OPEN ⇒ OPEN は回数ベース
  • 呼び出し遅延とタイムアウトの設定は別
  • resilience4j-spring-boot2
  • Actuator で CircuitBreaker の状態を監視
    • resilience4j-prometheus は非 Spring Boot 向け?
  • Spring Cloud Circuit Breaker
  • TimeLimiter?

Spring Cloud Consul / Consul 入門

  • 大規模分散システムを構築するための機能を提供
  • HashiCorp Consul
    • Web API の設計がきれい
  • Server/Agent によるクラスタ構成 ※同じバイナリ
    • Agent 配下の node の情報は Server 経由でクラスタ内に同期される
  • Consul ⇒ サービスの状態管理 & Key-Value Storage
  • Multi Datacenter
  • Consul Connect (Service Mesh)
  • Spring Cloud Consul
    • Service Discovery, クライアントサイドロードバランシング
    • Distributed Configuration ≒ Spring Cloud Config
  • Spring Cloud Consul はライブラリとして動作する
    • サービスと同じプロセス内で動く?
    • ⇔ サービスメッシュ
  • ローカルのプロパティを Consul の設定で上書きできる
  • @RefreshScope
    • Key-Value Storage の値を変更すると Bean をリフレッシュする (DIをやり直す)
    • もしくは /refresh エンドポイントを叩く
  • Spring Cloud Gateway
  • 通信や API の通信を暗号化するため TLS は必須
  • デフォルトは認証なしのため ACL を有効 + 必要最低限の API を公開する
    • デフォルトはすべての API が認証なしでアクセスできる

github.com

Spring Cloud Gateway on Kubernetes

www.slideshare.net

  • API Gateway Pattern
    • マイクロサービスのエッジに API Gateway を置く
    • サービスごとに横断する関心ごとをゲートウェイに持たせる
    • それぞれのサービスはシンプルに
  • Route, Predicate, Filter
    • ルーティングの設定は Functional に記述可
  • WebFlux & Reactor でノンブロッキングに実装されている
    • 大量リクエストを効率的に捌けるはず
  • Spring Cloud Kubernetes
  • Discovery Client (Service Discovery)
    • @EnableScheduling を付けないとポーリングしてくれない
  • Distributed Configuration
  • Circuit Breaker
    • Resilience4j
  • Security (Spring Security)
    • Spring Cloud Gateway 上で session と資格情報を関連付ける
    • Scope による権限制御
  • Monitoring (Prometheus)
    • Actuator + Micrometer

github.com

Windows の curl で SSL 証明書の失効チェックができない

前回の続き。備忘録。

Jenkins から curl で Google Chat に通知する - kntmr-blog

しばらくは問題なく動作していたが、いつ頃からか Jenkins から curl を実行したところで以下のようなエラーが出るようになった。

curl: (35) schannel: next InitializeSecurityContext failed: Unknown error (0x80092013) - 失効サーバーがオフラインのため、失効の関数は失効を確認できませんでした。

SSL 証明書の失効チェックができてないっぽい?

次のどちらかのオプションで回避する。セキュリティ的にはよろしくないかもだけど、社内の限定的な範囲でしか使わないのでよしとする。

  • --ssl-no-revoke: SSL 証明書の失効チェックを無効にする (Windows のみ)
  • -k, --insecure: SSL で安全ではないサーバー接続を許可する

参考

curl - How To Use

Jenkins から curl で Google Chat に通知する

備忘録。

社内の情報共有サイトに Google Chat で Webhook を使う方法が流れてたので、それを参考に Jenkins のビルドを通知する Bot を設定しました。

普段、Git と Jenkins を使っているのですが、現在の運用では、リリース内容によってはビルドするブランチを master から feature や release などに切り替えることがあります。で、今の Jenkins のビルド設定でどのブランチのどのコミットをビルドしたのかを手軽に知りたいと思いまして。

Git のブランチモデルについてまとめた記事はこちら。

Git ブランチモデル改善 (案) - kntmr-blog

前提

Webhook

Google Chat のルームから Webhook を設定する。以下のような URL が生成される。

https://chat.googleapis.com/v1/spaces/<ROOM_ID>/messages?key=<KEY>&token=<TOKEN>

Jenkins

今回は「Windowsバッチコマンドの実行」から curl で POST する。curl コマンドがない場合はインストールする。

Jenkins から curl が参照できない

この Jenkins が 32bit で動作しているのが原因なのか、C:\Windows\System32\curl コマンドが参照できないっぽい。なので、C:\Windows\SysWOW64\curl.exe を使うようにする。

リクエストエラー1

コマンドプロンプトから叩くと正常に実行できるのに、Jenkins から実行すると Payload が正しくないというエラーが返る。

$ curl -X POST -H "Content-Type:application/json" -d '{"text": "message"}' "%WEBHOOK_URL%"

リクエストの JSON をダブルクォートで囲って、中のダブルクォートをエスケープしたらイケた。ただ、^エスケープするだけでもよかったかも。

$ curl -X POST -H "Content-Type:application/json" -d "{\"text\": \"message\"}" "%WEBHOOK_URL%"

リクエストエラー2

Jenkins から curl を実行すると 400 Invalid request token が返る。原因は Webhook の URL に &% が含まれているため。& はクエリパラメータなのでいいとして、なぜ token に % が含まれるんだろうか...。

それぞれエスケープして ^&%% にする。

https://chat.googleapis.com/v1/spaces/<ROOM_ID>/messages?key=<KEY>^&token=aaaaaaaa%%3D

まとめ

最終的にこんな感じになりました。リクエストに thread を指定すると同一のスレッドにメッセージを送ることができる。今回は Jenkins の環境変数を利用して以下の情報を通知するようにした。(実際はもう少し気の利いたメッセージにしてある)

  • BUILD_NUMBER: ビルド番号
  • GIT_BRANCH: ブランチ
  • GIT_COMMIT: コミットハッシュ
set PROXY=http://<PROXY_HOST>:<PROXY_PORT>/
set WEBHOOK_URL=https://chat.googleapis.com/v1/spaces/<ROOM_ID>/messages?key=<KEY>^&token=aaaaaaaa%%3D
curl -X POST -H "Content-Type:application/json" -d "{\"text\": \"%BUILD_NUMBER% %GIT_BRANCH% %GIT_COMMIT%\", \"thread\": {\"name\": \"spaces/<ROOM_ID>/threads/<THREAD_ID>\"}}" -x %PROXY% "%WEBHOOK_URL%"

AirPods Pro を購入しました

AirPods Pro を購入しました。

これまで、「イヤホンを充電する」という行為がどうしても煩わしく感じてて、オーディオテクニカの普通のカナル型イヤホンを使い続けていました。

が、通勤であったり、最近は仕事中に耳栓代わりにイヤホンを着けたりしてて、やっぱりワイヤレスがいいかなとか思い始めまして...。あと、ノイズキャンセリング。これがどんなものなのかが気になってました。

で、モノは試しということで AirPods Pro をポチることに。ポチってから届くまで3週間ほど。

所感

持ち運びしやすそうなケースで、Qi に対応している。iPhone と同じ Lightning ケーブルで手軽に充電できるので、特に面倒に感じることはなさそう。

音質はイマイチ。特に中音域の抜けがイマイチ。音質にそこまでこだわるわけではないけれど、それでもイマイチに感じる。

ノイズキャンセリングはそこそこいい耳栓と同程度。仕事中にイヤホンを耳栓代わりに使うのでちょうどいい。それより外部音取り込みモードの聴こえ具合に驚いた。ただ、用途が分からない...。どういうときに使うの?

音質だけ目をつぶれば、この使いやすさでノイズキャンセリングが使えるならいいかなって。充電もそれほど煩わしくなさそうだし、とりあえず買ってよかった、ということで。

ECRS

昔のメモを読み返してたら ECRS という単語が目に留まりました。たぶん社内研修かなんかで聞いた単語をメモったんだと思われます。

ECRS は『業務プロセスを改善するためのフレームワーク』らしいです。

ECRS (改善の4原則) | 用語集 - JMAC

  1. Eliminate (排除)
  2. Combine (結合)
  3. Rearrange (再配置)
  4. Simplify (簡素化)

近頃、DX でモダナイゼーションがどうのこうの (雑) という話をよく聞きます。モダナイゼーションとは、老朽化したシステムの刷新、業務プロセスの改善や効率化などを指すようです。たぶん。

この業務プロセスの改善に ECRS の観点が大事なんだろうなぁと、ふと思った今日この頃です。

余談

全然関係ないけど、部屋の掃除や片付けをするときに ECRS が使えそう。今度子供に教えてみるか。

  • 不要なものは捨てる
  • 類似するものはまとめて収納する
  • よく使うものは手が届くところに置く
  • 使う頻度が低いものはクローゼットなどに入れる

JSUG勉強会 2020 その2 Spring Boot 1.x から 2.x への移行 に行ってきた #jsug

JSUG勉強会 2020 その2 Spring Boot 1.x から 2.x への移行 に行ってきました。簡単に所感をまとめます。

jsug.doorkeeper.jp

所感

普段あまり他社さんのバージョンアップの話を聴く機会は多くないかと思うので、なかなか興味深い内容でおもしろかったです。バージョンアップの流れとかハマりどころとかまとまった情報は重宝しそう。

細いけど、非推奨な機能を使ってるときに警告を出力する設定にしたり、小まめに PR してレビューコストを削減 (分散?) するのがわりとポイントかなと思ったり。

Micrometer の話は、去年の Spring Fest でも聴いたけど、とても便利そうだし使ってみたいです。なかなか使える機会がないけど...。(そもそも Boot アプリじゃない)

あとで読む。

以下、メモから抜粋。

決済サービスの Spring Boot のバージョンを2系に上げた話

www.slideshare.net

  • 2.x のリリースは 2018/03 なので 1.x を使ってる場合じゃない
  • 2.0.x は EOL 間近なので早めにアップデート
  • 2.0.x は Gradle 4+
  • バージョンアップ作業は半年くらい
  • まずは Gradle のバージョンをあげる
  • --warning-mode all が便利
    • Gradle 5 で非互換になる機能を出力してくれる
  • implementation
    • マルチジュール構成でハマった
    • モジュールが双方向に依存してるとつらい
  • プロジェクト直下の build.gradle でバージョン一元管理
  • hibernate-validator => javax.validation
  • spring-boot-starter-json
  • コネクションプールが Tomcat から HikariCP に
    • プロパティが url から jdbc-url に
  • HtmlEmail で null のときに Exception 投げるように
  • AWS X-RaySQL トレースで HikariCP が使えない
  • Flyway が2バージョンあがる (3.x ⇒ 5.x)
  • @ConfigurationProperties の prefix は必ずケバブケースで書く
  • Gradle と Lombok のバージョン相性問題
    • ClassCastException が起きる、などなど

Spring Boot 1.5 → 2.1 バージョンアップを経験して分かったハマりどころ

  • Migration Guide & Release Note でざっくり把握
  • 小さいリポジトリから着手
  • 変更点が多いのでモブレビューでコスト削減
    • 一気にPRすると大変なので小出しにする
  • maven-compiler-plugin の warning と非推奨ログを出力するように
  • Spring Data JPA
    • Query By Example のみに
    • PK による検索は *ById を使う
  • 2.1 から Bean の override はデフォルト禁止
    • allow-bean-definition-overriding で変更可
  • Mockito の any* や any(class) では null 禁止
    • isNull() か any() を使う
    • そもそも引数が nullable かどうか見直すこと
  • spring-boot-properties-migrator
    • 旧verの書き方のときに warning を出力してくれる
  • @SpringBootTest による結合テスト大事
  • バージョンアップをやり切ってから機能追加する

Metrics with Micrometer in Spring Boot 2

docs.google.com

  • 1.x でも /metrics は使える
    • 階層的なメトリクスしか対応してない
    • 時間計測は未対応
    • ネーミングの標準化は未対応
  • Micrometer
    • SLF4J のようなもの
    • 抽象化している
    • バックエンドに送るところは実装による
    • タグなどを使うことで多次元に分析できる
  • Spring とは別のプロジェクトで開発されている
  • 問題検知 & 分析
  • ログとは別にメトリクスを管理することでストレージを節約
  • 普段はインメモリでメトリクスを保持
    • いいタイミングでバックエンドに publish する
  • ネーミングルールなどのバックエンドによる違いは Micrometer が吸収してくれる
  • カスタムメトリクスを作るときはネーミングルールに気を付けること
  • 複数のバックエンドに publish することも可
  • publish する間隔はデフォルト1分
  • Controller で HTTP リクエストのメトリクスを取ると便利 (ステータスコードとか)
  • not boot アプリでも利用可
    • もちろん Auto Configuration ではない
  • 多次元の分析ができるバックエンドがおすすめ
    • Prometheus, Datadog など
  • jvm の shutdown-hook で publish する実装になっている