wwwave'sTechblog |ウェイブのエンジニアブログ

株式会社ウェイブのエンジニアによるテックブログです。会社の話や Ruby、Vue.jsについてなど技術的な話をしていきたいと思います。

株式会社ウェイブの人事部ブログです。社内の雰囲気やイベント、福利厚生などについてお伝えいたします!

株式会社ウェイブのエンジニアブログです。 エンジニアの目線から会社の話や技術的な話をしていきます。

Amazon EventBridgeでバッチ処理のスケジュール管理を改善しました!

ウェイブTechブログとは?
ウェイブの仕事をエンジニア目線でお伝えするWebメディアです。毎月15日の更新を目指しています。肩の力を抜いて執筆し、ありのままのウェイブをお見せできるよう心がけています。

本日の担当:SRE ヤギ
 ・2016年4月入社
 ・ゲーム好きの超インドア派
 ・最近はelden ring

今回のお話

電子コミック配信サービス「ComicFesta」が抱えるバッチ処理スケジュールの管理課題をAmazon EventBridgeを使って改善しました!

画像上が改善前、下が改善後になります。

 

 

課題

ComicFestaではバッチのスケジュール管理をAmazon EC2上にあるComicFestaのシステムとは別のバッチ管理サーバーで設定していました。  

この設定ではバッチ管理サーバーに障害が発生した場合、バッチの実行にも影響が出てしまいます。また、バッチ管理サーバーは別プロジェクトとも関わっているため、依存関係の面でも別の管理方法に移行したいと考えました。

解決方法

ComicFestaはAmazon ECSで稼働しています。  
課題を解決するにあたりマネージドのサービスに移したいと思いECSとの連携を考えてEventBridgeを使うことに決めました。

EventBridgeのドキュメントを見ると「サーバーレスのイベントバスサービス」と書かれています。  
この説明ではイメージが沸かないですが、私はEventBridgeを「指定したルールに一致するイベントをトリガーに、別のサービスに処理をリクエストしてくれるサービス」と理解しています。

指定したルールは、cronにより時間指定も可能なため、スケジュール管理を行うことができます。またマネージドなAWSサービスとしてECSなど他のAWSサービスとの連携も容易で、今回の課題を解決するものとして採用することにしました。

改善内容

StepFunctionの利用

ECSで行っているバッチ処理のタスク定義は1つだけです。この定義のタスクを起動する際に実行コマンドを引数で渡すことで異なるバッチを実行しています。  

初めEventBridgeからECSを呼び出す処理をしたのですが、引数として実行コマンドを上手く渡すことが出来ませんでした(こちらに関しては今振り返ると出来そうな気もするので検証時のやり方が悪かっただけかもしれません)  

また、EventBridgeからは本来cronで設定しているトリガーを手動で実行することができません。バッチ管理サーバーで運用している時は手動でのバッチ実行をする機会があるため代わりの手段が必要でした。  

これらを解決するためにEventBridgeとECSの間にStepFunctionを挟むことにしました。  
これによりECSへの実行コマンドを渡せるようになり、StepFunctionからECSを呼び出すことで手動でのバッチ実行を実現しました。  

スケジュールの登録方法

EC2で管理している時は自作のスクリプトを用意してymlで記載された定義ファイルから一括でバッチのスケジュールを登録していました。EventBridgeに移行後も同様の運用を行いたいと思い、スクリプトを修正してAWS CLI経由で一括登録を行うようにしました。  

例として毎朝9時にバックアップを動かすバッチがあった場合、ymlファイルで下記のように定義してスクリプトからEventBridgeへ反映しています。

Backup:
  cron: "0 9 * * ? *"
  description: バックアップ
  batch_class: "Batches::Daily::Backup"
  is_active: true

また、EventBridgeに登録するcronはUTC時間での登録になります。しかし運用上UTC時間での記載はコードを見た際にわかりにくいため、定義ファイルではJST時間で登録し、スクリプトでUTC時間に置き換えて登録しています。

アラートの検知

バッチのスケジュールではありませんが、今回の対応をきっかけにEventBridgeでECSタスクの異常終了を検知できることを知りました。

バッチのスケジュール登録の時はcronでルールを指定しましたが、EventBridgeでは特定のAWSイベントを検知してトリガーすることも出来ます。そのためバッチのECSタスクが異常終了したイベントを検知してアラート通知を行うよう設定を行いました。  

cloudformationにて設定しているのですが設定コードを一部記載します。

Resources:
  BatchAlertEventsRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern: !Sub |
        {
          "source": [
            "aws.ecs"
          ],
          "detail-type": [
            "ECS Task State Change"
          ],
          "detail": {
            "clusterArn": [
              "arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${ECSClusterName}"
            ],
            "group": [
              "family:${ECSTaskFamily}"
            ],
            "containers": {
              "exitCode": [
                {"anything-but": 0},
                {"exists": false}
              ]
            },
            "lastStatus": [
              "STOPPED"
            ]
          }
        }
      State: 'ENABLED'
      Targets:
        - Arn: !Ref BatchAlertSNSTopic
         Id: 'BatchAlert'

 

結果

移行後はサーバレスな環境であり、サーバー管理を気にする必要がなくなりました。SLAの観点からもEC2単体と比べて高いため、安定性が向上しています。

サービス SLA
EC2 99.5%
EventBridge 99.99%
StepFunction 99.9%

