我使用 Netty 作为我的服务器和 JDBC for MySQL 的基础。我使用 BoneCP 来汇集我的 JDBC 连接。
在我的服务器中,唯一的 I/O 操作是 JDBC 连接。(以及用于将异常记录到文本文件的 PrintWriter)
我知道每个 JDBC 连接都使用单线程。但是,如果我使用 BoneCP 来汇集我的连接,它会在某种程度上模拟异步 I/O,直到所有连接都被填满。如果我错了,请纠正我。
所以我想知道每个给定周期有多少连接创建(或 JDBC 执行)会产生阻塞 I/O。有哪些方法可以测试我的服务器是否被阻止?
最佳答案
JDBC 是一种同步 API,这意味着调用线程会阻塞每个操作才能完成。鉴于一个操作可能需要很长时间(相对而言)才能完成,无论 JDBC 驱动程序使用阻塞还是非阻塞 I/O,从 Netty 的角度来看,它都应该被视为阻塞操作。使用连接池不会改变这一点 - 它只是减少了获取数据库连接的开销。
假设您执行一个选择操作,并且该操作需要 100 毫秒才能完成,因为它会返回大量数据。如果您在 Netty 的 I/O 工作线程上执行该操作,则该线程管理的所有 channel 都将停止,直到 JDBC 操作完成。
如何解决这个问题实际上取决于您的应用程序要求。例如
- 测试数据库是否可以足够快地响应,以便您可以在 I/O 工作线程中执行 Netty JDBC 操作而不影响客户端。这可能只适用于客户端连接很少的轻负载服务器。
- 根据您使用的 Netty 版本,您可以将不同的线程池和执行器模型添加到您的管道中,以从 I/O 线程卸载 JDBC 操作。
- 如果您使用的是足够新的 Netty 3(我认为是 3.6)或 Netty 4 版本,您可以将 JDBC 操作卸载到一个完全独立的线程池,然后在 Netty I/O 线程上引发自定义事件JDBC 操作完成以继续处理请求。
要考虑的另一点是,如果数据库相对较慢,并且您的服务器处于负载之下,则您需要为允许的连接数设置一个上限,或者您必须暂停读取Netty channel 给数据库一个追赶的机会
关于java - 如何检查 I/O 操作是阻塞的还是非阻塞的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20235555/