ようへいの日々精進XP

よかろうもん

2019 年 02 月 17 日 (日)

ジョギング

  • 山王公園
  • 懸垂 x 5
  • トレランシューズで走ってみたけど, うーん, この靴は間違いなく失敗...

夕飯

奥さんのリクエストでジャージャー麺を肉味噌から作った. 肉味噌は平野レミのレシピを参考にしている.

remy.jp

分量とか適当だったけど, 思ったよりも美味しくてよかった.

あと, 明日からの夕飯としてカレーも煮込んでおいた. ちょっと食べてみたけど美味しかった. 明日はもっと美味しくなっていることを期待.

2019 年 02 月 16 日 (土)

ジョギング

  • 山王公園
  • 懸垂 x 5
  • 左のかかとに痛み (以前から痛めていたところ)...どうしたもんだかな

昼寝

  • お昼ごはんを食べた後, うとうとしていたら 3 時間くらい寝てしまった

夕飯

  • 久しぶりのお鍋
  • エビとしらすのつみれを作ったけど, 団子状にすることが出来ずに具材が溶けてしまったけど, スープにとろみが付いていい感じになったから良かった

サーバーレス環境 (主に AWS Lambda) における緩い感じの処理完了待ちを実装する考察

tl;dr

おはようございます. どうも, 処理待ち隆史 (反町隆史) です.

Lambda を使った RDS の定期スナップショットのコピーを実装するにあたって, コピー完了を待つ (処理完了待ち) という処理をどのように実装するか考えてみた際のメモです.

検討

2 案

処理完了待ちを実装するにあたり, 以下のような手法を検討しました.

  1. Lambda のタイムアウトを利用する
  2. 状態を保持する 何か を用意して, 別の Lambda で処理のプロセスを監視する

Lambda のタイムアウト

まず, Lambda のタイムアウトを利用するというのは, タイムアウト (15 分以内) に確実に処理が終わることが保証されているのであれば, この手法が一番手軽なのかもしれません. ところが, 実際にスナップショットコピーを動かしてみたところ 15 分以上掛かってしまいコピー完了を確認することが出来ない状況になりました. (コピー自体は完了していることをマネジメントコンソールで確認しています)

まさにこんな気持ちになりました.

別の Lambda で処理のプロセスを監視する

以下のような仕組みを考えました.

f:id:inokara:20190216194044p:plain

(1) 〜 (3) までの処理は, 今回は RDS のスナップショットコピーという処理になっていますが, 似たような処理完了を待つような処理を当てはめることが出来ると考えています.

コピー用の Lambda 関数はスナップショット作成完了の通知を受けると, スナップショットをコピーする処理がを実行します. 正常にコピー処理が開始されると, SQS キューにに処理を開始した旨のメッセージをキューイング (4) します. メッセージの内容は以下のような JSON となります.

{"snapshot": "コピーするスナップショット名", "count": "処理待ち用 Lambda 関数が呼ばれた回数"}

JSON は以下のような内容となります.

  • snapshot キーの値にはコピーするスナップショット名が入ります, ここには処理完了を監視する対象物が定義されます
  • num キーの値には処理待ち用 Lambda 関数が何回呼ばれたかが定義され, これは関数が呼ばれる度にインクリメントされます

ポイントは num キーとなります. これは, 処理が永遠に完了しない場合, しきい値を設けてサーキットブレーカー的に待機処理 (処理が完了することを監視する処理) を終了する為に利用します.

キューイング以降, 処理待ち用の Lambda 関数は SQS キューのメッセージを受け取ると, メッセージを削除後, スナップショットのコピーが完了しているかどうかをチェックします. スナップショットのコピーが完了していたら完了した旨を通知して Lambda 関数は終了します. コピーが完了していなければ, 改めて SQS キューにメッセージを放り込みます. 処理待ち用の Lambda 関数はメッセージを利用して SQS キューとピンポンしている状態になりますが, 永遠にピンポンするわけにはいかないので, 処理待ち用 Lambda 関数が呼ばれた回数を記録しておいて, しきい値を超えたら待機処理を終了するような流れになります.

