ファウンダー 証券金融テクノロジー クラウドネイティブ マイクロサービス構築実践

この記事は、CloudWeGo テクノロジー サロン「クラウド ネイティブ✖️AI 時代のマイクロサービス アーキテクチャと技術実践」での Founder Securities Financial Technology Engineering Institute のシニア R&D エンジニアである Liu Yi 氏の講演「Financial Technology Go Microservices」に基づいています。 2024年3月30日に北京で開催された北京イベント。「建設実践」より編集。

概要: この記事では、クラウド ネイティブ マイクロサービスの構築における Founder Securities Financial Technology Engineering Institute の実践経験を詳しく紹介します。共有には次の 3 つの側面が含まれます。

  1. マイクロサービスのガバナンス作業
  2. マイクロサービスの可観測性の取り組み
  3. マイクロサービス インターフェイス管理の上記の機能は統合され、Founder の Quark 開発プラットフォームに統合されています。

Founder Securitiesのマイクロサービス構築実践入門

2023 年の初めに、登録センターにはZooKeeperを、Web および RPC アプリケーション フレームワークにはそれぞれ CloudWeGo のHertzKitexを使用するマイクロサービス システムの構築を開始しました。    

現在、私たちはマイクロサービス構築の深層領域に参入しています。これには、主にマイクロサービス ガバナンス可観測性機能インターフェイス管理、およびその他の関連作業が含まれます。以下では、その概念と実装原理を詳しく紹介します。

マイクロサービス ガバナンス機能の構築

コンセプト

マイクロサービスアーキテクチャでは、ビジネス量が徐々に増加するにつれて、サービスの数も徐々に増加します。このような背景から、ビジネスの発展に伴い、サービスの管理・制御がますます難しくなり、サービスの分割によって生じる一連の問題を解決し、より安定的にサービスを稼働させることがサービスガバナンスの役割となります。サービスの登録と検出、ロード バランシング、サービス サーキット ブレーカー、サービスの低下、サービスの電流制限などを提供します。 Quark プラットフォームによって提供されるタイムアウト、再試行、およびサーバー側の電流制限機能はすべて、Kitexの関連機能に基づいています。現在使用されている登録センターは ZooKeeper (略称 zk) であるため、関連する動的構成もヘルプを使用して実装されます。 zk の設定を zk に書き込み、サーバーとクライアントに関連機能のアクティブ化を完了するように通知します。  

導入

  1. フロー制御

    フロー制御の粒度はサービス レベルです。次の図に示すように、サービスは 1 秒あたり最大 1,000 リクエストを処理でき、過剰なリクエストは直接シャットダウンされます。 huaxing_ratelimit

  2. 構成を再試行する

    再試行構成の粒度はメソッド レベルであり、現在のサービスが指定されたサービスのメソッドへのリクエストに失敗した場合に再試行する方法を構成するために使用されます。 huaxing_retry

  3. タイムアウト設定

    タイムアウト設定の粒度はメソッド レベルであり、現在のサービスが指定されたサービスのメソッドを要求するのにかかる最大時間を設定するために使用されます。この値を超えると、現在のサービスは切断されます。設定を参照してください。各構成の特定の機能の説明。 huaxing_timeout 

実装原則と詳細

サーバー側とクライアント側の両方で、Kitexスイートを拡張することによって、関連する設定の動的挿入を完了します。  

サーバ側

次のコードを使用して Kitex サーバーを構成します。

server.WithSuite(zooKeeperServer.NewSuite("Kitex-server", zooKeeperClient))
コピー

その中には、zooKeeperServer.NewSuite("Kitex-server", zooKeeperClient)スイート インスタンスが返され、サーバーに挿入されたリミッター設定が含まれます。 Options 

func (s *zooKeeperServerSuite) Options() []server.Option {
    opts := make([]server.Option, 0, 2)
    // WithLimiter实现中,在zk中注册了监听器,每当数据变化,动态更新Limiter的相关配置,以达到限流目的
    opts = append(opts, WithLimiter(s.service, s.zooKeeperClient, s.opts))
    return opts
}
コピー

上記の内容に基づいて、 Kitex フレームワークは現在、次の 2 種類のリミッターのみをサポートしていることがわかります。

  1. 接続リミッター (最大接続数を制限します)
  2. Qpsリミッター(最大QPSを制限)

zk を登録センターとして使用する場合、両方とも構成を通じて動的に調整できます。変更後、構成値は zk のリスナーを通じて取得されます。

