我是Java的新手,但对于一般编程并不陌生。
场景是我一次最多可以有n个连接,而打开和关闭连接的成本非常高。
我想重复使用相同的n个连接,并希望在Collection中保留一些内容。
当请求到来时,我会选择连接,完成工作并返回连接而不关闭。当下一个请求到来时,我会选择下一个可用的连接。
当所有连接都被使用并且请求到来时,我只是等待连接可用。
什么是最干净的Java解决方案。我不需要代码,我只需要一些想法来探索。可能是某些框架已经做到了,可能是某些java类已经提供了那个功能。
非常感谢任何想法。
答案 0 :(得分:0)
我建议你选择连接池。在这种情况下,如果您将Connection用于多个任务,请将它们分别写入池中。 在需要时从池中获取连接。然后在完成后将其推回池中。通过这种方式,Connection将是线程安全的,并且可以避免不一致。 此外,打开和关闭连接将导致资源紧缩。
答案 1 :(得分:0)
使用HTTP Core NIO或Netty等框架来执行此操作。对于HTTPCore NIO的示例实例,您可以创建一个工作线程组以连接到后端,如下所示。
ProxyConnPool connPool = createConnectionPool(connectingIOReactor);
connPool.setMaxTotal(100);
connPool.setDefaultMaxPerRoute(20);
private static ProxyConnPool createConnectionPool(final ConnectingIOReactor connectingIOReactor)
throws KeyManagementException,
KeyStoreException,
NoSuchAlgorithmException,
CertificateException,
FileNotFoundException,
IOException {
ProxyConnPool proxyConnPool = null;
if (SECURE_BACKEND) {
clientSSLContext =
SSLUtil.createClientSSLContext(TRUST_STORE_LOCATION,
TRUST_STORE_PASSWORD);
BasicNIOConnFactory connectionFactory =
new BasicNIOConnFactory(
clientSSLContext,
null,
ConnectionConfig.DEFAULT);
proxyConnPool = new ProxyConnPool(connectingIOReactor, connectionFactory, 5000);
} else {
proxyConnPool = new ProxyConnPool(connectingIOReactor, ConnectionConfig.DEFAULT);
}
return proxyConnPool;
}
您可以找到HTTP core NIO reverse proxy和Netty reverse Proxy
的示例代码在Netty中,代码与此类似。
// Configure the bootstrap.
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
希望这会有所帮助。快乐的编码!
答案 2 :(得分:0)
当请求到来时,我会选择连接,完成工作并返回连接而不关闭。当下一个请求到来时,我会选择下一个可用的连接。
我会使用一个由所有线程共享的简单BlockingQueue<Connection>
。
final BlockingQueue<Connection> connectionQueue = new LinkedBlockingQueue<Connection>();
在应用程序启动时,您将打开一堆Connection
个对象并将它们添加到队列中。
for (int i = 0; i < NUM_CONNECTIONS_TO_START; i++) {
queue.put(new Connection());
}
当线程获得连接时,它将从队列中获得Connection
,如果没有立即可用,则等待一个。{1}}。在使用Connection
之后,它会将其返回到队列以供下一个线程使用。
// this will wait if there are no connections available
Connection connection = queue.take();
try {
useTheConnection(connection);
} finally {
// after we are done add it back to the queue
queue.put(connection);
}
所有这一切的棘手部分是当你在套接字上得到某种网络异常时。您的线程需要正确关闭Connection
,然后将新的一个添加到队列中。也许是这样的:
// this will wait if there are no connections available
Connection connection = queue.take();
try {
useTheConnection(connection);
} catch (Exception e) {
// assume the connection is bad
try {
connection.close();
} catch (Exception e2) {
// ignore any exceptions here
}
// start a new fresh connection to add back to our queue
connection = new Connection();
} finally {
// after we are done add it back to the queue
queue.put(connection);
}
答案 3 :(得分:-1)
您可以使用具有固定线程数的Executor Service
ExecutorService service = Executors.newFixedThreadPool(n);
您可以创建一个类Connection,它将创建一个连接对象并将其返回
class Connection implements Callable<Connection> {
@Override
public Connection call() {
// Logic to get the connection
return new Connection();
}
}
然后提交任务并从池中获取Connection的Future对象。
Future<Connection> future = service.submit(new Connection());
Connection conn = future.get();