是否可以使用 Java SDK 通过反向代理连接到 Azure Cosmos DB?
Posted
技术标签:
【中文标题】是否可以使用 Java SDK 通过反向代理连接到 Azure Cosmos DB?【英文标题】:Is it possible to connect to Azure Cosmos DB via a reverse proxy using Java SDK? 【发布时间】:2021-11-27 15:07:53 【问题描述】:我正在尝试使用 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();
但是这会在启动时返回错误Database Account localhost does not exist
:
CosmosExceptionuserAgent=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$2
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.access$600(SslHandler.java:167)
at io.netty.handler.ssl.SslHandler$2.operationComplete(SslHandler.java:978)
at io.netty.handler.ssl.SslHandler$2.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.access$100(ProxyHandler.java:39)
at io.netty.handler.proxy.ProxyHandler$2.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$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.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 误解了客户端设置...
【问题讨论】:
【参考方案1】:我认为代理方法应该可行,但您必须在连接字符串中写入原始 Cosmos-DB-URL,您在 AccountSettings.HOST
中使用。
我想那里仍然引用了“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
然后你还需要在连接字符串中引用真实的 URL,然后指向 localhost。
【讨论】:
以上是关于是否可以使用 Java SDK 通过反向代理连接到 Azure Cosmos DB?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用代理从 Cosmos SDK .Net 连接到 Azure Cosmos?