本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用 Amazon EC2 实例元数据
适用于 Amazon EC2 实例元数据服务的 Java SDK 客户端(元数据客户端)允许您的应用程序访问其本地 EC2 实例上的元数据。元数据客户端使用 IMDSv2(实例元数据服务 v2)的本地实例,并使用面向会话的请求。
SDK 中有两个客户端类可用。同步 Ec2MetadataClient
用于阻塞操作,Ec2MetadataAsyncClient
开始使用
要使用元数据客户端,请将 imds
Maven 构件添加到您的项目中。您还需要在类路径上具有 SdkHttpClient
的类,或对于异步变体而言,具有 SdkAsyncHttpClient
的类。
以下 Maven XML 显示了使用同步 UrlConnectionHttpClient
<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>
VERSION
</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>imds</artifactId> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>url-connection-client</artifactId> </dependency> <!-- other dependencies --> </dependencies>
在 Maven Central 存储库bom
构件的最新版本。
要使用异步 HTTP 客户端,请替换 url-connection-client
构件的依赖项片段。例如,以下片段引入了 NettyNioAsyncHttpClient
<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>netty-nio-client</artifactId> </dependency>
使用元数据客户端
实例化元数据客户端
当类路径上只有一个 SdkHttpClient
接口的实现时,您可以实例化同步 Ec2MetadataClient
的实例。为此,请调用 static Ec2MetadataClient#create()
方法,如以下代码段所示。
Ec2MetadataClient client = Ec2MetadataClient.create(); // 'Ec2MetadataAsyncClient#create' is the asynchronous version.
如果您的应用程序有多个 SdkHttpClient
或 SdkHttpAsyncClient
接口的实现,则必须指定一个实现以供元数据客户端使用,如可配置 HTTP 客户端部分所示。
注意
对于大多数服务客户端(例如 Amazon S3),适用于 Java 的 SDK 会自动添加 SdkHttpClient
或 SdkHttpAsyncClient
接口的实现。如果您的元数据客户端使用相同的实现,则 Ec2MetadataClient#create()
将起作用。如果您需要不同的实现,则必须在创建元数据客户端时指定它。
发送请求
要检索实例元数据,请实例化 EC2MetadataClient
类,然后使用指定实例元数据类别的路径参数调用 get
方法。
以下示例将与 ami-id
键关联的值打印到控制台。
Ec2MetadataClient client = Ec2MetadataClient.create(); Ec2MetadataResponse response = client.get("/latest/meta-data/ami-id"); System.out.println(response.asString()); client.close(); // Closes the internal resources used by the Ec2MetadataClient class.
如果路径无效,则 get
方法将引发异常。
请对多个请求重复使用同一个客户端实例,但当不再需要该客户端时,请在该客户端上调用 close
来释放资源。调用 close 方法后,将无法再使用客户端实例。
解析响应
EC2 实例元数据可以以不同的格式输出。纯文本和 JSON 是最常用的格式。元数据客户端提供了使用这些格式的方法。
如以下示例所示,使用 asString
方法以 Java 字符串的形式获取数据。您还可以使用 asList
方法来分隔返回多行的纯文本响应。
Ec2MetadataClient client = Ec2MetadataClient.create(); Ec2MetadataResponse response = client.get("/latest/meta-data/"); String fullResponse = response.asString(); List<String> splits = response.asList();
如果响应采用 JSON 格式,请使用 Ec2MetadataResponse#asDocument
方法将 JSON 响应解析为 Document
Document fullResponse = response.asDocument();
如果元数据的格式不是 JSON,则会引发异常。如果成功解析了响应,则可以使用 document API
配置元数据客户端
重试
您可以为元数据客户端配置重试机制。如果这样做,则客户端可以自动重试因意外原因而失败的请求。默认情况下,客户端对失败的请求重试三次,两次尝试之间的时间呈指数回退。
如果您的用例需要不同的重试机制,则可以使用其客户端生成器上的 retryPolicy
方法自定义客户端。例如,以下示例将同步客户端配置为共五次重试,每两次重试之间固定延迟两秒钟。
BackoffStrategy fixedBackoffStrategy = FixedDelayBackoffStrategy.create(Duration.ofSeconds(2)); Ec2MetadataClient client = Ec2MetadataClient.builder() .retryPolicy(retryPolicyBuilder -> retryPolicyBuilder.numRetries(5) .backoffStrategy(fixedBackoffStrategy)) .build();
您可以将多种 BackoffStrategies
您也可以完全禁用重试机制,如以下代码段所示。
Ec2MetadataClient client = Ec2MetadataClient.builder() .retryPolicy(Ec2MetadataRetryPolicy.none()) .build();
使用 Ec2MetadataRetryPolicy#none()
会禁用默认的重试策略,因此元数据客户端不尝试重试。
IP 版本
默认情况下,元数据客户端使用位于 http://169.254.169.254
的 IPV4端点。要将客户端更改为使用 IPV6 版本,请使用生成器的 endpointMode
或 endpoint
方法。如果在生成器上同时调用这两个方法,则会出现异常。
以下示例演示两个 IPV6 选项。
Ec2MetadataClient client = Ec2MetadataClient.builder() .endpointMode(EndpointMode.IPV6) .build();
Ec2MetadataClient client = Ec2MetadataClient.builder() .endpoint(URI.create("http://[fd00:ec2::254]")) .build();
主要特征
异步客户端
要使用非阻塞版本的客户端,请实例化 Ec2MetadataAsyncClient
类的实例。以下示例中的代码使用默认设置创建异步客户端,并使用 get
方法检索 ami-id
键的值。
Ec2MetadataAsyncClient asyncClient = Ec2MetadataAsyncClient.create(); CompletableFuture<Ec2MetadataResponse> response = asyncClient.get("/latest/meta-data/ami-id");
当响应返回时,get
方法返回的 java.util.concurrent.CompletableFuture
就完成了。以下示例将 ami-id
元数据打印到控制台。
response.thenAccept(metadata -> System.out.println(metadata.asString()));
可配置 HTTP 客户端
每个元数据客户端的生成器都有一种可用于提供自定义 HTTP 客户端的 httpClient
方法。
以下示例显示了自定义 UrlConnectionHttpClient
实例的代码。
SdkHttpClient httpClient = UrlConnectionHttpClient.builder() .socketTimeout(Duration.ofMinutes(5)) .proxyConfiguration(proxy -> proxy.endpoint(URI.create("http://proxy.example.net:8888")))) .build(); Ec2MetadataClient metaDataClient = Ec2MetadataClient.builder() .httpClient(httpClient) .build(); // Use the metaDataClient instance. metaDataClient.close(); // Close the instance when no longer needed.
以下示例显示了带有异步元数据客户端的自定义 NettyNioAsyncHttpClient
实例的代码。
SdkAsyncHttpClient httpAsyncClient = NettyNioAsyncHttpClient.builder() .connectionTimeout(Duration.ofMinutes(5)) .maxConcurrency(100) .build(); Ec2MetadataAsyncClient asyncMetaDataClient = Ec2MetadataAsyncClient.builder() .httpClient(httpAsyncClient) .build(); // Use the asyncMetaDataClient instance. asyncMetaDataClient.close(); // Close the instance when no longer needed.
本指南中的 HTTP客户 主题详细介绍了如何配置适用于 Java 的 SDK 中可用的 HTTP 客户端。
令牌缓存
由于元数据客户端使用 IMDSv2,因此所有请求都与会话关联。会话由带过期时间的令牌定义,元数据客户端会为您管理该令牌。每个元数据请求都会自动重复使用令牌,直到令牌过期。
默认情况下,令牌持续六小时(21600 秒)。除非您的特定用例需要高级配置,否则我们建议您保留默认的生存时间值。
如果需要,可使用 tokenTtl
生成器方法配置持续时间。例如,以下代码段中的代码创建了一个会话持续时间为五分钟的客户端。
Ec2MetadataClient client = Ec2MetadataClient.builder() .tokenTtl(Duration.ofMinutes(5)) .build();
如果您省略调用生成器上的 tokenTtl
方法,则改用默认持续时间 21,600。