サンプル

サンプルとして...

実際に雰囲気を伝えたくて, 以下のような処理の流れを考えてみました.

f:id:inokara:20190216222028p:plain

S3 バケットにオブジェクトが放り込まれたら Lambda 関数が起動するやつです. そして, 放り込まれたオブジェクトが削除されるまで待機するという, 場合によっては, 永遠に待ち続けるような処理です.

コード

雑な感じで.

github.com

俺たちの Serverless Framework を利用します.

bundle exec rake deploy

でデプロイします. Slack に通知したい場合には, Incoming Webhook の URL を KMS で暗号化した内容を SLACK_ENCRYPTED_URL に記載します.

雰囲気

上記のコードの実行例です.

https://github.com/inokappa/serverless-waiter/blob/master/docs/images/2019021601.gif?raw=true

test.json ファイルを S3 にアップロードすると, PUT イベントをトリガーにして Lambda 関数が起動して SQS キューにメッセージが放り込まれます. メッセージは以下のような内容となります.

{"bucket":"serverless-waiting","key":"test.json","count":3}

count3 になっているので, 3 回目の削除待ち用 Lambda 関数が呼ばれていることになります. この実装例では, 10 回削除待ち用 Lambda 関数が呼ばれると削除待ちを終了するようになっています.

/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 START RequestId: f983604b-281a-5f35-93cf-34a90b14cb80 Version: $LATEST
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Deleted queue message.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] 10 回目の待機です.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 Error raised from handler method
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 {
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52   "errorMessage": "[ERROR] 待機制限 (10 回) を超えたので, 待機を終了します.",
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52   "errorType": "Function<RuntimeError>",
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52   "stackTrace": [

尚, 削除待ち用 Lambda 関数内でも指定した回数待機する処理になっています.

以上

緩い感じで

処理完了待ちを実装してみました. 実際に運用していますが, 今のところ処理待ちが滞っている等のトラブルはありません. また, 実装例も何度か試していますが意図したような挙動を確認しています. ただ, 例外処理は不十分である可能性があり, 完璧な処理完了待ちになっていない可能性がありますので, あくまでも緩い感じの実装になっていることをお許し下さい.

コスト?

  • Lambda 関数は月 1,000,000 件のリクエストは無料枠となり, よっぽどおかしな関数でなければ無料枠内でおさまると考えています
  • SQS は 100 万リクエストまでは無料枠の範囲内ですので, Lambda と SQS 間でおかしなピンポンがなければ無料枠の範囲でおさまると考えています

ということで

良い処理完了待ちライフを.

2019 年 02 月 15 日 (金)

ジョギング

  • お休み

インフラのコード化と現場の狭間で (1)

puppet や Chef に始まり, Ansible や Terraform, CloudFormation 等インフラをコードで管理することが当たり前になってきたけど, 一旦, コードに落とし込んで終わりというわけではなく, それを日々の運用の中でうまく管理していくことが重要でとても難しいと常々思っている.

新しい職場でも AWS のインフラは Terraform で管理されていて, マネジメントコンソールのポチポチの手間からは開放されていて素晴らしいなあと思っている. (Terraform 化してくれた同僚各位には感謝しかない)

インフラのクラウド化やアプリケーションのデプロイ環境がコンテナ化されてきたことにより, インフラ構成の追加や変更がインフラエンジニア以外でもカジュアルに行われるようになってきたことで, インフラをコードで落とし込む前にコマンド一発やポチポチでインフラの構成変更が行われ, コードと実際に動いているインフラとの乖離が発生は顕著になってきている.

しかし, 自分はそんな中で乖離自体大したことではなく, むしろ, スピード感を持ってアプリケーションをリリースしていくような中ではあるあるの事だと思っているし, この乖離をどのように吸収していくかルールや仕組みづくりが重要だと考えている. もちろん, 完璧にコード化されていることに越したことはないが, そうも言っていられないのがどこの現場にでもありそうな状況なのかなと考えている.

ということで, インフラのコード化と現場の狭間でどのように属人化を廃してインフラの運用管理を効率化するか考えていきたいと思うけど...生意気言ってすいません.

夕飯

どうしてもお寿司が食べたくて「銀のさら」の出前で満足.

2019 年 02 月 14 日 (木)

ジョギング

  • 大事を取ってお休み

夕飯

近所のお好み焼き屋さんからお好み焼きと焼きそばをテイクアウト. ここのお好み焼き屋さん, 調理する人によってお好み焼きのや焼き加減や焼きそばの味にムラがあるという人間味のあるお店である. 次はお店で食べてみたい.

awspec

去年, 自分がプルリクエストした実装に問題があって awspec が動かなくなっていた模様.

github.com

ほんとすいません!という気持ちでマージした.

2019 年 02 月 13 日 (水)

ジョギング

  • 山王公園
  • 左かかと周りにピキッとした痛み
  • あ〜っやっちまったかなって感じ (別大の後半で既に痛かった

奥さん

  • 夕飯の準備をしてくれていた, 有難い
  • 徐々に良い方向に向かってくれれば嬉しい

YAMAHA WLX202 の一部のシステム情報を JSON で返す API サーバーを作ってみた

tl;dr

YAMAHA の無線 LAN アクセスポイント WLX202 を触る機会がありました.

network.yamaha.com

YAMAHAルーターと組み合わせて, LAN マップ機能を使えば一括管理出来たりして最高な無線 LAN アクセスポイントだと思っています. ただ, この機器の CPU 使用率やメモリ使用率, アクセスポイントに接続しているクライアント数をモニタリングしたいと思った時に壁にぶち当たりました.

その壁とは, あくまでも「かっぱ調査」の範囲だと, CPU 使用率やメモリ使用率, 2.4GHz 帯, 5GHz 帯のそれぞれ接続しているクライアントの数を SNMP で取れないという壁です. 拡張 MIB を追加すれば取れるのかもしれませんが, シュッと取れない歯痒さに奮起した結果, Web 管理画面に出力されているシステム情報の HTML を解析して JSON で返せるようにしてみたメモです.

以下, WLX402 のシステム情報出力画面ですが, WLX202 でも似たような画面です.

f:id:inokara:20190212235325p:plain

上記の写真は http://www.rtpro.yamaha.co.jp/AP/docs/wlx402/wlan-controller/index.html より引用させて頂きました. ありがとうございます.

作ったもの

github.com

詳細はREADME をご一読下さい.

wlx は Docker コンテナを利用して動かすとバックグラウンドプロセスとして動かすよりも簡単にサービス化出来ます.

make image && make run

コンテナは WLX202 にアクセス可能なホストで起動して下さい. 無事に起動したら, 以下のように curl 等の HTTP クライアントで貴方の WLX202 の情報を取得して下さい.

curl -s -XPOST http://localhost:20200/wlx/${対象機器の IP アドレス} \
  -d "user=${ログインユーザー}" \
  -d "pass=${ログインパスワード}"

以下のような JSON が返ってくるはずです.

{
  "results": [
    {
      "ip_address": "対象機器の IP アドレス",
      "machine_name": "WLX202_XXXXXXXXXXX",
      "cpu_utilization": "10",
      "memory_usage": "39",
      "connected": "10",
      "connected_5g": "15"
    }
  ]
}

やったこと

Go で HTML を解析する

システム情報のページの HTML は以下のようになっています. (一部抜粋.)

...
<!-- wireless 5G information -->
<div class="settings">
    <h3><strong>無線情報 (5GHz)</strong></h3>
    <div class="settings-content">
    <table width="100%" summary="Settings" class="two_col_12">
        <tr>
            <td class="head">無線状態</td>
            <td>有効</td>
        </tr>
        <tr>
            <td class="head">無線モード</td>
            <td>11a+n+ac</td>
        </tr>
...
        <tr>
            <td class="head">接続端末台数</td>
            <td>14 台</td>
        </tr>
    </table>
    </div>
    <div class="clearfix">&nbsp;</div>
</div>
...

この HTML ページを解析する為に https://github.com/PuerkitoBio/goquery を利用しました. wlx のコード的には https://github.com/inokappa/wlx/blob/master/main.go#L98-L109 らへんです. CPU 稼働率, メモリ使用率が 1 つの TABLE 属性の中に含まれていて, 2.4GHz 帯の接続数, 5GHz 帯の接続数はそれぞれ個別の TABLE 属性に含まれています. もっとクールな情報の取得方法があるとは思いますが, ひとまず欲しいデータは取れたので満足しています.

Echo で API サーバーを実装する

JSON 化出来たので, その JSON を HTTP 経由で取得したいと思ったので, https://github.com/labstack/echo を使って API サーバーを作ってみました. サンプルをコピーしてこねくり回しただけの代物なので, エラー処理等が不十分で満足していません. ただ, Echo を使えば, 単純なレスポンスを返すサーバーであれば, 自分のようなスーパー素人でも実装出来るのは素晴らしいです. もっと, 使いこなせるようになりたいです.

で, wlx をどのように使うのか

監視で利用します.

Datadog Agent とカスタムの Agent Check を使って, WLX202 のリソースを監視したいと考えています. カスタム の Agent Check は wlx のエンドポイントにアクセスする HTTP クライアントと JSON をパースする処理を書くことでサクッと実装出来そうです.

以上

もしかしたら, 俺たちの YAMAHA さんのことなので, ファームウェアの更新で CPU 稼働率やメモリ使用率等, wlx を介して取得していた情報が SNMP で取れるようになるかもしれません. その暁には wlx を捨てて SNMP で取得したいと思いますので YAMAHA さん, 何卒, よろしくお願い致します.

ということで, また, クソコードを書いてしまいましたが, コードで何かを解決するというのは気持ちが良いものですよね. 引き続き, 精進します.

2019 年 02 月 12 日 (火)

ジョギング

  • お休み
  • 起きれなかった

奥さん

  • 通院
  • 自分は進歩していると思っているが, 奥さんは自分を追い詰めている感じがする
  • どういう言葉をかけてあげれば良いのか分からないけど, 自分が出来ることをやってあげられればと考えている

池江璃花子さん

news.livedoor.com

本人が一番ショックでどうしたら良いのはわからない状況だと思うけど, ツイッターの投稿を見ると本当に凄いなあと思う. 東京オリンピックとかどうでも良いので, 今はゆっくり静養して元気になって欲しい. しかし, ここぞとばかりにマスコミが騒ぎ立てるのは何なんだろう.

2019 年 02 月 11 日 (月)

ジョギング

  • 昨日に引き続き, 山王公園を 40 分程
  • 懸垂 x 5
  • ペースは 5 分を超えるくらい
  • トレランシューズ, 失敗したかな〜

奥さん

  • 少し笑ったり出来るのでちょっと安心
  • 食欲はまあまあありそうなので, 出来るだけ好きなものを食べさせてあげたい

2019 年 02 月 10 日 (日)

ジョギング

  • 久しぶりに山王公園を 40 分程
  • 懸垂 x 5
  • ペースは 5 分を超えるくらい
  • 疲労は全然抜けていない感じで, 走りはじめてすぐに筋肉痛がやってきて辛かった
  • 昨日買ったトレランシューズを履いて走ったが, 硬い材質なのか色々と違和感があって嫌な感じ

奥さん

  • 一進一退

夕飯

サニーで雑に買った惣菜を並べただけ. ごめんなさい.