気軽に楽しくプログラムと遊ぶ

自分が興味があってためになるかもって思う情報を提供しています。

Confluence PlantUML シーケンス図 ノートの表示位置調整

メッセージに付けるノートが思うように出力できなかったので、記載しておく

  • note 【表示位置】 of 【起点の要素】
  • 【表示位置】 :right left over
  • 【起点の要素】:participantで定義した要素

参考ソースと画面イメージ

@startuml
participant Alice
participant Bob
note left of Alice #aqua
This is displayed
left of Alice.
end note

note right of Alice: This is displayed right of Alice.

note over Alice: This is displayed over Alice.

note over Alice, Bob #FFAAAA: This is displayed\n over Bob and Alice.

note over Bob, Alice
This is yet another
example of
a long note.
end note
@enduml

参考

plantuml.com

AWSやKubernetes周りのツール 概要

AWS App Runner

  • ECRにコンテナイメージをpushまたは、GitHubにコードpushすると、自動デプロイしてくれる
  • コンテナがデプロイされるとApp RunnerがマネージドのLBを設定してくれる
  • コンテナ管理とかVPC周り、ALB,NLBとかscalingなどを隠蔽して提供してくれる

Kubernetes Ingressコントローラー

参考

サービスメッシュとIstio

マイクロサービスの課題

  • 近年、マイクロサービスが大流行しているがネットワークに関係する課題がある
    • トラッフィク管理、可観測性、セキュリティの3つ

ネットワークに由来する課題解決のための機能

マイクロサービスシステムの運用には、分散システムのネットワークに由来する課題が存在しており、その解決のための様々な機能の実装が必要となる。

  • トラフィック管理
    • サービスディスカバリ
      • サービスを利用する際、ドメイン名などのサービス識別子からIPアドレスなどの実サーバ接続情報を明示的/暗示的に得ること
    • 負荷分散
    • ロットリング
      • 一定の時間内に、事業者が特定の操作に対して送信できるリクエストの数を制限するプロセス
    • サーキットブレイカ
  • 可観測性
    • モニタリング
    • ロギング
    • 分散トレーシング
  • セキュリティ
    • サービス間の認可
    • 相互TLS

各種ライブラリを用いて、これらを実装して問題解決することも可能であるが、多くのマイクロサービスを抱える場合、統一的な問題解決をするのが難しくなってくる。

サービスメッシュが解決する課題

すべてのマイクロサービス間の通信に対して、一貫した仕組み(サーキットブレーカー、ログ、メトリクス、認証認可など)を提供するのがサービスメッシュ。

Istioの概要

Data Plane

  • マイクロサービス間のすべてのネットワーク通信を仲介・制御する
  • すべてのPodにEnvoyをサイドカープロキシとして配備する
  • アプリケーションは、IstioやEnvoy Proxyのための設定が不要となり、ビジネスロジックの実装に集中できるようになる
  • マイクロサービス間の通信の観測結果を収集し、レポートする

Control Plane

  • Data Planeを管理する
  • istio-initによって、Kubernetesクラスター内のすべてにEnvoy Proxyを注入する
  • RouteRuleなどの設定を常に最新に保つように、Reconciliation Loopを実行する
  • 可観測性の向上のためにログ集約するなどを行う

Istiod

  • サービス検出・構成・証明書管理を行う
  • 構成要素
    • Mixer : Envoy を通して各サービスのデータを収集し、その情報を元にアクセスコントロールを行う
    • Pilot : サービスディスカバリやトラフィック管理などを行う
      • A/Bテスト・カナリーリリースの実現や、タイムアウト・リトライ・サーキットブレーカーなどの手法を用いて Fault Isolation(障害の分離)の問題を解決することができる
    • Citadal : サービス間認証とエンドユーザ認証を実現する
      • この認証を利用することで、ポリシーベースでサービスメッシュを管理することができる。

サービスメッシュの本質

  • サービスメッシュの解決課題は、トラフィック管理、可観測性、セキュリティではない
  • インフラのコード化を実現したのがKubernetesこれをネットワークの世界に適用したのがサービスメッシュツールであるIstio

サービスメッシュの仕組み

  • サービスメッシュはアプリのサイドカーなので、拡張が可能
  • IstioのProxyとしてのEnvoyは、Envoyフィルタを利用して拡張を行う
  • Envoyフィルタは、Envoyコア機能に影響を与えずにカスタム機能を定義する
  • envoy.yamlによって追加機能をコード化することでIaCを実現可能

参考

UUID, ULIDとは?

UUIDとは?

開発時にデータに一意なIDを割り振る際によく用いられる。

UUIDには複数のバージョンがあり、UUID v4がよく用いられている。

特徴

  • ビット幅は 128ビット(16バイト) で、文字列表現では16進法で以下のような形で表現する。
  • (32バイト+バウンダリ4バイト=36バイト。 "-" がバウンダリ文字列)
550e8400-e29b-41d4-a716-446655440000

