2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Goを学ぶ ~番外編 Jaeger~

Last updated at Posted at 2023-04-08

目的

Jaegerって何?
echoとJaegerを使ってみる。

Jaegerとは

Jaeger(イェーガー)は、Uber Technologies社によって開発され、オープンソース化されたGo言語の分散トレーシングシステム
分散トレーシングとは、近年マイクロサービスも浸透してきており、処理が1つのアプリケーションで完結しなくなってきてる。
その結果、1つの処理の全体像をつかむことが難しいケースがうまれた。
例えば、
処理Aと処理Bの2つの処理があり、処理Aを行ったあとに処理Bを実施する分析処理がある。処理A,Bは別アプリケーションとする。
分析処理が遅延するケースがあることがわかり、処理時間を確認したところ

  • 処理A
    • 10秒
    • 3秒
  • 処理B
    • 5秒
    • 7秒

という通常より遅くなるものが見受けられた。
安易に考えると処理Aの10秒と処理Bの7秒が改善されればとなるかもしれないが、連動しているので
処理Aが10秒かかったときはもしかしたら処理Bは必ず通常通りに処理しているかもしれないし、5秒かかるかもしれないし、
ケースバイケースかもしれない。
すべてのパターンを検討すればいいといえばそうなのだが、非常に非効率な方針である。
今は2×2なのでたかがしれているが、現実はそんなに甘くないので現実的な方針が必要になる。
分散トレーシングは、分析処理としてみたときにあるときに処理Aが何秒、処理Bが何妙とアプリケーションではなく、さまざまな処理としてみることができるもの。
今回の問題は、どういった組み合わせが多いのかがわからないから全部みる?だったが、
常日頃からこういった処理をしているからこのパターンが顕著だから重点的に確認するといったことが可能になる。
こういった、分散トレーシングシステム非常にたくさんある。
有名なところだとAWS X-Ray、Datadogyとかかな?
当然それらを使ってもいいし、jaegerを使ってもいいとは思う。
先の2つの違いとしては、
jaegerはオープンソースなのでサーバー費用がかかるが、利用は無料な点
ある意味個人開発では非常に便利なのかもしれない。

Jaegerの理解を深める

JaegerはOpenTracingと互換性のあるデータモデルを持ち、各種言語用の計測ライブラリを提供している。
CNCF卒業プロジェクトとなっており、今後が期待されているOSS。

OpenTracing

Jaegerを理解するうえで、OpenTracingの理解する必要がある。
重要な概念として

  • スパン
  • トレース

の2つがある。関係性は下の図になる。
image.png
スパンは、処理時間だけでなく、操作名などの作業単位の情報を有しています。
トレースは実行パスも表している。

Jaegerのコンポーネント構成は下の図になる。
image.png
出典:https://www.jaegertracing.io/docs/1.43/architecture/

名前 説明
Tracing Trace 以前はJaeger Clientと呼ばれていた。アプリケーションにインストルメント化する必要がある。 インストルメント化されたアプリケーションでは、新しいリクエストをうけとるときにスパンを作成し、コンテキスト情報を発信リクエストに添付する。 echoのフレームワークで設定する内容はこの部分
Jaeger Agent 公式ドキュメントに非推奨となっているが、UDP経由で送信されたスパンを受け取るネットワークデーモン。 受け取ったスパンをバッチ化してコレクターに送信する。
Jaeger Collector トレースを受け取り、処理パイプラインを介してストレージに保存する。
Jaeger Query ストレージからトレースを取得するAPIを公開し、トレースを検索および分析するためのWebUIを提供する

ためしに使ってみる

OSSということもDocker提供されているので試しに使ってみる。

docker-compose.ymlを編集

version: '3'
services:
  go_echo:
    container_name: goEcho
    build:
      context: ./echo/
    volumes:
      - ./echo:/go/src/app
    tty: true
    environment:
      - TZ=Asia/Tokyo
      - JAEGER_SERVICE_NAME=go_echo_jaeger
      - JAEGER_ENDPOINT=http://jaeger:14268/api/traces
    ports:
      - 1323:1323
    networks:
      - jaeger

  go_echo_db:
    image: mysql:5.7
    container_name: mysqlEcho
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: echo
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./database/data:/var/lib/mysql
    ports:
      - 13306:3306

  jaeger:
    container_name: jaeger
    image: jaegertracing/all-in-one:latest
    ports:
      - "16686:16686"
      - "14268:14268"
    environment:
      - COLLECTOR_OTLP_ENABLED=true
      - LOG_LEVEL=debug
    networks:
      - jaeger

networks:
  jaeger:

part1,2のdocker-compose.ymlを使われている場合、
コンテナ名が変わっているので注意してください。
変更理由は、アンダースコアがホスト名として使用できないためです。
含んだものが混じっているでうまく名前解決できなくなり、Jaegerがスパンを受け取れなくなります。
go側に環境変数の宣言を追加しています。
これは公式ドキュメントに従っており、Jaeger関連の設定はデフォルト設定がありますが、環境変数に設定されている場合は、こちらが優先されます。ホスト名は変更する必要があるので設定してください。

server.goに追記

package infra

import (
	"app/controllers"
	"github.com/labstack/echo-contrib/jaegertracing"
	"github.com/labstack/echo/v4"
)

type Server struct {
	Echo *echo.Echo
}

func NewServer() *Server {
	return &Server{
		Echo: echo.New(),
	}
}

func (server *Server) Start() {
	server.Echo.GET("/", controllers.NewHelloController().GetMessage)

	c := jaegertracing.New(server.Echo, nil) //追加
	defer c.Close() // 追加

	server.Echo.Start(":1323")
}

こちらは公式ドキュメントに従っているので特別なことはなしです。

変更内容は以上!!!
あとはコンテナを起動して、echoも起動
起動後にlocalhost:1323に接続してHello Worldを表示させたあとに
http://localhost:16686 にブラウザに接続してください。
image.png
こんな画面が表示されたあと、
Serviceのセレクトボックスが1つ以上ある状態になり、「go_echo_jaeger」があればOKです。
詳細を見たいトレースをクリックすると詳細画面に遷移します。
image.png

ソース全体はこちら https://github.com/dsrice/go_echo/tree/jaeger

今回はリクエストのみ取得していますが、その気になれば別のアプリケーションでなくても細かくスパンをつくることは可能です。
コンテキストの持ち回りが必要だったりそこそこの労力にはなるのでやられる際は注意してください。
コンテキストの持ち回りが必要な理由は同一トレース化の判定に必要になるためです。このあたりは、
jaegerというよりOpenTracingの実装が必要になります。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?