ホームページ  >  記事  >  バックエンド開発  >  Golang でのハートビート パターンの使用

Golang でのハートビート パターンの使用

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-03 06:08:30926ブラウズ

Utilizando o pattern Heartbeats em Golang

アプリケーション監視のために Go にハートビートを実装する

データ エンジニアとソフトウェア エンジニアのバランスを取る冒険をしている間、私はいつも GoLang で少し違うものを探して勉強し、その仕組みを理解し、インターネットで見つけた従来の基本的なコースや記事よりも複雑なものに応用しています。 。この短い記事では、チャネルなどの使用に加えて、アプリケーションのハートビート (「生きている」) をシミュレートするために Ticker を使用する時間パッケージである Go Routines を介してどのように実装したかをレポートおよびデモンストレーションします。

特定の関数を呼び出す人が、その関数が時間をかけているか、処理中か、ロックされているかを確実に把握できるようにすることが非常に重要であることは、多くの人にとって新しいことではありません。とはいえ、トレース、メトリクス、接続性など、他のいくつかの用語も登場しています。これらは、ほとんどの場合、アプリケーション サーバーにインストールされたエージェントを使用してメトリクスを収集し、それらをすべて視覚化するインターフェイスに送信する監視アプリケーションで導入されています。ほぼ) アプリケーションのステータス。これらのツールには、DataDog、NewRelic、Slack、Grafana、Jaeger などがあります。

ここには何があるでしょうか?

私は、より高度な Go の概念に対応する、手早く簡単なものを作成することを検討し、検討していたので、ハートビート パターンを利用する比較的単純なアプリケーションを作成しました。私に電話をかけてきた人は誰でも結果を受け取り、同時に私がまだ活動しているかどうかの情報も受け取ります。より高度なシナリオでは、Prometheus の単純な実装でこのケース (アプリケーションはアクティブですか? CPU、メモリ、オープンゴルーチン) を解決できるため、ビジネスの特殊性に関して実際にアクティブなアプリケーションをカスタマイズするのは興味深いかもしれませんが、同時かつカスタマイズ可能なフィードバックはありません。

コードの時間!

構造に関して言えば、go mod を使用してパッケージ内に作成したファイルは 3 つだけです。

  • Dictionary.go: 検索する関数の名前の辞書が含まれています。
  • task.go: 辞書から名前をスキャンし、同時にteam.Tickerのチャンネルビートを通じてアクティブかどうかを通知する機能を含むタスク。
  • task_test.go: task.go に存在する関数の単体テストを実行して、辞書データからの応答と、アプリケーションがまだ起動しているかどうかに関するフィードバックの両方を確認します!

辞書.go

Go コードのこの部分では、ルーン文字と文字列を関連付けるマップである「dictionary」と呼ばれる変数を定義しています。

各マップ エントリはキー (ルーン) と値 (文字列) です。以下の例では、キーはアルファベットの小文字で、値は各文字に関連付けられた名前です。たとえば、文字「a」は名前「airton」に関連付けられ、文字「b」は名前「bruno」などに関連付けられます。

package heartbeat

var dicionario = map[rune]string{
    'a': "airton",
    'b': "bruno",
    'c': "carlos",
    'd': "daniel",
    'e': "eduardo",
    'f': "felipe",
    'g': "gustavo",
}

task.go

コード全体の後で、コードの各部分について詳しく説明します。

package heartbeat

import (
    "context"
    "fmt"
    "time"
)

func ProcessingTask(
    ctx context.Context, letras chan rune, interval time.Duration,
) (<-chan struct{}, <-chan string) {

    heartbeats := make(chan struct{}, 1)
    names := make(chan string)

    go func() {
        defer close(heartbeats)
        defer close(names)

        beat := time.NewTicker(interval)
        defer beat.Stop()

        for letra := range letras {
            select {
            case <-ctx.Done():
                return
            case <-beat.C:
                select {
                case heartbeats <- struct{}{}:
                default:
                }
            case names <- dicionario[letra]:
                lether := dicionario[letra]
                fmt.Printf("Letra: %s \n", lether)

                time.Sleep(3 * time.Second) // Simula um tempo de espera para vermos o hearbeats
            }
        }
    }()

    return heartbeats, names
}

依存関係のインポート

package heartbeat

import (
    "context"
    "fmt"
    "time"
)

ここには、タスクの処理中に特定の時間間隔で「ハートビート」を送信する機能を実装するハートビート パッケージがあります。このためには、context (コンテキスト管理)、fmt (文字列フォーマット用)、および時間制御のための time が必要です。

