マイナビニュースマイナビ

AWS X-Rayを用いたマイクロサービスの可視化(4)

【連載】

AWSで作るマイクロサービス

【第11回】AWS X-Rayを用いたマイクロサービスの可視化(4)

[2020/12/02 08:00]川畑 光平 ブックマーク ブックマーク

本連載では、以下に示すようなマイクロサービスアーキテクチャのアプリケーション環境を構築しています。

構成図

構成図

前回は、X-Rayデーモンへトレースデータを送信するためのフロントエンドのWebアプリケーションの設定を個別に実装しました。今回は、バックエンドのマイクロサービスにおけるX-Rayの設定実装について解説していきます。

なお、本連載で実際に作成するアプリケーションはGitHub上にコミットしています。以降に記載するソースコードでは、import文など本質的でない記述を省略している部分があるので、実行コードを作成する際は、必要に応じて適宜GitHubにあるソースコードも参照してください。

サンプリングルールの設定

前回と同様、共通のX-Rayの設定クラスではサンプリングルールを設定した「sampling-rules.json」を読み込みます。ここでも、全てのリクエストが計測対象となるよう、レートを「1」に設定しておきます。

{
  "version": 2,
  "rules": [
    {
      "description": "Sample description.",
      "host": "*",
      "http_method": "*",
      "url_path": "/api/*",
      "fixed_target": 1,
      "rate": 1
    }
  ],
  "default": {
     "fixed_target": 1,
     "rate": 0.1
  }
}

バックエンドのマイクロサービスにおけるX-Rayの設定

フロントエンドのWebアプリケーションと同様に、Controller、Service、Repositoryごとに実行時間を計測します。前回設定したXRayConfigクラスのAOPポイントカット定義に基づき、各コンポーネントの実装クラスに@XRayEnabledアノテーションを付与します。以下は、Controllerにアノテーションを付与する例です(backend-user-service/src/main/java/org/debugroom/mynavi/sample/aws/microservice/backend/user/app/web/BackendUserController.java)。

package org.debugroom.mynavi.sample.aws.microservice.backend.user.app.web;

// omit

import com.amazonaws.xray.spring.aop.XRayEnabled;

// omit

@XRayEnabled
@RestController
@RequestMapping("api/v1")
public class BackendUserController {
    // omit
}

ただし、Repositoryのクラスについては、org.springframework.data.repository.Repositoryインタフェースを継承しているので、特にアノテーションを設定する必要はありません。これは、XRayConfigの継承クラスcom.amazonaws.xray.spring.aop.AbstractXRayInterceptorが、既にそのインタフェースをポイントカット定義しているためです。

代わりにというわけではありませんが、バックエンドのマイクロサービスではインメモリデータベース「HSQL」を使ってユーザー情報を取得しているので、以下のようにDataSourceをcom.amazonaws.xray.sql.TracingDataSourceでラップして定義しておきます。

package org.debugroom.mynavi.sample.aws.microservice.backend.user.config;

// omit

import com.amazonaws.xray.sql.TracingDataSource;

// omit

@Profile("dev")
@Configuration
public class DevConfig {

    // omit

    @Bean
    public DataSource dataSource(){
        return new TracingDataSource(new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.HSQL)
                .addScript("classpath:schema-hsql.sql")
                .addScript("classpath:data-hsql.sql")
                .build());
    }

}

Controllerの処理が完了した後、TraceIDやユーザーID、実行時間をDynamoDBに保存するよう、HandlerInterceptorAdapterを継承したコンポーネントを生成します。TraceIDは前回の実装と同様、Segmentオブジェクトをcom.amazonaws.xray.AWSXRayから取得してもよいのですが、リクエストヘッダにもTraceIDは設定されているため、そこから取得するように実装してみましょう。最終的には、前回と同じくLogクラスに設定してDynamoDBへ保存します(backend-user-service/src/main/java/org/debugroom/mynavi/sample/aws/microservice/backend/user/app/web/interceptor/AuditLoggingInterceptor.java)。

package org.debugroom.mynavi.sample.aws.microservice.backend.user.app.web.interceptor;

// omit

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import org.debugroom.mynavi.sample.aws.microservice.common.apinfra.cloud.aws.log.dynamodb.model.Log;
import org.debugroom.mynavi.sample.aws.microservice.common.apinfra.cloud.aws.log.dynamodb.repository.LogRepository;
import org.debugroom.mynavi.sample.aws.microservice.common.apinfra.util.DateStringUtil;

