AWSからのEKS(弾性Kubernetesサービス)におけるGolangを用いたSQSメッセージの消費


davide ragusaによるUnsplash写真
数日前、ゴングでSQSに取り組んでいました.かなりトリッキーですが、私に十分な強調.私は私の消費者はEKSでよく働いているように5日間だけ立ち往生したので.
若干の文脈を与えるために、SQSは単純な待ち行列サービスの略です.AWSが提供するメッセージキューサービスです.詳細については、SQS from AWSの公式ページでご覧いただけます.
それを短くするために、私はSQSから多くのメッセージを消費する必要があるアプリケーションを持っていると仮定します.
単純に、私たちは、SQSメッセージを消費するためにAWS SDK Goを使用することができます.しかし、流れは私がGoogle Pubsubで経験したものと全く異なります.GCPでは、Google PubSubからメッセージを長く消費/ストリーミングする機能をすでに持っている完全なSDKを準備しました.AWS(特にSQS)では、長いループを作り、待ち行列のメッセージを引くために、残りの呼び出しをする必要があります.
それで、我々がすることは基本的にちょうどこのものすごい記事をコピーすることです.
func (c \*consumer) Consume() {
 for w := 1; w <= c.workerPool; w++ {
  go c.worker(w)
 }
}func (c \*consumer) worker(id int) {
 for {
  output, err := retrieveSQSMessages(c.QueueURL, maxMessages)
  if err != nil {
   continue
  } var wg sync.WaitGroup
  for \_, message := range output.Messages {
   wg.Add(1)
   go func(m \*message) {
     defer wg.Done()
     if err := h(m); err != nil {
       //log error
       continue
     }
     c.delete(m) //MESSAGE CONSUMED
   }(newMessage(m))

   wg.Wait()
  }
 }
}
はい、私は彼のコードをコピーします.それはすでに良い探しているので.労働者パターンで.では、なぜそれを正しく使用しないのですか?
TLRでも今は2つの問題がある
  • チェーン資格証明書問題
  • SQS からのメッセージを消費するとき、
  • タイムアウトエラー

    SQS消費者設計:Goにおける並行性を管理しながら高いスケーラビリティを達成する 問題声明


    チェーン資格証明書


    我々の問題は労働者やスタッフとは関係がない.それはSDK導入に続いて私たちから始まります.
    それで、デフォルトのSDKは認証のための順序を持っています.あなたがこのページに行くならば、「 」、あなたはチェーン資格証明命令についてわかります.
    Configuring the AWS SDK for Goチェーン資格証明書
    そのドキュメントから、我々はSDKが最初にENVキーを探すことを学ぶことができます.存在しない場合は、共有資格ファイルを探します.また、資格情報ファイルも存在しない場合は、EC 2のIAMロールなどを見てください.
    したがって、ここでの問題は、SDKのデフォルトの設定が最初にenv変数をロードするので、ここで問題があることです.そして、ローカルワークスペースのために、/に位置するAWS Configの資格情報ファイルを調べます.AWS/資格情報(Mac/Linux)(詳細については、を読むことができます).
    それは私たちにとって問題になります.プロジェクトは私たちのためだけに使用されませんが、別のチームで他のエンジニアよりも.私たちは、設定されたAWSコンフィグを持っている他のエンジニアに、それが/に位置しているということを恐れます.AWS/資格情報.私たちは、ローカルでアプリケーションを実行する機会があると仮定します.AWS/資格情報.
    だから、本当に欲しいのは
  • ローカル開発、我々はENV変数
  • を使用します
    ステージと生産に関して、我々はIAM役割を使います.
  • 最初の場所で共有資格情報ファイルを使用しないでください.他のエンジニアによって誤って生産アクセス資格ファイルを使用しないようにします.
  • 最初の試み解決
    最初の解決策は、IAMロールを最初に検出します.存在しない場合は、我々のアプリケーションはAwsHand AccessLes Keychen IDとAwsSignal SecretRadiusキーであるEnvキーを検索します.
    そこで、下記のようにチェーンの資格情報をカスタマイズしました
    < div >
    上記の関数、特にCreodProviderを見ると、資格情報連鎖プロバイダーの注文を指定します.まず、インスタンスIAMロールを調べ、Envプロバイダーを検索します.したがって、基本的に共有資格情報ファイルを使用して認証を削除します.それで、エンジニアが設定されたAWS資格情報キーを持っているときはいつでも、彼らのPCでは/に位置します.AWS/資格情報、それはまだ安全です、SDKがIAM役割とEnvキーだけを探すので.p >
    < br/> < br/> < br/>
    カスタムチェーンの資格情報を作成した後、我々は別の問題を発見した.EC 2インスタンスではよく実行できますが、EKSでは使えません.要するに、私たちのチェーン資格証明書はEC 2のインスタンスレベルでのみ働きます.そして、EKSケースのために、私たちがノードレベルでIAM役割を許すだけであるなら、それは働きますp >
    セキュリティのために、EKSのために、私たちはサービスアカウントレベルまたはPODレベルにIAMロールを使用したいです、ノードレベルではなく、ここでの例で見つけることができますp >
    したがって、我々のカスタムチェーン資格証明書はEksのためにうまく機能していません.そこで、チェーンメソッドを変更する必要があります.p >
    <最終回> < br/> < br/>
    それを修正するために、我々はそれから我々の技術者と一緒に座ります.アプリケーションの議論とデバッグ.一日中、多くの試みで、我々は最終的に我々のアプリケーションで論理的に解決策を決めることを決めますp >
    < tt > EOKSで動作するように、共有資格情報ファイルを有効にしなければなりません.EKSではAWSUNE WebCount IdentityExtentenChrenファイルを使用するためです.p >
    したがって、Webアイデンティティトークンファイルを使用するには、ファイルを使用して資格情報を有効にする必要があります.EKSでうまく動作するためには、共有された資格情報ファイルを使用してチェーン認証を有効にすることを決定します.p >
    しかし、エンジニアのローカル共有資格ファイル~/を避けるために.誤って使用されているAWS/資格情報は、我々は、アプリケーション内で論理的に処理することを決定します.p >
    <高橋潤子>**この項目の翻訳は古いバージョンが元になっています**br/>
    <> P >
    クラスをハイライト表示する
    // IsLocal will return true if the APP\_ENV is not listed in those
    // three condition
    
    func IsLocal() bool {
      envLevel := MustHaveEnv("APP\_ENV")
      return envLevel != "production" && 
             envLevel != "staging" &&   
             envLevel != "integration"
    }
    
    < div >
    したがって、AppCount ENVの値に関係なく、生産やステージングや統合でなければ、ローカルと仮定します.p >
    < div class ="LagagCount - gig - Link - tag "
    "スクリプトのID "https://gist.github.com/bxcodec/31d2b5445f6116ee06b9ca685ea3c70a.js//>
    < div >
    <高橋潤子> <山田>そして、それがローカルであるならば、我々はEnvキーを使用します、そして、それは必要です、したがって、我々は偶然に、エンジニアのローカルワークスペース~で生産アクセス資格証明書を使用するのを避けることができます/...証明書p >
    これにより、SDKの資格情報を問題なく解決します.私たちはエンジニアにEnvキーをローカルで使用するように強制します(hereを使用して).そして、ステージングとプロダクション

    で共有資格情報ファイルを使用します

    サービスアカウントのための細粒度IAMロールの導入 カスタマイズHTTPクライアントの使用


    もう一つの問題は、SQSメッセージを消費しようとする時です.しかし、それについての詳細を伝える前に、AWS SDKドキュメンテーションページで若干の文脈を与えるために、我々はこの記事を「article」とわかりました.このページでHTTPクライアントのカスタマイズ方法を見つけました.p >
    <堀田>
    <高橋潤子> <高橋潤子>
    それから、我々はちょうどこれらのステップに従います.HTTPクライアントをカスタマイズしました.タイムアウト、最大アイドル接続等を設定し、ローカルで実行します( localstackに感謝します).我々は地元でテストし、すべてがうまくいきます.完全に動作します.p >
    < br/> < br/> < br/>
    しかし、それから我々がEKSでそれを展開しようとしたとき.EKSに配備された後、エラーがたくさん発生しましたbr/>
    <> P >
    クラスをハイライト表示する
    time="2020-02-06T07:23:02Z" level=error msg="there was an error reading messages from SQS RequestError: send request failed\ncaused by: Post [https://sqs.ap-southeast-2.amazonaws.com/](https://sqs.ap-southeast-2.amazonaws.com/): net/http: request canceled (Client.Timeout exceeded while awaiting headers)"
    time="2020-02-06T07:23:02Z" level=error msg="there was an error reading messages from SQS RequestError: send request failed\ncaused by: Post [https://sqs.ap-southeast-2.amazonaws.com/](https://sqs.ap-southeast-2.amazonaws.com/): net/http: request canceled (Client.Timeout exceeded while awaiting headers)"
    
    < div >
    実際にこれは大きな問題ではありませんが、これは私たちのログストレージを迷惑化し、増加します.なぜなら、これはHTTPコールを使用してSQSからの長いメッセージを引っ張ってくるためです.これを解決するには、私は2日かかる!私の全部の2日は、これのために滅びました.<武井>p >
    <最終回> < br/> < br/>
    私はイライラされました、なぜこの問題が私のチームで起こっているかについて理解する誰もいません.そして、私はゴーファーのスラックグループで尋ねましたp >
    そして、スラックゴーファー Creating a Custom HTTP Clientと他に感謝します.彼らは、私がここで私の問題を解決するのを助けますp >
    要約すると、これは長いポーリングを有効に使用するためですが、長いポーリング、接続が有効になっているので、HTTPクライアントをカスタマイズしています.p >
    したがって、解決策は、長いポーリングがSQSからメッセージを消費するために、HTTPクライアントをカスタマイズしてはいけません.なぜなら、HTTPクライアント(タイムアウトなど)をカスタマイズした場合、長いポーリング接続時間と競合し、要求がキャンセルされた(ヘッダを待っている間にclient . timeoutを超える)エラーが発生します.p >
    私が知っている限り、悪いタイムアウトとユーザーエクスペリエンスを避けるために、私は通常私のHTTPクライアントをカスタマイズしました.しかし、この例では、SQSのために、長いポーリング呼び出しを有効にするので、正しい解決はタイムアウト設定を持っていないデフォルトのHTTPクライアントを使用するだけです.p >

    結論


    < tt > EOSで囲碁とSISを統合する場合、このプロジェクト全体からの取り出しは以下の通りです
    <ウル>
  • AWS SDKのカスタムチェーン資格証明書を手動で処理し、ローカルのワークスペースのエンジニアの生産アクセス資格情報ファイルを使用しないようにします.AWS/資格情報.
  • PODレベルでIAMロールを有効にするには、SDKが共有資格情報ファイルを使用できるようにする必要があります.これはローカルのワークスペースで無効になっているので、非常にトリッキーです.
  • 私たちはコードで論理的にチェーン資格情報を扱います.
  • 長いポーリング接続がSQSメッセージを消費するのを可能にするなら、デフォルトHTTPクライアントを使用しなければなりません.
    localstack
  • < ull >
    < hr/>