初期関数定義

func ProcessingTask (
    ctx context.Context, letras chan rune, interval time.Duration,
) (<-chan struct{}, <-chan string) {

これは、ctx コンテキスト、レター チャネル (Unicode 文字を受け取るチャネル)、および時間間隔を引数として受け取る ProcessingTask 関数の定義です。この関数は 2 つのチャネルを返します。1 つは「ハートビート」ごとに空の構造体を送信するハートビート チャネル、もう 1 つは受信した各文字に対応する文字の名前を送信する名前チャネルです。

チャンネル

heartbeats := make(chan struct{}, 1)
names := make(chan string)

これらの 2 行は 2 つのチャネルを作成します。heartbeats は 1 要素の容量を持つバッファー チャネルで、names はバッファーなしのチャネルです。

面倒な作業を行う Go ルーチン

go func() 
    defer close(heartbeats)
    defer close(names)

    beat := time.NewTicker(interval)
    defer beat.Stop()

    for letra := range letras {
        select {
        case <-ctx.Done():
            return
        case <-beat.C:
            select {
            case heartbeats <- struct{}{}:
            default:
            }
        case names <- dicionario[letra]:
            lether := dicionario[letra]
            fmt.Printf("Letra: %s \n", lether)

            time.Sleep(3 * time.Second) // Simula um tempo de espera para vermos o hearbeats
        }
    }
}()

return heartbeats, names

これは、ProcessingTask 関数のメイン ロジックを実行する匿名の goroutine (または新しいスレッドで実行される匿名関数) です。 for-range ループを使用して文字チャネルから文字を読み取ります。ループ内で、選択を使用して、使用可能なオプションから実行するアクションを選択します。

  • case <-ctx.Done(): コンテキストがキャンセルされた場合、関数は return.
  • ステートメントを使用して直ちに終了します。
  • case <-beat.C: ビート ティッカーが値を送信する場合、ゴルーチンは空のデフォルトの select を使用して空の構造体をハートビート チャネルに送信しようとします。
  • case names <-dictionary[letter]: 文字を受信した場合、ゴルーチンは対応する文字の名前を辞書辞書から取得し、それを名前チャネルに送信し、fmt パッケージを使用して文字を画面に出力し、待機します。次の文字に進むまでの 3 秒。このシミュレートされた待機は、送信される「ハートビート」を確認できるようにするためのものです。

最後に、関数はハートビートを返し、チャネルに名前を付けます。

アプリケーションのテスト

task_test.go

package heartbeat

var dicionario = map[rune]string{
    'a': "airton",
    'b': "bruno",
    'c': "carlos",
    'd': "daniel",
    'e': "eduardo",
    'f': "felipe",
    'g': "gustavo",
}

ここでは、前に説明した ProcessingTask 関数の Go 単体テストを作成しました。 TestProcessingTask テスト関数は、タイムアウトが 20 秒のコンテキストと Unicode 文字 (文字) のチャネルを作成します。次に、匿名のゴルーチンは歌詞を歌詞チャネルに送信します。次に、コンテキスト、Unicode 文字チャネル、および時間間隔を指定して、ProcessingTask 関数が呼び出されます。ハートビート チャネルとワード チャネルの 2 つのチャネルを返します。

テスト関数は、コンテキスト、ハートビート チャネル、ワード チャネルの 3 つのチャネルから読み取る選択を含む無限ループを実行します。

コンテキストがキャンセルされた場合、テストループは終了します。ハートビートを受信すると「Application Up!」が表示されます。が標準出力に出力されます。単語を受信した場合、テストではその単語が文字辞書に存在するかどうかがチェックされます。存在しない場合、テストは失敗し、エラー メッセージが表示されます。

したがって、この単体テストでは、時間制限を使用したコンテキストで実行中に、あるチャネルから文字を受信し、別のチャネルに文字名を送信し、「ハートビート」を送信する ProcessingTask 関数をテストします。ああ...そして、単語チャネルに送信された文字の名前が辞書に存在するかどうかもチェックされます。

私の結論

この Go コードは、Go 言語と単体テストのいくつかの重要な概念を示しています。

  • コンテキスト
  • ゴルーチン
  • チャンネル
  • 単体テスト (select を使用して複数のチャネルを監視)

GitHub 上の完全なプロジェクト: https://github.com/AirtonLira/heartbeatsGolang

LinkedIn - エアトン リラ ジュニア

以上がGolang でのハートビート パターンの使用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。