EventBridgeへの移行から数ヶ月経過しましたが、特に問題も発生しておらず運用を続けることが出来ています。  
今まではEventBridgeに関してほとんど触ってきませんでしたが、今回の対応を通してスケジュール管理以外にも、他イベントを検知してアラートするなどの活用方法を知ることが出来て良かったです。

 

ウェイブではともにチャレンジしてくれるエンジニアを募集しています。

現在の募集職種はこちらをご覧ください。

recruit.wwwave.jp

CoolmicのSentryエラー監視を改善してみた!

f:id:sys_wwwave:20220411175009p:plain

ウェイブTechブログとは?
ウェイブの仕事をエンジニア目線でお伝えするWebメディアです。毎月15日の更新を目指しています。肩の力を抜いて執筆し、ありのままのウェイブをお見せできるよう心がけています。

本日の担当:SRE シラト
 ・2017年4月入社の新卒社員(2021年9月〜SREに所属)。
 ・ユニバ大好き。
 ・おすすめのチュリトスはミニオンのチョコバナナ・チュリトス。

今回のお話

今回は、海外向けコミック配信サービス「Coolmic」でのエラー監視改善についてお話したいと思います!

環境

Coolmicでは以下の構成でエラー監視を行っております。

Category Technology
Programming Languages(Backend) Ruby on Rails
Programming Languages(Frontend) Vue.js
Monitoring Sentry
Communication Slack

f:id:sys_wwwave:20220411145345p:plain

課題

Coolmic、サービスリリースからあっという間に四年が過ぎました。
この四年間、幾度となくエラーを解決してきましたが、中には以下のような厄介者が紛れ込んでくることがあります。

・原因はわかるが売上影響度が低く、修正時間がかかり費用対効果が悪い

・特定の端末でのみ発生する

このようなエラーの修正は新機能開発よりも優先度が低くなってしまうため、放置されがちです。その結果、Slackでのエラー通知が1日100件とノイズで埋め尽くされるときもありました・・・。

このままでは致命的な障害発生時に速やかに覚知することができないと感じたため改善を行いました。

改善点

今回一番問題だったのは『エラーをすぐに解決せず、放置したこと』ではなく『エラー監視の改善を行わなかったこと』だと感じました。
監視改善に対する重要度が低かったのですが、書籍『入門 監視』を読んで意識が変わりました。

そこで今回は、監視の質を上げるべく改善を行いました。

1. 常に改善し続ける

前提の話になりますが、このマインド重要です。『入門 監視』にもありましたが、『銀の弾丸はない』とのこと。改めて考えてみたら、サービスは変化し続けるので、監視もチューニング必要ですね。

2. エラー通知を放置しない

『入門 監視』にもありましたが、以下のような問いかけをすると判断コスト減らせてよかったです!
・エラー通知でアクションすることはありますか?
・過去、同じエラー通知で何らかのアクションはしましたか?
・通知を停止させるにはどうすればいいですか?

過去アクションしたことがないエラー通知であれば、思い切ってエラー通知を Discard して良さそうです。
もし、エラー修正するのであれば、タスクに有効期限を設定し、その期限内はエラー通知をOFFにする対応だけでもノイズを減らす手段として有効です。

3. Sentry 通知を Discard する

Sentry 通知を OFF にする方法として、Ignore と Discard の二種類あります。実は、Discard にすると Sentry にエラーが送信されても料金がかからないです!!
Ignore にしているエラーを見直すとコスト削減に繋がる可能性があります。

手段 通知条件
Ignore 設定した条件を満たすまで通知しない
Discard  一度設定したら二度と通知しない

4. Sentry 通知をグルーピングする

Sentry 側で Discard 対応したのに、同じようなエラー通知が来てしまうことがあります。
Sentry は独自のアルゴリズムでエラーのグルーピングしているみたいです。
同じエラーメッセージやスタックトレースをSentry側でグルーピングすることができます。
gemのバージョンを更新しただけで新しいエラーになってしまうので、この機能を有効活用したいです!

5. 非対応端末は例外を送らない

以下のようにJavaScriptでbeforeSendメソッドの戻り値をnullにしました。
これでSentryへ例外通知しないようにできます。
Sentryのコンソールからも似たような設定はできます。
しかし、サイトの推奨端末以外は動作保証外ため、エラー通知がノイズになってしまいます。
細かいOSのバージョンなどは指定できないため、前述の対応でフィルタリングすることにしました。

Sentry.init({
dsn: "SentryのDSN",
  beforeSend(event) {
    if (非対応端末 === "true") {
      return null;
    }
    return event;
  },
});

改善結果

改善直後は、1日数件程度までエラー通知数を減らすことができました。今回の改善で応急処置できたかと思います。ただ、開発業務と並行して監視改善を行うには、判断コストを減らすなど効率化が必要そうです。

SRE配属前はCoolmic開発チームに所属していたので、課題意識のあった監視の改善ができてよかったです!

まとめ

・エラー監視は常に改善し続けることが大切!

・思い切ってエラー通知を削除することは、ノイズを減らす第一歩に繋がる!

SREチームの業務の一部のご紹介でした!今回のように改善して振り返っての繰り返しで成長する機会がたくさんある環境です!少しでもウェイブに興味ある方、オフィスでお待ちしております〜。

 

ウェイブではともにチャレンジしてくれるエンジニアを募集しています。

現在の募集職種はこちらをご覧ください。

recruit.wwwave.jp

トップに戻る