Java编写Gremlin代码连接AWS Neptune报NoHostAvailable异常如何解决
AWS Neptune Java连接NoHostAvailableException解决方案
核心报错原因
keyStore参数仅支持JKS格式的密钥库文件,直接传入PEM证书会导致SSL上下文初始化失败,触发空指针和主机不可用异常。另外需确保安全组、网络访问、依赖版本配置正确。
前置检查项
- Neptune实例安全组入方向开放8182端口给代码运行机器的IP
- 若Neptune未开启公共访问,本地运行需先配置VPC SSH隧道,转发本地8182端口到Neptune端点的8182端口
- 依赖版本需与Neptune引擎支持的TinkerPop版本匹配,推荐使用3.5.x系列版本
可直接在IntelliJ运行的连接代码
无IAM认证的集群代码
import org.apache.tinkerpop.gremlin.driver.Cluster; import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal; public class NeptuneConnectTest { public static void main(String[] args) throws Exception { // 替换为你的Neptune端点,无需加https://前缀 String neptuneEndpoint = "xxx.cluster-xxx.us-east-2.neptune.amazonaws.com"; // 替换为生成的JKS密钥库路径 String jksPath = "src/main/resources/neptune.jks"; // 生成JKS时设置的密码 String jksPwd = "changeit"; Cluster cluster = Cluster.build() .addContactPoint(neptuneEndpoint) .port(8182) .enableSsl(true) .keyStore(jksPath) .keyStorePassword(jksPwd) .create(); GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster)); // 测试查询 System.out.println(g.V().limit(10).toList()); cluster.close(); } }
开启IAM认证的集群代码
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; import org.apache.tinkerpop.gremlin.driver.Cluster; import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; import software.amazon.neptune.driver.auth.NeptuneNettyHttpSigV4Signer; import software.amazon.neptune.driver.auth.NeptuneSigV4SignerException; import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal; public class NeptuneIamConnectTest { public static void main(String[] args) throws Exception { String neptuneEndpoint = "xxx.cluster-xxx.us-east-2.neptune.amazonaws.com"; String jksPath = "src/main/resources/neptune.jks"; String jksPwd = "changeit"; // 替换为Neptune所在区域 String region = "us-east-2"; Cluster cluster = Cluster.build(neptuneEndpoint) .port(8182) .enableSsl(true) .keyStore(jksPath) .keyStorePassword(jksPwd) .handshakeInterceptor(request -> { try { NeptuneNettyHttpSigV4Signer signer = new NeptuneNettyHttpSigV4Signer(region, new DefaultAWSCredentialsProviderChain()); signer.signRequest(request); } catch (NeptuneSigV4SignerException e) { throw new RuntimeException("请求签名失败", e); } return request; }) .create(); GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster)); System.out.println(g.V().limit(10).toList()); cluster.close(); } }
必要Maven依赖(pom.xml)
<dependencies> <dependency> <groupId>org.apache.tinkerpop</groupId> <artifactId>gremlin-driver</artifactId> <version>3.5.7</version> </dependency> <!-- IAM认证需额外引入以下依赖 --> <dependency> <groupId>software.amazon.neptune</groupId> <artifactId>amazon-neptune-sigv4-signer</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-core</artifactId> <version>1.12.500</version> </dependency> </dependencies>
remote-objects.yaml 配置内容
若使用配置文件方式初始化连接,配置内容如下:
hosts: [xxx.cluster-xxx.us-east-2.neptune.amazonaws.com] port: 8182 enableSsl: true keyStore: "src/main/resources/neptune.jks" keyStorePassword: "changeit" serializer: className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1 config: serializeResultToString: true connectionPool: maxSize: 8 minSize: 2
JKS密钥库生成步骤
Neptune使用亚马逊根证书,需将PEM证书转换为JKS格式:
- 下载亚马逊全局根证书
SFSRootCAG2.pem - 执行JDK自带keytool命令生成JKS文件:
keytool -importcert -alias neptune -file SFSRootCAG2.pem -keystore neptune.jks -storepass changeit
- 命令执行时输入
yes确认信任证书,将生成的neptune.jks文件放入项目resources目录即可
本地无VPC访问的临时方案
若本地无法直接访问Neptune所在VPC,可通过EC2配置SSH隧道转发端口:
ssh -i your-ec2-key.pem -L 8182:neptune-endpoint:8182 ec2-user@ec2-public-ip
此时代码中的连接端点改为localhost即可正常访问。
内容的提问来源于stack exchange,提问作者Harish
相关产品推荐
相关产品推荐