@Component
public class AuditLoggingInterceptor extends HandlerInterceptorAdapter {

    private static final String HEADER_KEY = "X-Amzn-Trace-Id";

    @Autowired(required = false)
    LogRepository logRepository;

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {
        Log log = Log.builder()
                .userId("1")
                .traceId(getTraceId(request))
                .createdAt(DateStringUtil.now())
                .build();

        logRepository.save(log);
    }

    private String getTraceId(HttpServletRequest request){
        String header = request.getHeader(HEADER_KEY);
        String[] headerElements = StringUtils.split(header, ";");
        String rootElements = Arrays.stream(headerElements)
                .filter(headerElement -> headerElement.startsWith("Root="))
                .findFirst().get();
        String[] traceIdElement = StringUtils.split(rootElements, "=");
        return traceIdElement[1];
    }

}

なお、Webアプリケーションから送信されたリクエストに設定されているTraceIDは、com.amazonaws.xray.javax.servlet.AWSXRayServletFilterで取り出されて、バックエンドマイクロサービスのセグメントに設定されます。

実装が完了したら、双方のアプリケーションを起動してログイン処理を行ってみましょう。以下の通り、アプリケーション起動処理と、Webアプリケーションからマイクロサービスへの呼び出しが以下のように可視化されるはずです。

可視化

Webアプリケーションがバックエンドマイクロサービスにアクセスしてデータを取得し、認証処理をトレースして可視化すると以下のようになります。

可視化

各コンポーネントの処理でどれくらい時間がかかっているのか、ビジネスロジックにほぼ手を加えずに可視化できたことを実感いただけると思います。

DynamoDBに保存したログは以下の通りです。ユーザーIDやTraceIDなどで検索しやすくなるので、必要に応じて保存する項目をカスタマイズするとよいでしょう。

可視化

* * *

以上、今回はバックエンドのマイクロサービスにX-Rayを設定する実装を行い、フロントエンドのWebアプリケーションから呼び出して処理するまでの一連の流れを可視化しました。実装の初期から各処理を可視化しておけば、性能上ボトルネックになりそうな箇所を早めに特定できます。問題のある部分は随時改善し、製造過程で品質を作り込んでいくことを心がけましょう。 次回以降は「AWS Cognito」を使い、認証/認可処理の組み込みやバックエンドのマイクロサービスへの認可制御の組み込みを実装していきます。

著者紹介


川畑 光平(KAWABATA Kohei) - NTTデータ

金融機関システム業務アプリケーション開発・システム基盤担当、ソフトウェア開発自動化関連の研究開発を経て、デジタル技術関連の研究開発・推進に従事。

Red Hat Certified Engineer、Pivotal Certified Spring Professional、AWS Certified Solutions Architect Professional等の資格を持ち、アプリケーション基盤・クラウドなど様々な開発プロジェクト支援にも携わる。AWS Top Engineers & Ambassadors選出。

本連載の内容に対するご意見・ご質問は Facebook まで。

※ 本記事は掲載時点の情報であり、最新のものとは異なる場合がございます。予めご了承ください。

一覧はこちら

連載目次

もっと知りたい!こちらもオススメ

【連載】いまさら聞けないマイクロサービスの基本 [4] なぜ今マイクロサービスなのか? マイクロサービスを開花させた技術要素

【連載】いまさら聞けないマイクロサービスの基本 [4] なぜ今マイクロサービスなのか? マイクロサービスを開花させた技術要素

各社製品がマイクロサービス対応をうたってきています。その中でも中核を成すのが、クラウド製品です。その他にも開発フレームワークとしてSpring Bootの存在も大きく、仮想化やCIの技術も見逃せません。今回は、これまでの技術との違いを踏まえ、マイクロサービスを開花させた技術要素を解説します。

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で TECH+ の人気記事をお届けします
注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
ニューノーマル時代のオウンドメディア戦略
ミッションステートメント
教えてカナコさん! これならわかるAI入門
AWSではじめる機械学習 ~サービスを知り、実装を学ぶ~
対話システムをつくろう! Python超入門
Kubernetes入門
SAFeでつくる「DXに強い組織」~企業の課題を解決する13のアプローチ~
PowerShell Core入門
AWSで作るマイクロサービス
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

今注目のIT用語の意味を事典でチェック!

一覧はこちら

会員登録(無料)

ページの先頭に戻る