// zk数据变化时的回调方法
onChangeCallback := func(restoreDefault bool, data string, parser zooKeeper.ConfigParser) {
   lc := &limiter.LimiterConfig{}
   if !restoreDefault && data != "" {
      err := parser.Decode(data, lc)
      if err != nil {
         klog.Warnf("[zooKeeper] %s server zooKeeper config: unmarshal data %s failed: %s, skip...", dest, data, err)
         return
      }
   }
   // 将zk中的数据动态更新到配置中
   opt.MaxConnections = int(lc.ConnectionLimit)
   opt.MaxQPS = int(lc.QPSLimit)
   u := updater.Load()
   if u == nil {
      klog.Warnf("[zooKeeper] %s server zooKeeper limiter config failed as the updater is empty", dest)
      return
   }
   if !u.(limit.Updater).UpdateLimit(opt) {
      klog.Warnf("[zooKeeper] %s server zooKeeper limiter config: data %s may do not take affect", dest, data)
   }
}
// path,对于limiter,其值为:/KitexConfig/{ServiceName}/limit
zooKeeperClient.RegisterConfigCallback(context.Background(), path, uniqueID, onChangeCallback)
コピー

クライアント側

サーバー側と同様に、クライアント側にも同じ構成があります。

bizService.NewClient("Kitex-client",
client.WithSuite(zooKeeperclient.NewSuite("Kitex-server", "Kitex-client", zooKeeperClient)))
コピー

クライアント側のスイートには次のオプションが含まれています。

func (s *zooKeeperClientSuite) Options() []client.Option {
    opts := make([]client.Option, 0, 7)
    opts = append(opts, WithRetryPolicy(s.service, s.client, s.zooKeeperClient, s.opts)...)
    opts = append(opts, WithRPCTimeout(s.service, s.client, s.zooKeeperClient, s.opts)...)
    opts = append(opts, WithCircuitBreaker(s.service, s.client, s.zooKeeperClient, s.opts)...)
    return opts
}
コピー

つまり、クライアントは、再試行、タイムアウト、サーキット ブレーカーの 3 つの動的構成をサポートします。関連する処理は、zk クライアントのコールバック メソッドを通じて実行され、動的更新の効果が実現されます。

タイムアウト設定に関する追加の注意事項

タイムアウトの場合、その構成メソッドの具体的な実装は次のとおりです。

func WithRPCTimeout(dest, src string, zooKeeperClient zooKeeper.Client, opts utils.Options) []client.Option {
    // ...
    return []client.Option{
        client.WithTimeoutProvider(initRPCTimeoutContainer(path, uid, dest, zooKeeperClient)),
        client.WithCloseCallbacks(func() error {
            // cancel the configuration listener when client is closed.
            zooKeeperClient.DeregisterConfig(path, uid)
            return nil
        }),
    }
}
コピー

最後に、 Kitex が提供するメソッドを呼び出すことで、client.WithTimeoutProviderタイムアウトに関連する特定の設定が完了します。タイムアウトには、次のようなさまざまな構成方法があります。

func WithRPCTimeout(d time.Duration) Option {
    // ...
}

func WithConnectTimeout(d time.Duration) Option {
    // ...
}

func WithTimeoutProvider(p rpcinfo.TimeoutProvider) Option {
    // ...
}
コピー

このうち、WithTimeoutProvider設定されたタイムアウトはの設定値WithRPCTimeoutで上書きされるため、Kitex クライアント作成時にまたは をWithConnectTimeout呼び出した場合、動的設定は有効になりません。WithRPCTimeoutWithConnectTimeout

設定手順

タイムアウト

対応する zk ノード:/kitexConfig/{ClientName}/{ServiceName}/rpc_timeout

書き込まれた構成の形式は次のとおりです。

{
  "*": {
    "conn_timeout_ms": 100,
    "rpc_timeout_ms": 800
  },
  "GetDemoInfo": {
    "rpc_timeout_ms": 300
  },
  "GetDemoInfo3": {
    "rpc_timeout_ms": 300
  }
}
コピー

フィールドの意味: 新しい接続を確立するための最大待ち時間 : rpc 呼び出しの最大時間。 conn_timeout_ms rpc_timeout_ms

リトライ

対応する zk ノード:/kitexConfig/{ClientName}/{ServiceName}/retry

書き込まれた構成の形式は次のとおりです。

