是否可以使用 Java SDK 通过反向代理连接到 Azure Cosmos DB?
Is it possible to connect to Azure Cosmos DB via a reverse proxy using Java SDK?
我正在尝试使用 java sdk 连接到 cosmos。我在 AKS 中有一个 Nginx 代理 运行 指向我的 cosmos 实例(下面 nginx.conf 的子集):
server {
listen {{ .Values.cosmosDB.port }} so_keepalive=on;
proxy_connect_timeout 5s;
proxy_timeout 60m;
proxy_buffer_size 30M;
proxy_socket_keepalive on;
proxy_ssl_session_reuse on;
proxy_pass my-instance-cosmos-dev.documents.azure.com:443;
}
我的想法是,通过端口转发,我可以通过此代理将我的本地用作 cosmos 主机 url:
kubectl port-forward svc/data-proxy 3308:443
运行 java 的快速入门(通过 Azure 门户生成)我无法配置连接的 cosmos 客户端。我尝试了几种配置:
默认网关模式:
client = new CosmosClientBuilder()
.endpoint(AccountSettings.HOST)
.key(AccountSettings.MASTER_KEY)
.endpointDiscoveryEnabled(true)
.gatewayMode()
.userAgentSuffix("CosmosDBJavaQuickstart")
.consistencyLevel(ConsistencyLevel.EVENTUAL)
.buildClient();
但是 returns 启动时出错 Database Account localhost does not exist
:
CosmosException{userAgent=azsdk-java-cosmos/4.4.0 MacOSX/10.15.7 JRE/15.0.2,
error={"code":"Forbidden","message":"Database Account localhost does not exist\r\nActivityId: 742a632d-cd00-42b7-8599-8fc6ff1eccad, Microsoft.Azure.Documents.Common/2.14.0, StatusCode: Forbidden","additionalErrorInfo":null}, resourceAddress='null', requestUri='null', statusCode=403, message=Database Account localhost does not exist
然后我尝试按如下方式传递代理配置,但收到 SSL 验证错误:
ProxyOptions opts = new ProxyOptions(ProxyOptions.Type.HTTP, InetSocketAddress.createUnresolved("127.0.0.1", 3308));
gatewayConnectionConfig.setProxy(opts);
gatewayConnectionConfig.setMaxConnectionPoolSize(5);
// Create sync client
client = new CosmosClientBuilder()
.endpoint(AccountSettings.HOST)
.key(AccountSettings.MASTER_KEY)
.endpointDiscoveryEnabled(true)
.gatewayMode(gatewayConnectionConfig)
.userAgentSuffix("CosmosDBJavaQuickstart")
.consistencyLevel(ConsistencyLevel.EVENTUAL)
.buildClient();
输出:
INFO: Getting database account endpoint from http://localhost:3308
Oct 07, 2021 10:01:31 AM com.azure.cosmos.implementation.RxGatewayStoreModel
lambda$toDocumentServiceResponse
SEVERE: Network failure
javax.net.ssl.SSLException: failure when writing TLS control frames
at io.netty.handler.ssl.SslHandler.setHandshakeFailureTransportFailure(SslHandler.java:1863)
at io.netty.handler.ssl.SslHandler.access0(SslHandler.java:167)
at io.netty.handler.ssl.SslHandler.operationComplete(SslHandler.java:978)
at io.netty.handler.ssl.SslHandler.operationComplete(SslHandler.java:973)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:551)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
at io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:608)
at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:117)
at io.netty.channel.PendingWriteQueue.safeFail(PendingWriteQueue.java:279)
at io.netty.channel.PendingWriteQueue.removeAndFailAll(PendingWriteQueue.java:177)
at io.netty.handler.proxy.ProxyHandler.failPendingWrites(ProxyHandler.java:435)
at io.netty.handler.proxy.ProxyHandler.failPendingWritesAndClose(ProxyHandler.java:352)
at io.netty.handler.proxy.ProxyHandler.setConnectFailure(ProxyHandler.java:347)
at io.netty.handler.proxy.ProxyHandler.access0(ProxyHandler.java:39)
at io.netty.handler.proxy.ProxyHandler.run(ProxyHandler.java:199)
at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:170)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: io.netty.handler.proxy.ProxyConnectException: http, none, /127.0.0.1:3308 => localhost/<unresolved>:3308, timeout
... 10 more
我不确定如何进行。这是受支持的连接模式吗?也许我在这里通过 SDK 误解了客户端设置...
我认为代理方法应该可行,但您必须在 connection-String 中写入您在 AccountSettings.HOST
中使用的原始 Cosmos-DB-URL。
我猜那里仍然引用了“localhost”,因为您是第一次尝试直接访问。但是由于您现在正在通过代理,所以应该有真正的 URL。 (my-instance-cosmos-dev.documents.azure.com)
此外,您没有收到 SSL 验证错误,它看起来像是超时。 (因为代理试图连接到本地主机)
如果您确实想使用第一种(直接)方法,那么您可以在 /etc/hosts 中添加一个条目,这应该让 cosmos-db SDK 发送正确的 Host-header 在请求中。
127.0.0.1 my-instance-cosmos-dev.documents.azure.com
然后你还需要在connection-string中引用真正的URL,然后指向localhost。
我正在尝试使用 java sdk 连接到 cosmos。我在 AKS 中有一个 Nginx 代理 运行 指向我的 cosmos 实例(下面 nginx.conf 的子集):
server {
listen {{ .Values.cosmosDB.port }} so_keepalive=on;
proxy_connect_timeout 5s;
proxy_timeout 60m;
proxy_buffer_size 30M;
proxy_socket_keepalive on;
proxy_ssl_session_reuse on;
proxy_pass my-instance-cosmos-dev.documents.azure.com:443;
}
我的想法是,通过端口转发,我可以通过此代理将我的本地用作 cosmos 主机 url:
kubectl port-forward svc/data-proxy 3308:443
运行 java 的快速入门(通过 Azure 门户生成)我无法配置连接的 cosmos 客户端。我尝试了几种配置:
默认网关模式:
client = new CosmosClientBuilder()
.endpoint(AccountSettings.HOST)
.key(AccountSettings.MASTER_KEY)
.endpointDiscoveryEnabled(true)
.gatewayMode()
.userAgentSuffix("CosmosDBJavaQuickstart")
.consistencyLevel(ConsistencyLevel.EVENTUAL)
.buildClient();
但是 returns 启动时出错 Database Account localhost does not exist
:
CosmosException{userAgent=azsdk-java-cosmos/4.4.0 MacOSX/10.15.7 JRE/15.0.2,
error={"code":"Forbidden","message":"Database Account localhost does not exist\r\nActivityId: 742a632d-cd00-42b7-8599-8fc6ff1eccad, Microsoft.Azure.Documents.Common/2.14.0, StatusCode: Forbidden","additionalErrorInfo":null}, resourceAddress='null', requestUri='null', statusCode=403, message=Database Account localhost does not exist
然后我尝试按如下方式传递代理配置,但收到 SSL 验证错误:
ProxyOptions opts = new ProxyOptions(ProxyOptions.Type.HTTP, InetSocketAddress.createUnresolved("127.0.0.1", 3308));
gatewayConnectionConfig.setProxy(opts);
gatewayConnectionConfig.setMaxConnectionPoolSize(5);
// Create sync client
client = new CosmosClientBuilder()
.endpoint(AccountSettings.HOST)
.key(AccountSettings.MASTER_KEY)
.endpointDiscoveryEnabled(true)
.gatewayMode(gatewayConnectionConfig)
.userAgentSuffix("CosmosDBJavaQuickstart")
.consistencyLevel(ConsistencyLevel.EVENTUAL)
.buildClient();
输出:
INFO: Getting database account endpoint from http://localhost:3308
Oct 07, 2021 10:01:31 AM com.azure.cosmos.implementation.RxGatewayStoreModel
lambda$toDocumentServiceResponse
SEVERE: Network failure
javax.net.ssl.SSLException: failure when writing TLS control frames
at io.netty.handler.ssl.SslHandler.setHandshakeFailureTransportFailure(SslHandler.java:1863)
at io.netty.handler.ssl.SslHandler.access0(SslHandler.java:167)
at io.netty.handler.ssl.SslHandler.operationComplete(SslHandler.java:978)
at io.netty.handler.ssl.SslHandler.operationComplete(SslHandler.java:973)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:551)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
at io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:608)
at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:117)
at io.netty.channel.PendingWriteQueue.safeFail(PendingWriteQueue.java:279)
at io.netty.channel.PendingWriteQueue.removeAndFailAll(PendingWriteQueue.java:177)
at io.netty.handler.proxy.ProxyHandler.failPendingWrites(ProxyHandler.java:435)
at io.netty.handler.proxy.ProxyHandler.failPendingWritesAndClose(ProxyHandler.java:352)
at io.netty.handler.proxy.ProxyHandler.setConnectFailure(ProxyHandler.java:347)
at io.netty.handler.proxy.ProxyHandler.access0(ProxyHandler.java:39)
at io.netty.handler.proxy.ProxyHandler.run(ProxyHandler.java:199)
at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:170)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: io.netty.handler.proxy.ProxyConnectException: http, none, /127.0.0.1:3308 => localhost/<unresolved>:3308, timeout
... 10 more
我不确定如何进行。这是受支持的连接模式吗?也许我在这里通过 SDK 误解了客户端设置...
我认为代理方法应该可行,但您必须在 connection-String 中写入您在 AccountSettings.HOST
中使用的原始 Cosmos-DB-URL。
我猜那里仍然引用了“localhost”,因为您是第一次尝试直接访问。但是由于您现在正在通过代理,所以应该有真正的 URL。 (my-instance-cosmos-dev.documents.azure.com)
此外,您没有收到 SSL 验证错误,它看起来像是超时。 (因为代理试图连接到本地主机)
如果您确实想使用第一种(直接)方法,那么您可以在 /etc/hosts 中添加一个条目,这应该让 cosmos-db SDK 发送正确的 Host-header 在请求中。
127.0.0.1 my-instance-cosmos-dev.documents.azure.com
然后你还需要在connection-string中引用真正的URL,然后指向localhost。