

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

# Neptune 公有端点
<a name="neptune-public-endpoints"></a>

## 概述
<a name="neptune-public-endpoints-overview"></a>

Amazon Neptune 集群通常部署在 VPC 内，并且只能从该 VPC 内对其进行访问。这需要在 VPC 内配置应用程序和开发环境，或者使用代理服务连接到该 VPC，但这会增加设置时间和成本。

公有端点允许通过互联网直接连接到 Neptune，从而简化这种体验，让您无需具备专业联网知识即可更轻松地开始使用图形数据库。

## 何时使用公有端点
<a name="neptune-public-endpoints-when-to-use"></a>

在以下场景中，可以考虑使用公有端点：
+ 您希望在开发或测试环境中快速测试 Neptune 而无需复杂的网络配置
+ 你没有专业的 Amazon 网络知识
+ 应用程序的安全状况不需要私有 VPC
+ 您需要从本地开发环境连接到 Neptune

## 安全注意事项
<a name="neptune-public-endpoints-security"></a>

使用公有端点时，请记住以下安全注意事项：
+ 启用公有端点的集群需要 IAM 身份验证。
+ 对数据库的访问由它使用的安全组控制。
+ 您可以限制哪些 IP 地址能够连接到集群。
+ 您可以使用 IAM 策略来控制谁能创建或修改具有公共访问权限的集群。请参阅：[限制公共访问权限的创建](#neptune-public-endpoints-restrict-access)

## 启用公有端点
<a name="neptune-public-endpoints-enabling"></a>

默认情况下，新的 Neptune 数据库是在禁用公有端点的情况下创建的。创建或修改集群时，您必须显式启用公共访问权限。

Neptune 引擎发行版本 1.4.6.x 支持公有端点。您需要将现有集群至少升级到此版本才能使用此功能。

公有端点设置在 Neptune 实例而不是 Neptune 集群上可用。因此，Neptune 集群可能存在一些带有公有端点的实例，以及一些没有公有端点的实例。但是，我们不建议使用这种设置。有关这方面的更多信息，请参阅：[公有端点的工作原理](#neptune-public-endpoints-how-they-work)

## 先决条件
<a name="neptune-public-endpoints-prerequisites"></a>

### Neptune 集群上的 IAM 身份验证设置
<a name="neptune-public-endpoints-iam-auth"></a>

在 Neptune 实例上启用公有端点之前，请确保集群支持 IAM 身份验证。如果不支持，请使用以下命令启用该功能：

```
aws neptune modify-db-cluster \
  --region us-west-2 \
  --engine graphdb \
  --engine-version 1.4.6.x \
  --db-cluster-identifier neptune-public-endpoint \
  --enable-iam-database-authentication
```

### 网络设置
<a name="neptune-public-endpoints-network-settings"></a>

1. 确保 VPC 具有启用公有路由（公有路由在子网的路由表中包含互联网网关的条目）的子网。如果您在创建集群时未提供 `db-subnet-group-name` 参数，则系统会选择默认子网组来创建集群。

1. 确保附加到集群的安全组允许以下入站流量：允许的 IP 范围和允许的端口的入站流量。例如，如果您要允许来自所有的 TCP 流量 IPs 连接到在端口 8182 上运行的 Neptune 实例，则入站规则应具有：

   1. 类型：所有 TCP

   1. 协议：TCP

   1. 端口范围：8182

   1. CIDR 数据块：0.0.0.0/0

**注意**  
虽然您可以将 CIDR 数据块范围设置为 0.0.0.0/0，但我们建议将其缩小到客户端应用程序的特定 IP 范围，以获得更好的安全状况。

## 创建带有公有端点的新实例
<a name="neptune-public-endpoints-creating-instance"></a>

您可以使用 Amazon 管理控制台、CL Amazon I 或 Amazon SDK 创建带有公共终端节点的新 Neptune 实例。

使用 C Amazon LI：

```
aws neptune create-db-instance \
  --region us-west-2 \
  --engine graphdb \
  --engine-version 1.4.6.x \
  --db-cluster-identifier neptune-public-endpoint \
  --publicly-accessible
```

## 修改现有实例以进行公共访问
<a name="neptune-public-endpoints-modifying-instance"></a>

要修改现有 Neptune 实例以启用公共访问，请执行以下操作：

```
aws neptune modify-db-instance \
  --region us-west-2 \
  --engine graphdb \
  --engine-version 1.4.6.x \
  --db-instance-identifier neptune-public-endpoint \
  --publicly-accessible
```

**注意**  
公共访问是在实例级别启用的，而不是在集群级别启用的。为确保集群始终可通过公有端点进行访问，集群中的所有实例都必须启用公共访问。

## 使用公有端点
<a name="neptune-public-endpoints-using"></a>

要检查您的数据库是否可以访问，请使用 Amazon CLI `NeptuneData` API 检查状态：

```
aws neptunedata get-engine-status \
  --endpoint-url https://my-cluster-name.cluster-abcdefgh1234.us-east-1.neptune.amazonaws.com:8182
```

如果数据库可访问，则响应如下所示：

```
{
    "status": "healthy",
    "startTime": "Sun Aug 10 06:54:15 UTC 2025",
    "dbEngineVersion": "1.4.6.0.R1",
    "role": "writer",
    "dfeQueryEngine": "viaQueryHint",
    "gremlin": {
        "version": "tinkerpop-3.7.1"
    },
    "sparql": {
        "version": "sparql-1.1"
    },
    "opencypher": {
        "version": "Neptune-9.0.20190305-1.0"
    },
    "labMode": {
        "ObjectIndex": "disabled",
        "ReadWriteConflictDetection": "enabled"
    },
    "features": {
        "SlowQueryLogs": "disabled",
        "InlineServerGeneratedEdgeId": "disabled",
        "ResultCache": {
            "status": "disabled"
        },
        "IAMAuthentication": "disabled",
        "Streams": "disabled",
        "AuditLog": "disabled"
    },
    "settings": {
        "StrictTimeoutValidation": "true",
        "clusterQueryTimeoutInMs": "120000",
        "SlowQueryLogsThreshold": "5000"
    }
}
```

## 如何查询数据库的示例
<a name="neptune-public-endpoints-examples"></a>

### Amazon CLI
<a name="neptune-public-endpoints-aws-cli"></a>

```
aws neptunedata execute-open-cypher-query \
--open-cypher-query "MATCH (n) RETURN n LIMIT 10" \
--endpoint-url https://my-cluster-name.cluster-abcdefgh1234.us-east-1.neptune.amazonaws.com:8182
```

### Python
<a name="neptune-public-endpoints-python"></a>

```
import boto3
import json
from botocore.config import Config

# Configuration - Replace with your actual Neptune cluster details
cluster_endpoint = "my-cluster-name.cluster-abcdefgh1234.my-region.neptune.amazonaws.com"
port = 8182
region = "my-region"

# Configure Neptune client
# This disables retries and sets the client timeout to infinite 
#     (relying on Neptune's query timeout)
endpoint_url = f"https://{cluster_endpoint}:{port}"
config = Config(
    region_name=region,
    retries={'max_attempts': 1},
    read_timeout=None
)

client = boto3.client("neptunedata", config=config, endpoint_url=endpoint_url)

cypher_query = "MATCH (n) RETURN n LIMIT 5"
try:
    response = client.execute_open_cypher_query(openCypherQuery=cypher_query)
    print("openCypher Results:")
    for item in response.get('results', []):
        print(f"  {item}")
except Exception as e:
    print(f"openCypher query failed: {e}")
```

### JavaScript
<a name="neptune-public-endpoints-javascript"></a>

```
import {
    NeptunedataClient,
    GetPropertygraphSummaryCommand
} from "@aws-sdk/client-neptunedata";
import { inspect } from "util";
import { NodeHttpHandler } from "@smithy/node-http-handler";

/**
 * Main execution function
 */
async function main() {
    // Configuration - Replace with your actual Neptune cluster details
    const clusterEndpoint = 'my-cluster-name.cluster-abcdefgh1234.my-region.neptune.amazonaws.com';
    const port = 8182;
    const region = 'my-region';

    // Configure Neptune client
    // This disables retries and sets the client timeout to infinite 
    //     (relying on Neptune's query timeout)
    const endpoint = `https://${clusterEndpoint}:${port}`;
    const clientConfig = {
        endpoint: endpoint,
        sslEnabled: true,
        region: region,
        maxAttempts: 1,  // do not retry
        requestHandler: new NodeHttpHandler({
            requestTimeout: 0  // no client timeout
        })
    };

    const client = new NeptunedataClient(clientConfig);
    try {
        try {
            const command = new GetPropertygraphSummaryCommand({ mode: "basic" });
            const response = await client.send(command);
            console.log("Graph Summary:", inspect(response.payload, { depth: null }));
        } catch (error) {
            console.log("Property graph summary failed:", error.message);
        }    
    } catch (error) {
        console.error("Error in main execution:", error);
    }
}

// Run the main function
main().catch(console.error);
```

### Go
<a name="neptune-public-endpoints-go"></a>

```
package main
import (
    "context"
    "fmt"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/neptunedata"
    "os"
    "encoding/json"
    "net/http"
)

func main() {    
    // Configuration - Replace with your actual Neptune cluster details
    clusterEndpoint := "my-cluster-name.cluster-abcdefgh1234.my-region.neptune.amazonaws.com"
    port := 8182
    region := "my-region"
    
    // Configure Neptune client
    // Configure HTTP client with no timeout
    //    (relying on Neptune's query timeout)
    endpoint := fmt.Sprintf("https://%s:%d", clusterEndpoint, port)
    // Load Amazon SDK configuration
    sdkConfig, _ := config.LoadDefaultConfig(
        context.TODO(),
        config.WithRegion(region),
        config.WithHTTPClient(&http.Client{Timeout: 0}),
    )
    
    // Create Neptune client with custom endpoint
    client := neptunedata.NewFromConfig(sdkConfig, func(o *neptunedata.Options) {
        o.BaseEndpoint = aws.String(endpoint)
        o.Retryer = aws.NopRetryer{} // Do not retry calls if they fail
    })

    gremlinQuery := "g.addV('person').property('name','charlie').property(id,'charlie-1')"
    serializer := "application/vnd.gremlin-v1.0+json;types=false"
    
    gremlinInput := &neptunedata.ExecuteGremlinQueryInput{
        GremlinQuery: &gremlinQuery,
        Serializer:   &serializer,
    }
    gremlinResult, err := client.ExecuteGremlinQuery(context.TODO(), gremlinInput)
    if err != nil {
        fmt.Printf("Gremlin query failed: %v\n", err)
    } else {
        var resultMap map[string]interface{}
        err = gremlinResult.Result.UnmarshalSmithyDocument(&resultMap)
        if err != nil {
            fmt.Printf("Error unmarshaling Gremlin result: %v\n", err)
        } else {
            resultJSON, _ := json.MarshalIndent(resultMap, "", "  ")
            fmt.Printf("Gremlin Result: %s\n", string(resultJSON))
        }
    }
}
```

## 公有端点的工作原理
<a name="neptune-public-endpoints-how-they-work"></a>

当 Neptune 实例可公开访问时：
+ 它的 DNS 端点会从数据库集群的 VPC 内解析为私有 IP 地址，
+ 从数据库集群的 VPC 外解析为公有 IP 地址。
+ 访问由分配给集群的安全组控制。
+ 只有可公开访问的实例才能通过互联网访问。

### 读取器端点行为
<a name="neptune-public-endpoints-reader-behavior"></a>
+ 如果所有读取器实例均可公开访问，则读取器端点将始终通过公共互联网进行解析。
+ 如果只有部分读取器实例可公开访问，则只有当读取器端点选择可公开访问的实例来提供读取查询时，它才会进行公开解析。

### 集群端点行为
<a name="neptune-public-endpoints-cluster-behavior"></a>
+ 数据库集群端点始终解析为写入器的实例端点。
+ 如果在写入器实例上启用公有端点，则集群端点将可公开访问，否则将不可公开访问。

### 集群失效转移后的行为
<a name="neptune-public-endpoints-failover-behavior"></a>
+ Neptune 集群可以将实例设置为不同的公共可访问设置。
+ 如果集群具有公共写入器和非公共读取器，则在集群失效转移后，新的写入器（之前的读取器）将变为非公共写入器，而新的读取器（之前的写入器）将变为公共读取器。

## 网络配置要求
<a name="neptune-public-endpoints-network-requirements"></a>

要使公有端点正常工作，需满足以下要求：

1. Neptune 实例必须位于 VPC 内的公有子网中。

1. 与这些子网关联的路由表必须具有通往互联网网关的路由 0.0.0.0/0。

1. 安全组必须允许从您想要授予访问权限的公有 IP 地址或 CIDR 范围进行访问。

## 限制公共访问权限的创建
<a name="neptune-public-endpoints-restrict-access"></a>

您可以使用 IAM 策略来限制谁能创建或修改具有公共访问权限的 Neptune 集群。以下示例策略拒绝创建具有公共访问权限的 Neptune 实例：

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Deny",
      "Action": [
        "rds:CreateDBInstance",
        "rds:ModifyDBInstance",
        "rds:RestoreDBInstanceFromDBSnapshot",
        "rds:RestoreDBInstanceToPointInTime"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {
          "rds:PubliclyAccessible": true
        }
      }
    }
  ]
}
```

------

有关 `rds:PublicAccessEnabled` IAM 条件键的更多信息：[Amazon RDS Service Authorization Reference](https://docs.amazonaws.cn//service-authorization/latest/reference/list_amazonrds.html#amazonrds-rds_PubliclyAccessible)

## Amazon CloudFormation 支持
<a name="neptune-public-endpoints-cloudformation"></a>

通过在模板中指定`PubliclyAccessible`参数 Amazon CloudFormation ，您可以使用启动启用了公共终端节点的 Neptune Amazon CloudFormation 集群。

## 与 Neptune 功能的兼容性
<a name="neptune-public-endpoints-compatibility"></a>

启用公有端点的集群支持仅 VPC 集群支持的所有 Neptune 功能，包括：
+ Neptune Workbench
+ 全文搜索集成
+ Neptune 流
+ 自定义端点
+ Neptune 无服务器
+ 图形浏览器

## 定价
<a name="neptune-public-endpoints-pricing"></a>

除了标准的 Neptune 定价之外，使用公有端点不会产生额外费用。但是，通过公有 IP 从本地环境连接到 Neptune 可能会增加数据传输费用。