{
  "GetDemoInfo": {
    "enable": true,
    "type": 0,
    "failure_policy": {
      "stop_policy": {
        "max_retry_times": 2,
        "max_duration_ms": 9000,
        "cb_policy": {
          "error_rate": 0.1
        }
      }
    }
  },
  "GetDemoInfo5": {
    "enable": true,
    "type": 0,
    "failure_policy": {
      "stop_policy": {
        "max_retry_times": 2,
        "max_duration_ms": 9000,
        "cb_policy": {
          "error_rate": 0.1
        }
      }
    }
  }
}
コピー

フィールドの意味

設定項目 デフォルト値 説明する 限界
max_retry_times 2 最初のリクエストを除く再試行の最大数。 0 に設定すると、再試行を停止することを意味します。 有効な値: [0-5]
max_duration_ms 0 最初に失敗したリクエストと再試行リクエストの経過時間を含む累積最大経過時間。経過時間が制限に達すると、それ以降の再試行は停止されます。 0 は制限がないことを意味します。注: 構成されている場合、この構成項目は要求タイムアウトより大きくなければなりません。  
エラー率 10% 再試行サーキット ブレーカーのエラー率のしきい値。メソッド レベルのリクエストのエラー率がしきい値を超えると、再試行が停止されます。 有効な値: (0-30%]

制限する

この構成はサービスのグローバル構成であるため、zk ノード パスには serviceName のみが含まれます。/kitexConfig/{ServiceName}/limit

書き込まれた構成の形式は次のとおりです。

{
  "qps_limit": 100
}
コピー

マイクロサービスの可観測性機能の構築

コンセプト

サービス可観測性構築とは、システムの稼働状況や性能指標を包括的かつタイムリーに把握するために、分散システムにおける監視、ロギング、追跡などのツールや技術を確立・改善することを指します。

完全な監視ツールはビジネス システムに多くのメリットをもたらします。

  1. 問題をタイムリーに検出して解決する能力。
  2. チームがシステムの全体的な操作と内部相互作用をより明確に理解できるようにします。
  3. システムの負荷ステータス、リソース使用率、傾向変化を理解して、容量計画とリソースの最適化をサポートできます。
  4. ログ・追跡システムでシステムの操作ログやリクエストの追跡を記録することで、ユーザーの操作行動や異常なリクエスト、セキュリティイベントなどを追跡・分析し、システムのセキュリティと信頼性を向上させることができます。

導入

サービスの詳細は、ゴールデン モニタリング インジケーター (QPS、レイテンシ、エラー率)、SLO、ランタイム関連情報などを含む、サービス自体の全体的な動作を表示するために使用されます。 華興_グラファナ

トポロジ図は、サービス間の上流と下流の依存関係を示すために使用されます。 華興_トポロジー

呼び出しチェーン データには、サービス間の各呼び出しに関する詳細情報が含まれています。 華興トレース

実装原則と詳細

huaxing_otel

現在、 OpenTelemetryクライアントはテンプレート コードに統合されており、生成されたHertz サービスKitexサービスには、デフォルトで監視可能なデータ (メトリクス + トレース) レポート機能があります。    

詳細については、kitex-contrib/obs-opentelemetry およびhertz-contrib/obs-opentelemetryを参照してください。 

OpenTelemetry  (OTel) は、開発チームが統一された単一形式でテレメトリ データを生成、処理、送信できるようにするオープン ソースの可観測性フレームワークです。これは、メトリクス、ログ、トレースを収集して監視プラットフォームに送信するための標準プロトコルとツールを提供するために、Cloud Native Computing Foundation (CNCF) によって開発されました。 OpenTelemetry は、ベンダーに依存しない SDK、API、およびツールを提供します。 OpenTelemetry は急速にクラウドネイティブ アプリケーションの有力な可観測性テレメトリ データ標準になりつつあります。 OpenTelemetry の導入は、特定のベンダーに縛られたり、レガシー テクノロジーに制限されたりせずに、将来のデータ ニーズに対応できるようにしたい組織にとって重要です。

痕跡

トレースにより、リクエストの受信から完了までのライフサイクル全体の全体像が得られます。

リクエストを受信した後、サービスはメタ情報 (Kitex) または http ヘッダー (Hertz) からのリンク追跡を有効にします。メタ情報または HTTP ヘッダーにトレース情報がない場合、新しいリンク トレースが自動的に有効になります。リンク情報は、コンテキストを通じてサービス プロセス内で渡されます。

アクセス方法:

// for Hertz
tracer, cfg := hertztracing.NewServerTracer()
h := server.Default(tracer)
h.Use(hertztracing.ServerMiddleware(cfg))
コピー
// for Kitex
svr := echo.NewServer(new(DemoImpl),
    server.WithSuite(tracing.NewServerSuite()),
    server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: serviceName}),)
