web-dev-qa-db-ja.com

AmazonAWSラムダでSpringboot / cloudを使用しても、値が挿入されません

AWSによって直接呼び出されるAWSlambda RequestHandlerクラスがあります。最終的には、Spring Cloud構成サーバーからデータを取得できるようにする必要があるため、SpringBootで動作させる必要があります。

問題は、コードを自分の開発環境からローカルで実行すると機能するが、は設定値を挿入できないことですAWSにデプロイした場合

@Configuration
@EnableAutoConfiguration
@ComponentScan("my.package")
public class MyClass implements com.amazonaws.services.lambda.runtime.RequestHandler<I, O> {
   public O handleRequest(I input, Context context) {
        ApplicationContext applicationContext = new SpringApplicationBuilder()
                .main(getClass())
                .showBanner(false)
                .web(false)
                .sources(getClass())
                .addCommandLineProperties(false)
                .build()
                .run();

        log.info(applicationContext.getBean(SomeConfigClass.class).foo);
        // prints cloud-injected value when running from local dev env
        //
        // prints "${path.to.value}" literal when running from AWS 
        //    even though Spring Boot starts successfully without errors
   }
}

@Configuration
public class SomeConfigClass {
   @Value("${path.to.value}")
   public String foo;
}

src/main/resources/bootstrap.yml:
spring:
  application:
    name: my_service
cloud:
  config:
    uri: http://my.server
    failFast: true
    profile: localdev

私は何を試しましたか:

  • 通常のSpringMVCを使用しますが、これは @Valueインジェクション/ Springクラウドとの統合はありません
  • @PropertySourceを使用しています-しかし、.ymlファイルをサポートしていないことがわかりました
  • 構成サーバーが任意のIPアドレスへの要求を処理していることを確認しました(IPアドレスのフィルタリングはありません)
  • curlを実行して、値が確実に戻されるようにします
  • .jarが実際にjarルートにbootstrap.ymlを含むことを確認しました
  • .jarに実際にSpringBootクラスが含まれていることを確認しました。 FWIWプロジェクトをすべての依存関係を持つfat.jarにパッケージ化するMavenシェードプラグインを使用しています。

注:AWS Lambdaは環境変数をサポートしていません。したがって、spring.application.name(環境変数としても-Dパラメーターとしても)のようなものを設定することはできません。また、実際にMyClassを起動する基になるクラスを制御することもできません。これはエンドユーザーに対して完全に透過的です。 jarをパッケージ化してエントリポイント(クラス名)を提供するだけで、残りは処理されます。

見逃したことはありますか?これをもっとうまくデバッグできる方法はありますか?

14
mindas

少しデバッグした後、問題はMavenShadeプラグインの使用にあると判断しました。 Spring Bootは、自動構成jarでMETA-INF/spring.factories jarを探します ここを参照 これに関する情報については。 Spring Boot jarを正しくパッケージ化するには、 Spring Boot Mavenプラグイン を使用し、Mavenの再パッケージ化フェーズで実行するように設定する必要があります。ローカルで機能する理由IDE Shadeパッケージjarを実行していないためです。Shadeプラグインが認識していない適切な場所に物事を配置するために、プラグインで特別な魔法を実行します。 。

最初は値を挿入していなかったサンプルコードを作成できましたが、正しいプラグインを使用することで機能するようになりました。 this GitHub repo を参照して、私が行ったことを確認してください。

Spring Cloudに接続しませんでしたが、Spring Bootインジェクションの残りの部分が機能しているので、簡単なはずです。

コメントで述べたように、単純なREST呼び出しでクラウド構成を取得し、それを自分で注入して、すべてのリクエストでSpringアプリケーションをロードするオーバーヘッドを節約することを検討することをお勧めします。

更新:Spring Boot 1.4.xの場合、SpringBootプラグインで次の構成を提供する必要があります。

            <configuration>
                <layout>MODULE</layout>
            </configuration>

そうしない場合、プラグインの新しい動作は、jarを実行可能にし、bootstrapプロセスにロードさせることを目的としているため、すべてのjarをBOOT-INFの下に置くことです。 。ここで発生した状況に対する警告の追加に対処しているときにこれを見つけました。参照については https://github.com/spring-projects/spring-boot/issues/5465 を参照してください。

22
Rob Baily