UUID v4

  • UUID v4は、ランダムな値に基づいて生成される128ビットの識別子
  • 生成ごとに完全にランダムな値が生成される
  • 衝突可能性も0ではないが、現実的には衝突ので安全に利用できる

UUID v7

  • UUID v7は、UUID v4と同様に128ビットのランダムな識別子
  • 現在の時刻を表すタイムスタンプに基づいて生成される
  • タイムスタンプは、ナノ秒単位の精度まで含まれる
  • このため、生成時刻の順序が保証され、生成時刻を基準にソートが可能

ULID

  • ULIDとは、UUIDと同様にランダムな識別子
  • UUID v4とは違い、先頭48ビットにタイムスタンプを置くことにより、ソート可能
  • 1ミリ秒単位でソート順が保証されており、同一の生成器であれば280までソート順が保証される。

それぞれの識別子フォーマット

UUID(Ver.4)
2ec40df6-7587-42ee-bf83-ef97a3e46556

UUID(Ver.7)
018422b2-4843-7a62-935b-b4e65649de3e

ULID
01GWKR0SQ0KD0QZ3SHEEAM8YDJ

参考URL

New Relic アラートについて

New Relicのアラートのコンポーネント構成

  • アラート条件(Alert Condition)に定義した条件違反が検出されると、Incidentが作成される
  • Incidentは、Alert Policyの設定にしたがってグルーピングされ、Issueとなる
  • IssueがWorkflowをトリガーして、実際にユーザーへの通知が行われる

アラート条件の集計結果

  • シグナル
    • 集計結果は、シグナルと呼ばれるデータセットとして記録される
      • FACETで複数対象の監視を行っている場合、監視対象ごとにシグナルが作成される
  • Incident
    • シグナルの値と、アラート条件の閾値が比較評価され、条件を満たす場合にはIncidentが作成される
  • 集計処理
    • 収集データ(シグナル)の格納処理、アラートパイプライン処理(フィルタリング、データ集計、評価)は並行して行われる

集計方法の選択

データ転送の特徴によって、適切な集計方法を選択することで有用な結果を得られる。

Event Flow

データが一定間隔で確実に到着し、タイムラグが少ない場合に選択

Event Timer

  • データのタイムスタンプと集計時点との間にタイムラグがある場合
  • 例えば、ログメッセージなど、エラー時にのみ発生するようなデータ、またはバッチ処理で取得するメトリクスのような場合が適している

参考URL

Kotlin 処理実行時間をhh:mm:ssのフォーマットで出力する

バッチなどで経過時間をログ出力したいときに、ミリ秒表示などではなく時間形式で表示したい場合の処理を記載しておく。

fun main() {
    val begin = System.nanoTime()
 
    /*コードが始まります*/
 
    //2秒間スリープします
    Thread.sleep(2000)
 
    /*コードは終了します*/
 
    val end = System.nanoTime()
    val elapsedTime = formatElapsedTime(end-begin)
 
    println("Elapsed time: ${elapsedTime}")
}

/**
 * 経過時間(ナノ秒)をhh:mm:ssのフォーマットで出力する
 */
fun formatElapsedTime(elapsedTimeNanos: Long): String {
    val elapsedTimeSeconds = elapsedTimeNanos / 1_000_000 / 1_000
    val hours = elapsedTimeSeconds / 3600
    val minutes = (elapsedTimeSeconds % 3600) / 60 // 1時間の剰余の秒/60秒
    val seconds = (elapsedTimeSeconds % 60) // 1分の剰余の秒
    return String.format("%02d:%02d:%02d", hours, minutes, seconds)
}

参考URL

UTで現在時刻を扱うとき使う java.time.Clock

UTで現在時刻を扱う際の課題

現在時刻を取得するためにSystem.currentTimeMills()やLocalDateTime.now()などのstatic methodを呼び出して利用することが多いが、static methodを利用して現在時刻を取得するとテストで利用する際の時刻のスタブを用意しずらくなる。

Clockクラスを用いるとスタブを用意しやすい

static methodではなく、Clockのインスタンスメソッドを使って現在時刻を取得するため、テストでスタブを用意しやすくなる。 時間設定もfixedというメソッドがあるため、簡単に設定可能。

SpringでClockを用いるときは、BeanとしてClockインスタンスを定義しておき、利用する。

@Bean
    fun clock(): Clock = Clock.fixed(Instant.parse("2023-11-13T00:00:00.00Z"), ZoneId.systemDefault())

実装では、コンストラクタインジェクションでDIして利用。

テストでは、@MockとMockitoを利用して固定のInstantを返却する。

class SampleBeanTest {

  @MockBean
  Clock clock;
  
  @InjectMocks
  SampleBean sampleBean;
  
  @Test
  public testSample(){
  
    when(clock.instant()).thenReturn(Instant.parse("2023-11-13T00:00:00Z"))
  
    // ...
  }
}

参考URL