コピー

トレース情報は OpenTelemetry Collector に報告され、その後、Jaeger に透過的に送信されます。リンク関連情報は、Jaeger で照会できます。

デフォルトでトレース関連情報を出力する統合ログ プリンタ fzlog を提供します。

{
  "file": "get_repositories.go:33",
  "func": "gitlab.fzzqft.com/ifte-quark/quark-api/biz/service.(*GetRepositoriesService).Run",
  "level": "info",
  "msg": "GetRepositoriesService Run req: page:1 limit:10 service_name:\"kitex\"",
  "span_id": "aa26bab58cdf6806",
  "time": "2024-04-23 15:59:40.609",
  "trace_flags": "01",
  "trace_id": "f714dbe2a96b1882dfc4b81909e55643"
}
コピー

ログが収集および処理された後、リンク全体の関連ログ情報をログ プラットフォームで照会できます。 trace_id 

メトリクス

メトリクスは、リクエスト率、応答時間、エラー率など、システムのパフォーマンスと動作を測定する重要なデータです。通常、メトリクスは、システムの健全性を監視し、傾向分析を実行するために収集、集計、視覚化されます。

現在、各サービスは独自のメトリクス データを報告し、それらを Prometheus/VictoriaMetrics に均一に保存し、最終的に grafana を使用して監視パネルを形成します。

以下では、QPS、リクエスト時間、エラー率という 3 つの一般的なサービス記述インジケーターを使用して、サービスによって報告されるメトリック データの使用方法を示します。

  • QPS: QPS の定義に基づいて、QPS を計算するにはリアルタイム リクエストの数を取得するだけで済みます。http_server_duration_count 報告されたデータの値はリクエストの数と一致しているため、このメトリクスを使用して計算を完了できます。 QPS。

    sum(rate(http_server_duration_count{service_name="$service_name"}[$__rate_interval]))
    
    コピー

    上記の promQL では、指定された期間内の特定のメトリクスの増加率を計算するために rate 関数が使用され、最終結果は指定された期間内のリクエストの平均数になります。

  • リクエスト消費時間: これは統計データであるため、ここではサービスリクエストの消費時間を表すために平均を使用することを選択します。平均消費時間は、指定された期間内のすべてのリクエストの消費時間の合計によって取得されます。指定された期間内のリクエスト:

    sum(rate(http_server_duration_sum{service_name="$service_name"}[$__rate_interval])) by (application) /
    sum(rate(http_server_duration_count{service_name="$service_name"}[$__rate_interval])) by (application)
    
    コピー
  • エラー率: まず、エラーのあるリクエストの数をフィルターで除外し、リクエストの総数で割ってエラー率を取得します。

    round((1 - (sum(rate(http_server_duration_count{service_name="$service_name",http_status_code=~"^(2|3).*"}
    [$__interval]))/sum(rate(http_server_duration_count{service_name="$service_name"}[$__interval])))), 0.0001)
    
    コピー

トポロジー

全体的なサービス間の依存関係は、集計で言及されているメトリック データを通じて表示されます。レポートされるデータには情報が含まれておりservice_namesourceサービスのアップストリーム情報とダウンストリーム情報はtargetPromSQL オペレーターを通じてsum取得できます。

マイクロサービスインターフェイス管理機能の構築

コンセプト

  • IDL

    インターフェイス記述言語 (IDL) は、ソフトウェア コンポーネントのインターフェイスを記述するために使用されるコンピューター言語です。 IDL はプログラミング言語に依存しない方法でインターフェイスを記述し、異なるプラットフォーム上で実行されるオブジェクトや異なる言語で記述されたプログラムが相互に通信できるようにします。

  • インターフェース管理

    Kitex (RPC) サービスはすべて IDL に基づいて実装されており、インターフェイス管理プラットフォームは主に RPC サービスの IDL 製品を管理するためのインターフェイス プラットフォームを提供し、開発者が RPC インターフェイスを管理および呼び出すことを容易にします。

  • インターフェースのテスト

    Kitex (RPC) サービスはテストにアクセスできません。インターフェイス テスト プラットフォームのユーザーは、プラットフォームを通じて RPC リクエストを開始してデバッグを完了することで、この問題を解決し、テストと開発を促進します。

