Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Deep Dive into AWS SDK for Java

hata
October 20, 2020

Deep Dive into AWS SDK for Java

AWS で Java アプリケーションを開発する全ての人ににとってためになる(わけでもない小ネタ集です)。

AWS SDK for Java の以下について
* ソースコードの構成 ( both 1.x & 2.x )
* 内部動作
* 多様な機能
* 最適化やチューニング

AWS DevDay Online Japan 2020 登壇資料。

hata

October 20, 2020
Tweet

More Decks by hata

Other Decks in Programming

Transcript

  1. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Deep Dive into AWS SDK for Java 知ってると役に立つかもしれない Java SDK の コードの構成、内部動作、機能、最適化 Fumihiko Hata, Solutions Architect, AWS Japan C - 2 2 0 . 1 0 . 2 0 2 0
  2. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 自己紹介 • 畑 史彦 AWS Japanソリューションアーキテクト • 普段は AWS を活用した課題解決の提案や 設計の相談などをさせていただいていいます • Java は以前に開発で数年使っていました(v5~9) • 好きな 命令コード: InvokeDynamic (JEP303) • 好きな GC の実装: Epsilon GC (JEP318)
  3. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Scope 話すこと AWS SDK for Java 自体の設計や実装 AWS SDK for Java の 多様な機能 最適化・チューニング 話さないこと AWS と AWS の各種サービス Java や JVM Java 以外の SDK AWS SDK for Java の基本的な使い方
  4. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Scope 注意点 • 特に説明なく「Java SDK」や「SDK」と表記している 場合は「AWS SDK for Java」を指します。 • 扱う Java SDK のソースコードは すべて v1.11.882 または v2.15.9 を対象としています。 • https://github.com/aws/aws-sdk-java/tree/1.11.882 • https://github.com/aws/aws-sdk-java-v2/tree/2.15.9 • 記載内容は今後の開発などによって実際の内容と乖離 する可能性があります。 常に公式のドキュメントとお使いのバージョンの ソースコードをご参照ください。
  5. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Contents 1. Amazon/AWS と Java 2. AWS SDK for Java とは 3. 大まかな処理の流れと内部動作 4. コードベースの構成 5. version 2 6. 機能・最適化 7. 開発・設計 8. まとめ
  6. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with
  7. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Amazon Corretto • OpenJDK ディストリビューションのダウンストリーム バイナリ • Amazon 社内の数千の本番サービスで使用 • 全てのパッチや機能改善は OpenJDK にアップストリームされる • Multiplatform : Linux, Windows, macOS, Docker, X86/X86-64, AARCH64 • OSS ライセンスのもとに配布、 LTS を無償提供: JDK8, JDK11 • https://github.com/corretto , https://aws.amazon.com/corretto
  8. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Amazon Corretto • OpenJDK ディストリビューションのダウンストリーム バイナリ • Amazon 社内の数千の本番サービスで使用 • 全てのパッチや機能改善は OpenJDK にアップストリームされる • Multiplatform : Linux, Windows, macOS, Docker, X86/X86-64, AARCH64 • OSS ライセンスのもとに配布、 LTS を無償提供: JDK8, JDK11 • https://github.com/corretto , https://aws.amazon.com/corretto https://twitter.com/errcraft/status/1062649279305711616
  9. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Amazon グループ内の数多くのシステムの開発に Java が使われている そこには当然 AWS も含まれる
  10. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Java in AWS itself https://d1.awsstatic.com/events/reinvent/2019/Migrating_AWS_Lambda's_front_end_from_Java_8_to_Java_11_OPN304.pdf https://www.youtube.com/watch?v=Cg3mM8UYh-Q
  11. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Java in AWS itself https://d1.awsstatic.com/events/reinvent/2019/Migrating_AWS_Lambda's_front_end_from_Java_8_to_Java_11_OPN304.pdf https://www.youtube.com/watch?v=Cg3mM8UYh-Q
  12. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Java in AWS itself https://d1.awsstatic.com/events/reinvent/2019/Migrating_AWS_Lambda's_front_end_from_Java_8_to_Java_11_OPN304.pdf https://www.youtube.com/watch?v=Cg3mM8UYh-Q
  13. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with AWS のサービス提供においても Java は非常に重要
  14. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Java Supports on AWS in Various Style AWS Lambda AWS Elastic Beanstalk Amazon Kinesis Data Analytics Amazon EMR Amazon Elasticsearch Service Amazon Redshift Amazon Athena AWS Glue Amazon Aurora Amazon CodeGuru AWS X-Ray AWS Cloud Development Kit (CDK) AWS Tools and SDKs AWS CodeBuild AWS Cloud9 AWS Artifact AWS CodeStar Java based MW/SW JDBC Connector Trace/Review/Profile Apps Computing/Runtime Package Management Interface Develop/Build Apps
  15. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Java Supports on AWS in Various Style AWS Lambda AWS Elastic Beanstalk Amazon Kinesis Data Analytics Amazon EMR Amazon Elasticsearch Service Amazon Redshift Amazon Athena AWS Glue Amazon Aurora Amazon CodeGuru AWS X-Ray AWS Cloud Development Kit (CDK) AWS Tools and SDKs AWS CodeBuild AWS Cloud9 AWS Artifact AWS CodeStar Java based MW/SW JDBC Connector Trace/Review/Profile Apps Computing/Runtime Package Management Interface Develop/Build Apps And more.. * Amazon Corretto: JVM * Heapothesys: GC Benchmarking * ACCP: high-performance cryptographic implementation * Container Insights Prometheus Metrics Monitoring etc.
  16. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Java Supports on AWS in Various Style AWS Lambda AWS Elastic Beanstalk Amazon Kinesis Data Analytics Amazon EMR Amazon Elasticsearch Service Amazon Redshift Amazon Athena AWS Glue Amazon Aurora Amazon CodeGuru AWS X-Ray AWS Cloud Development Kit (CDK) AWS Tools and SDKs AWS CodeBuild AWS Cloud9 AWS Artifact AWS CodeStar Java based MW/SW JDBC Connector Trace/Review/Profile Apps Computing/Runtime Package Management Interface Develop/Build Apps And more.. * Amazon Corretto: JVM * Heapothesys: GC Benchmarking * ACCP: high-performance cryptographic implementation * Container Insights Prometheus Metrics Monitoring etc.
  17. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with
  18. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with AWS SDK • AWS の各種サービスを操作するための REST API (Web API) への アクセスを便利に楽にしてくれる各種言語のバインディング • Java 以外にも .NET, Go, Python, Ruby, PHP, Node.js, C++, JavaScript • IDE や エディタのサポート/ツールキット
  19. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with AWS SDK for Java • AWS SDK の Java の実装。 AWS Services REST API Your Application Java API
  20. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with
  21. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 使用方法の典型例(1.x系): EC2 インスタンス の起動 1. AWS サービスに応じた Client Object の作成。 2. 必要なパラメータをセットした Request Object の作成。 3. 作成した Request Object を引数にして Client Object の該当アクションのメソッド (startInstances) 呼び出し。 1. 2. 3.
  22. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 使用方法の典型例(1.x系): EC2 インスタンス の起動 1. Client Object の作成 2. Request Object の作成 3. 該当アクションのメソッド (startInstances) 呼び出し。
  23. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 1. Client Object の作成 • 各サービスクライアント AmazonXxxxxClient (AmazonS3Client など)は 間接的に org.apache.http.client.HttpClient の拡張オブジェクトを保持する • アプリケーション内で初めてサービスクライアントが生成される際には IdleConnectionReaper という独立したデーモンも生成され、 HTTP クライアントを監視対象に追加する • IdleConnectionReaper は(デフォルトでは)60 秒ごとにアイドルなコネクション がないかを監視し続け、あればコネクションの解放を実行。 コネクションを GC するデーモンを導入しリソースリークを防止 AmazonXxxxxClient http Client AmazonYyyyyClient http Client AWS Services IdleConnectionReaper (daemon)
  24. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 2. Request Object の作成 • REST API への HTTP リクエストに詰めるパラメータを集約したオブジェ クトをビルドする
  25. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 3. 該当アクションのメソッド呼び出し • 1. で設定した挙動で 2. のパラメータを添えて HTTP リクエストが送信される • HTTP リクエストの送受信の挙動をカスマイズ可能にするために IRequestHandler2 Interface が多数のフックポイントを公開。 ユーザもこのサブクラスをさらに拡張して独自の処理を 挿入することができる。 AmazonXxxxxClient AWS Services 1 beforeExecution Request Object が AmazonXxxxxClient に渡されてすぐ 2 beforeMarshalling Request Object → http request 変換前 3 beforeRequest Client Runtime から実⾏される直前 4 beforeAttempt http request 実⾏直前 5 beforeUnmarshalling http response → Response Object 変換前 6 afterAttempt http request 実⾏の finally ブロック内 7 afterResponse http request 実⾏完了後 8 afterError http request 実⾏の catch ブロック内
  26. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 3. 該当アクションのメソッド呼び出し • AWS X-Ray では実際にこの RequestHandler2 を拡張した TracingHandler を使って AWS リソースへのアクセスを 透過的にトレーシングしている(※)。 AmazonXxxxxClient AWS Services ExecutionInterceptor Javadoc TracingInterceptor 1 beforeExecution Request Object が AmazonXxxxxClient に渡されてすぐ 2 beforeMarshalling Request Object → http request 変換前 3 beforeRequest Client Runtime から実⾏される直前 4 beforeAttempt http request 実⾏直前 5 beforeUnmarshalling http response → Response Object 変換前 6 afterAttempt http request 実⾏の finally ブロック内 7 afterResponse http request 実⾏完了後 8 afterError http request 実⾏の catch ブロック内
  27. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with
  28. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with /aws-java-sdk-{serviceName} • ルートフォルダを見るとサービス毎の 大量のサブフォルダが目に付く • aws-java-sdk-{serviceName} • 開発中にエラーやトラブルがあると、 このあたりから覗くことになることが多い • ユーザが直接使うサービスクライアント (AmazonXxxxxClient)もこの中 • 継承と委譲でできる限り共通処理は /aws-java-sdk-core に分離されているが、 それでもサービスごとの大量のコードが格納
  29. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with フォルダ構成 • ルートフォルダを見るとサービス毎の 大量のサブフォルダが目に付く • aws-java-sdk-{serviceName} • いくつかの特別なサブフォルダ • aws-java-sdk-core 各種サービス固有ではない共通の処理の クラス群 • aws-java-sdk 全サービスの依存を含めた pom.xml • release-resources リリース作業用のビルド定義 (Amazon CodeBuild の buildspec YAML ) • aws-java-osgi OSGI (Open Service Gateway Initiative)
  30. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with /aws-java-sdk-core • ルートフォルダを見るとサービス毎の 大量のサブフォルダが目に付く • aws-java-sdk-{serviceName} • いくつかの特別なサブフォルダ • aws-java-sdk-core 各種サービス固有ではない共通の処理の クラス群 • aws-java-sdk 全サービスの依存を含めた pom.xml • release-resources リリース作業用のビルド定義 (Amazon CodeBuild の buildspec YAML ) • aws-java-osgi OSGI (Open Service Gateway Initiative)
  31. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with
  32. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with AWS SDK for Java Version 2.x • 2017年に Developer Preview、2018年に GA https://github.com/aws/aws-sdk-java-v2 • 1.x 系からの改善や新機能 • HTTP Client の実装をプラガブルに。非同期クライアントはデフォルトで Netty • ノンブロッキング I/O をサポート • 自動ページネーションにより、ページングのためのループを書かなくて良くなった • HTTP Client のオブジェクトを複数のサービスクライアントで共有可能に • 多くのオブジェクトが Immutable になり、スレッド安全性が向上 Service Client, Request Object, Response Object, etc. • SDK 起動時間の短縮 ※ 1.x 系の SDK も引き続きアクティブにメンテされています https://aws.amazon.com/jp/blogs/developer/aws-sdk-for-java-2-x-released/ https://aws.amazon.com/jp/blogs/developer/aws-sdk-for-java-2-0-developer-preview/
  33. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 2.x 系ではまだサポートされていない機能 • 各 AWS サービスの高レベル ライブラリ • S3 Transfer Manager • S3 Encryption Client • DynamoDB document APIs • DynamoDB Encryption Client • SQS Client-side Buffering • Waiters → 2020年10月 GA • SDK Metrics Publisher → 2020年8月 GA • Progress Listeners https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/welcome.html#features-notyet
  34. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 1.X から 2.x への移行 • 基本的には 2.x 系を使ったほうが高性能・高機能 かつ使いやすい • マイグレーションガイド バージョン間の差異についても詳細に整理されている https://docs.aws.amazon.com/sdk-for-java/v2/migration-guide/what-is-java-migration.html
  35. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 1.X と 2.x の併用 • AWS サービスの単位で併用が可能 • 移行が難しい箇所があればその AWS サービス周りは 1.x を使い、 それ以外は 2.x を使うということも可能 https://docs.aws.amazon.com/sdk-for-java/v2/migration-guide/side-by-side.html
  36. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 2.x 系のコードベース • サービスごとの固有実装部分は /services 配下に移動 • 少数の JSON ファイルのみ • REST API の情報を記載した JSON ファイルからコード生成する仕組みに(※) • コード生成は Maven • チェックアウトして mvn clean install –P quick でOK • コード生成自体の実装は /codegen と /codegen-lite 配下に • 最終的な .java の書き出しには JavaPoet を使用 https://github.com/square/javapoet • コード全体をざっと読みたい場合は、まずはローカルでビルドを! ※ 正確には 1.x 系でもコード生成自体は活用されている。ただし、生成したコードはリポジトリに コミットされていたので GitHub 上でもコードが直接追いやすかった。
  37. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 2.x 系のコードベース • 共通処理の部分は 1.x 系同様に /core 配下にまとまっている • 他にいくつか大きな機能の実装がトップレベルに • /http-clients 2.x 系では HTTP クライアントの実装がプラガブルになった。その共通部分と各個別部分 • /http-clients-spi SDK のメトリクス送信機能、そのコア部分やインターフェイスなど • /metric-publishers/cloudwatch-metric-publisher 送信先ごとのメトリクス送信の実際の実装。現在は CloudWatch のみビルトインで提供 • /services-custom/dynamodb-enhanced Amazon DynamoDB の高レベルクライアント
  38. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with
  39. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 機能とチューニング 1. Consumer Builder Pattern 2. SDK Metric Publisher 3. Waiter 4. AWS Common Runtime HTTP Client 5. AWS Lambda のコールドスタートの最適化 6. 通信と接続の最適化 • enhanced DynamoDB client (割愛)
  40. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Consumer Builder Pattern • Java 8 の Lambda 式を活用したビルダーパターン。↓これが https://aws.amazon.com/jp/blogs/developer/consumer-builders-in-the-aws-sdk-for-java-v2/
  41. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Consumer Builder Pattern • Java 8 の Lambda 式を活用したビルダーパターン。こう書ける↓ https://aws.amazon.com/jp/blogs/developer/consumer-builders-in-the-aws-sdk-for-java-v2/
  42. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with SDK Metric Publisher • SDK による通信や処理のレイテンシ情報を Amazon CloudWatch に 送信可能 (1.x にも同様の機能がある) • MetricPublisher インターフェイスを実装すれば独自の送信処理も 可能なので、ローカル開発時のロギングにも使える https://aws.amazon.com/jp/blogs/developer/using-the-new-client-side-metrics-feature-in-the-aws-sdk-for-java-v2/ https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/configuration-metrics-list.html
  43. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with SDK Metric Publisher https://aws.amazon.com/jp/blogs/developer/using-the-new-client-side-metrics-feature-in-the-aws-sdk-for-java-v2/ https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/configuration-metrics-list.html
  44. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with Waiter • リソース作成処理のあとに作成完了を待つような場面でポーリングを 自分で書かなくてもよい (1.x にも同様の機能がある) • 例えば DynamoDB のテーブルを作成して、データ Put する前に作成完 了を待つ、など • 同期/非同期 両クライアントをサポート • タイムアウトや試行回数などは設定変更が可能 https://aws.amazon.com/jp/blogs/developer/using-waiters-in-the-aws-sdk-for-java-2-x/
  45. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with AWS Common Runtime HTTP Client • 2.x 系の大きな特長として HTTP Client の実装がプラガブルになったこ とがある • 1.x 系のように Apache HTTP Client に縛られない • そして Java SDK 2.x のために新たに書かれた HTTP Client が AWS Common Runtime HTTP Client https://github.com/awslabs/aws-crt-java https://aws.amazon.com/jp/blogs/developer/introducing-aws-common-runtime-http-client-in-the-aws-sdk-for-java-2-x/
  46. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with AWS Common Runtime HTTP Client 特長(一部) • 起動時間の短縮 • 独自の非同期 DNS リゾルバ • 遅い接続を自動リフレッシュ 注意点 • HTTP/2 を未サポート → KinesysAsyncClient など HTTP/2を必要 とするものには使えない https://aws.amazon.com/jp/blogs/developer/introducing-aws-common-runtime-http-client-in-the-aws-sdk-for-java-2-x/
  47. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with AWS Lambda のコールドスタートの最適化 o 2.x 系にデフォルトで入った起動速度向上のための改善 • Jackson-jr を使用、 JodaTime をやめ java.time を採用、slf4j を採用、 1. 各種ルックアップ時間の短縮 1. リージョンを明示 → 最大 80 ms の高速化 2. EnvironmentVariableCredentialsProvider でクリデンシャルを明示 → 最大 90 ms の高速化 2. HttpUrlConnection や CrtClient などの軽量な HTTP Client に差し替える → 最大で秒レベルの高速化 3. pom.xml のSDK の依存を必要なものだけに絞る https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/client-configuration-starttime.html https://aws.amazon.com/jp/blogs/developer/tuning-the-aws-java-sdk-2-x-to-reduce-startup-time/
  48. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 通信と接続の最適化 • テストとベンチマークを実施しデフォルト値を最適化するのが推奨 • デフォルトの値は SdkHttpConfigurationOption Class にまとまっている https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/client-configuration-http.html
  49. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 通信と接続の最適化 • テストとベンチマークを実施しデフォルト値を最適化するのが推奨 • デフォルトの値は SdkHttpConfigurationOption Class にまとまっている • 設定の上書きは簡単↓ https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/client-configuration-http.html
  50. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with
  51. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 開発の進み方 • GitHub にホストされ Issue を起点に需要と設計を議論し進めている。 Issue 以外に Gitter やメールアドレスもある。 • https://gitter.im/aws/aws-sdk-java-v2 • バグや機能要望に対しては 広く Issue を受け付けている • Pull Request ももちろん • CONTRIBUTING.md
  52. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with 設計についての議論 • 本格的に着手された大型の機能の多くは 設計の詳細がドキュメントにまとまっている • Tenets や課題の整理などがされており、 既にリリースされた機能であってもこれらのドキュメントを読むと 理解が深まるのでおすすめ • aws-sdk-java-v2/docs/design
  53. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with aws-sdk-java-v2/docs/design
  54. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with aws-sdk-java-v2/docs/design/services/dynamodb/high-level-library
  55. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with
  56. © 2020, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. In Partnership with AWS SDK for Java まとめ ü 性能向上や安全性担保のための多数の工夫 ü モニタリングやフックなど多数の機能とカスマイズ性 ü OSS の柔軟性
  57. Thank you! © 2020, Amazon Web Services, Inc. or its

    affiliates. All rights reserved. In Partnership with Fumihiko Hata Happy Coding with Java & AWS!