You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java通过代理连接带URL路径的MongoDB及连接超时问题排查

How to Connect to MongoDB with a URL Path via Proxy in Java

Let's break down why you're hitting that timeout and walk through the fixes step by step:

First, Fix Your Connection String

The immediate red flag in your error is the address server.com/mongo:80 — your MongoDB driver is treating server.com/mongo as a single hostname, which doesn't exist. That's almost certainly because you formatted your connection string incorrectly.

Wrong: mongodb://server.com/mongo:80/dbName
Right: mongodb://server.com:80/dbName

But this alone won't solve the problem, since your proxy expects the /mongo path prefix. Let's tackle that next.

If you have control over the proxy (like Nginx), the simplest fix is to set up a TCP forward instead of using a path-based HTTP proxy. MongoDB uses a binary protocol, which doesn't play nicely with HTTP path prefixes by default.

For Nginx, use the stream module instead of http to forward traffic directly from port 80 to your MongoDB instance:

stream {
    server {
        listen 80;
        proxy_pass localhost:27017; # Replace with your internal MongoDB address:port
    }
}

With this setup, your corrected connection string (mongodb://server.com:80/dbName) will work immediately, no extra driver configuration needed.

Option 2: Customize the Java Driver to Handle the Path Prefix

If you can't modify the proxy (e.g., strict environment restrictions), you'll need to add custom logic to your driver to send the /mongo path before initiating the MongoDB binary protocol. This assumes your proxy accepts an HTTP request first, then switches to forwarding TCP traffic for MongoDB.

Step 1: Create a Custom Socket Stream Factory

This factory will establish the socket connection, send the required path prefix via HTTP, then hand off to the MongoDB driver:

import com.mongodb.connection.SocketStreamFactory;
import com.mongodb.connection.SocketSettings;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class PathPrefixedStreamFactory extends SocketStreamFactory {
    private final String pathPrefix;

    public PathPrefixedStreamFactory(SocketSettings settings, String pathPrefix) {
        super(settings);
        this.pathPrefix = pathPrefix;
    }

    @Override
    protected Socket createSocket() throws IOException {
        Socket socket = super.createSocket();
        
        // Send HTTP request with the path prefix (adjust based on your proxy's requirements)
        OutputStream out = socket.getOutputStream();
        String httpRequest = String.format("GET %s HTTP/1.1\r\nHost: server.com\r\n\r\n", pathPrefix);
        out.write(httpRequest.getBytes());
        out.flush();
        
        // Optional: Read the proxy's HTTP response to confirm connection (adjust as needed)
        // InputStream in = socket.getInputStream();
        // // Read response headers here to ensure proxy accepts the request
        
        return socket;
    }
}

Step 2: Configure MongoClient with the Custom Factory

Use this factory when building your MongoClient to inject the path handling logic:

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClients;
import com.mongodb.connection.SocketSettings;

public class MongoProxyConnection {
    public static void main(String[] args) {
        SocketSettings socketSettings = SocketSettings.builder()
                .connectTimeout(30000)
                .build();

        // Initialize our custom factory with the /mongo path
        PathPrefixedStreamFactory streamFactory = new PathPrefixedStreamFactory(socketSettings, "/mongo");

        MongoClientSettings clientSettings = MongoClientSettings.builder()
                .applyConnectionString(new ConnectionString("mongodb://server.com:80/dbName"))
                .applyToSocketSettings(builder -> builder.applySettings(socketSettings))
                .streamFactoryFactory((socketSettings1, sslSettings) -> streamFactory)
                .build();

        // Test the connection
        try (var mongoClient = MongoClients.create(clientSettings)) {
            var db = mongoClient.getDatabase("dbName");
            db.listCollectionNames().first(); // Trigger a connection
            System.out.println("Successfully connected to MongoDB via proxy!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Important Notes for Option 2

  • This relies on your proxy supporting the HTTP-to-TCP switch. If your proxy only handles HTTP requests, this won't work (MongoDB's binary protocol isn't compatible with HTTP).
  • Double-check that your environment allows outbound connections to server.com:80 — even if no ports are open inbound, outbound traffic to port 80 is usually permitted.

内容的提问来源于stack exchange,提问作者Kévin Darty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:36:22