導入

  • インターフェース管理プラットフォーム(操作方法は画像参照) huaxing_interface_1 huaxing_interface_2 huaxing_interface_3
  • インターフェイステストプラットフォーム(Kitex(RPC)インターフェイスのデバッグ) huaxing_interface_test

実装原則と詳細

  • インターフェース管理

    以前は、 kitexサービスの IDL 製品を管理するために、gitlabci を使用した独立したウェアハウスを使用していました実際の使用中に、次の問題点がありました。   huaxing_interface_impl 

    1. 発信者は、小さなウィンドウ (プライベート チャット) を通じて IDL 製品ウェアハウスのアドレス、支店、またはバージョン番号を取得する必要があります。
    2. サービスの提供方法は、サービスプロジェクトの倉庫とそれに対応する製品の倉庫の両方に注意を払う必要があります。
    3. Gitlabci はランナーに強く依存しているため、新しいグループを使用するには管理者が新しいグループを構成する必要があります。
    4. 既存の CICD プロセスに深くバインドできない

    上記の問題と問題点を解決するために、インターフェイス管理プラットフォームが設​​計および開発されました。 huaxing_interface_platform

    サービスが構築されパッケージ化されると、IDL 製品の更新プロセスがトリガーされ、プラットフォームはサービスの種類を自動的に検出し、対応する IDL 製品を生成して、gitlab の独立したウェアハウスに送信します。ユーザーはプラットフォームで IDL 製品を手動で作成または更新することもできます。呼び出し元は、インポート パス コマンドをコピーして実行するだけで、対応するバージョンのサービス依存関係を取得できます。

  • インターフェイス テストは、Kitex PB の JSON マッピング一般化呼び出しに基づいて実装されます。ユーザーがプラットフォーム上で対応するサービスとインターフェイスを選択すると、プラットフォームは対応する IDL ファイルを自動的に解析し、デフォルトのリクエスト パラメーター (json 形式) を与えます。リクエストを送信した後、プラットフォームは汎用呼び出しを通じてターゲット サービスへの RPC リクエストを開始し、結果を返します。 huaxing_interface_test_logic 

まとめ

現在のマイクロサービス システムはすでにほとんどの技術的ニーズを満たすことができますが、クラウド ネイティブ システムの下でさらに進化する予定です。

  1. サービス ガバナンスは、クラウドネイティブのサービス メッシュ (ServiceMesh) 機能に依存してトラフィックを管理すると同時に、他のアプリケーション フレームワークからの East-West トラフィックも組み込みます。
  2. 可観測性を備えた OpenTelemetry は、言語やアプリケーション フレームワークに依存しない一連のソリューションであり、統一されたセマンティクスを通じて、Java の Web (Springboot) システムと RPC (Dubbo) システムを統合する予定です。
  3. インターフェイス管理では、将来的には RPC インターフェイスと HTTP インターフェイスを一元管理し、インターフェイスのユースケースを自動生成する予定です。

最近の活動

企業ユーザーと開発者の皆様は、ぜひCloudWeGoテクノロジー サロンにご参加ください。このイベントは、2024 年5 月25 日(土曜日)に上海で開催され、技術者の同僚を招待して、企業がクラウド ネイティブxAIの波の下で製品の迅速なイテレーションと開発をサポートするクラウドネイティブ マイクロサービス アーキテクチャを構築する方法について話し合います。画像の QR コードをスキャンしてすぐにサインアップしてください。また会いましょう! 

 

「Celebrated More Than Years 2」の海賊版リソースが npm にアップロードされたため、npmmirror は unpkg サービスを停止せざるを得なくなり、 最初の創設者の 数百人が参加して、一斉に米国に向かいました。 フロントエンド視覚化ライブラリと Baidu の有名なオープンソース プロジェクト ECharts - Fish 詐欺師をサポートするために「海へ行く」が、TeamViewer を使用して 398 万を送金しました。リモート デスクトップ ベンダーは何をすべきでしょうか? 周宏宜: Google に残された時間はあまり多くありません。すべての製品をオープンソースにすることが推奨されています。 ある有名なオープンソース企業の元従業員が、部下から異議を申し立てられた後、激怒しました。妊娠中の女性従業員を解雇しました。Google は Android 仮想マシンで ChromeOS を実行する方法を示しました。 ここで time.sleep(6) はどのような役割を果たしますか? マイクロソフト、中国のAIチームが「米国のために荷造りしている」という噂に反応 人民日報オンラインはオフィスソフトのマトリョーシカのような課金についてコメント:「セット」を積極的に解決することによってのみ、私たちは未来を手に入れることができる
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/4843764/blog/11181511