

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用适用于 Kotlin 的软件开发工具包使用 Amazon S3 多区域接入点
<a name="use-services-s3-mrap"></a>

Amazon S3 多区域接入点提供了一种全局端点，应用程序可以使用该端点来满足来自位于多个 AWS 区域的 Amazon S3 存储桶的请求。您可以使用多区域接入点构建多区域应用程序，使用单个区域中使用的相同架构，然后在世界任何地方运行这些应用程序。

Amazon S3 用户指南包含有关[多区域接入点](https://docs.aws.amazon.com//AmazonS3/latest/userguide/MultiRegionAccessPoints.html)的更多背景信息。

## 使用多区域接入点
<a name="mrap-s3control-config"></a>

要创建多区域接入点，首先要在要处理请求的每个 AWS 区域中指定一个存储桶。以下代码段创建了两个存储桶。

### 创建存储桶
<a name="mrap-s3-create-buckets"></a>

以下函数创建两个用于多区域接入点的存储桶。一个存储桶在区域中`us-east-1`，另一个存储桶在区域中`us-west-1`。

作为第一个参数传入的 S3 客户端的创建如下的第一个示例所示[使用对象和多区域接入点](#mrap-s3client-config)。

```
        suspend fun setUpTwoBuckets(
            s3: S3Client,
            bucketName1: String,
            bucketName2: String,
        ) {
            println("Create two buckets in different regions.")
            // The shared aws config file configures the default Region to be us-east-1.
            s3.createBucket(
                CreateBucketRequest {
                    bucket = bucketName1
                },
            )
            s3.waitUntilBucketExists {
                bucket = bucketName1
            }
            println("  Bucket [$bucketName1] created.")

            // Override the S3Client to work with us-west-1 for the second bucket.
            s3.withConfig {
                region = "us-west-1"
            }.use { s3West ->
                s3West.createBucket(
                    CreateBucketRequest {
                        bucket = bucketName2
                        createBucketConfiguration = CreateBucketConfiguration {
                            locationConstraint = BucketLocationConstraint.UsWest1
                        }
                    },
                )
                s3West.waitUntilBucketExists {
                    bucket = bucketName2
                }
                println("  Bucket [$bucketName2] created.")
            }
        }
```

您可以使用 Kotlin SDK 的 [S3 控制客户端](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/s3control/aws.sdk.kotlin.services.s3control/-s3-control-client/index.html)来创建、删除和获取有关多区域接入点的信息。

添加对 S3 控件工件的依赖关系，如以下代码段所示。（您可以导航到该*X.Y.Z*链接以查看可用的最新版本。）

```
...
implementation(platform("aws.sdk.kotlin:bom:[https://github.com/awslabs/aws-sdk-kotlin/releases/latest](https://github.com/awslabs/aws-sdk-kotlin/releases/latest)"))
implementation("aws.sdk.kotlin:s3control")
...
```

配置要使用的 S3 控制客户端 AWS 区域 `us-west-2`，如以下代码所示。所有 S3 控制客户端操作都必须以该`us-west-2`区域为目标。

```
        suspend fun createS3ControlClient(): S3ControlClient {
            // Configure your S3ControlClient to send requests to US West (Oregon).
            val s3Control = S3ControlClient.fromEnvironment {
                region = "us-west-2"
            }
            return s3Control
        }
```

使用 S3 控制客户端通过指定存储桶名称（之前创建的）来创建多区域接入点，如以下代码所示。

```
    suspend fun createMrap(
        s3Control: S3ControlClient,
        accountIdParam: String,
        bucketName1: String,
        bucketName2: String,
        mrapName: String,
    ): String {
        println("Creating MRAP ...")
        val createMrapResponse: CreateMultiRegionAccessPointResponse =
            s3Control.createMultiRegionAccessPoint {
                accountId = accountIdParam
                clientToken = UUID.randomUUID().toString()
                details {
                    name = mrapName
                    regions = listOf(
                        Region {
                            bucket = bucketName1
                        },
                        Region {
                            bucket = bucketName2
                        },
                    )
                }
            }
        val requestToken: String? = createMrapResponse.requestTokenArn

        // Use the request token to check for the status of the CreateMultiRegionAccessPoint operation.
        if (requestToken != null) {
            waitForSucceededStatus(s3Control, requestToken, accountIdParam)
            println("MRAP created")
        }

        val getMrapResponse =
            s3Control.getMultiRegionAccessPoint(
                input = GetMultiRegionAccessPointRequest {
                    accountId = accountIdParam
                    name = mrapName
                },
            )
        val mrapAlias = getMrapResponse.accessPoint?.alias
        return "arn:aws:s3::$accountIdParam:accesspoint/$mrapAlias"
    }
```

由于创建多区域接入点是一项异步操作，因此您可以使用从即时响应中收到的令牌来检查创建过程的状态。状态检查返回成功消息后，您可以使用该`GetMultiRegionAccessPoint`操作来获取多区域接入点的别名。别名是 ARN 的最后一个组成部分，这是执行对象级操作所必需的。

### 使用令牌查看状态
<a name="mrap-s3-control-poll"></a>

使用`DescribeMultiRegionAccessPointOperation`来检查上次操作的状态。`requestStatus`值变为 “成功” 后，您就可以使用多区域接入点了。

```
        suspend fun waitForSucceededStatus(
            s3Control: S3ControlClient,
            requestToken: String,
            accountIdParam: String,
            timeBetweenChecks: Duration = 1.minutes,
        ) {
            var describeResponse: DescribeMultiRegionAccessPointOperationResponse
            describeResponse = s3Control.describeMultiRegionAccessPointOperation(
                input = DescribeMultiRegionAccessPointOperationRequest {
                    accountId = accountIdParam
                    requestTokenArn = requestToken
                },
            )

            var status: String? = describeResponse.asyncOperation?.requestStatus
            while (status != "SUCCEEDED") {
                delay(timeBetweenChecks)
                describeResponse = s3Control.describeMultiRegionAccessPointOperation(
                    input = DescribeMultiRegionAccessPointOperationRequest {
                        accountId = accountIdParam
                        requestTokenArn = requestToken
                    },
                )
                status = describeResponse.asyncOperation?.requestStatus
                println(status)
            }
        }
```

## 使用对象和多区域接入点
<a name="mrap-s3client-config"></a>

您可以使用 S [3 客户端](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/s3/aws.sdk.kotlin.services.s3/-s3-client/index.html)处理多区域接入点中的对象。您对存储桶中的对象使用的许多操作都可以在多区域接入点上使用。有关更多信息和操作的完整列表，请参阅[多区域接入点与 S3 操作的兼容性](https://docs.aws.amazon.com//AmazonS3/latest/userguide/MrapOperations.html#mrap-operations-support)。

使用多区域接入点的操作使用非对称 Sigv4 (Sigv4A) 签名算法进行签名。要配置 Sigv4a，请先将以下依赖项添加到您的项目中。（您可以导航到该*X.Y.Z*链接以查看可用的最新版本。）

```
...
implementation(platform("aws.sdk.kotlin:bom:[https://github.com/awslabs/aws-sdk-kotlin/releases/latest](https://github.com/awslabs/aws-sdk-kotlin/releases/latest)"))
implementation(platform("aws.smithy.kotlin:bom:[https://github.com/smithy-lang/smithy-kotlin/releases/latest](https://github.com/smithy-lang/smithy-kotlin/releases/latest)"))

implementation("aws.smithy.kotlin:aws-signing-default")
implementation("aws.smithy.kotlin:http-auth-aws")
implementation("aws.sdk.kotlin:s3")
...
```

添加依赖关系后，将 S3 客户端配置为使用 Sigv4a 签名算法，如以下代码所示。

```
        suspend fun createS3Client(): S3Client {
            // Configure your S3Client to use the Asymmetric SigV4 (SigV4a) signing algorithm.
            val sigV4aScheme = SigV4AsymmetricAuthScheme(DefaultAwsSigner)
            val s3 = S3Client.fromEnvironment {
                authSchemes = listOf(sigV4aScheme)
            }
            return s3
        }
```

配置 S3 客户端后，S3 支持的多区域接入点操作的工作原理相同。唯一的区别是存储桶参数必须是多区域接入点的 ARN。您可以从 Amazon S3 控制台获取 ARN，也可以通过编程方式获取 ARN，如前面返回 ARN 的`createMrap`函数中所示。

以下代码示例显示了操作中使用的 ARN。`GetObject`

```
    suspend fun getObjectFromMrap(
        s3: S3Client,
        mrapArn: String,
        keyName: String,
    ): String? {
        val request = GetObjectRequest {
            bucket = mrapArn // Use the ARN instead of the bucket name for object operations.
            key = keyName
        }

        var stringObj: String? = null
        s3.getObject(request) { resp ->
            stringObj = resp.body?.decodeToString()
            if (stringObj != null) {
                println("Successfully read $keyName from $mrapArn")
            }
        }
        return stringObj
    }
```