我正在实现一个连接池(JDBC连接和SMPP连接)。我知道有几个经过良好测试的连接池。但我只想自己实现。我在多线程环境中使用它。这更是我个人的兴趣所在。我的实现是这样的。我创建一个ConcurrentLinkedQueue并将连接推送到队列。每次线程请求连接时,都会从队列中弹出连接。作业完成后,线程将连接推回到队列。我的连接轮询实现类如下所示。
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.log4j.Logger;
import org.jsmpp.bean.BindType;
import org.jsmpp.bean.NumberingPlanIndicator;
import org.jsmpp.bean.TypeOfNumber;
import org.jsmpp.session.BindParameter;
import org.jsmpp.session.SMPPSession;
public class SMPPConnectionPool {
static ConcurrentLinkedQueue<SMPPSession> connectionPool = null;
static Logger LOG = null;
static
{
LOG = LogManager.getLogger(SMPPConnectionPool.class);
connectionPool= new ConcurrentLinkedQueue<SMPPSession>();
}
/* This method returns session from queue .If no sessions exist in the queue,then a new session will be created and returned.
* This method use QueryGparams APi to read conenction related data from gparams
* */
public static SMPPSession getConenction()
{
SMPPSession session=connectionPool.poll();
if(session!=null)
{
System.out.println("Thread "+Thread.currentThread().getName() +" got "+session.getSessionId());
LOG.info("Thread "+Thread.currentThread().getName() +" got "+session.getSessionId());
return session;
}
else
{
SMPPSession smppSession = new SMPPSession();
try {
String host = QueryGparams.getGparamAsString(NotificationConstants.SMSC_HOST);
int port = QueryGparams.getGparamAsInteger(NotificationConstants.SMSC_PORT);
String systemId = QueryGparams.getGparamAsString(NotificationConstants.SMSC_SYSTEM_ID);
String password = QueryGparams.getGparamAsString(NotificationConstants.SMSC_PASSWORD);
if(host == null || systemId == null || password == null || port == 0)
{
String errorMessage = "Following parameters are null \n";
if(host == null) {
errorMessage = errorMessage + "host is null";
}
if(systemId == null) {
errorMessage = errorMessage + "systemId is null";
}
if(password == null) {
errorMessage = errorMessage + "password is null";
}
if(port == 0) { //TODO Need to change this if QueryGParams API will not return zero when port number is not specified
errorMessage = errorMessage + "port is null";
}
throw new Exception(errorMessage);
}
smppSession
.connectAndBind(host,port, new BindParameter(
BindType.BIND_TRX, systemId,
password, "",
TypeOfNumber.UNKNOWN,
NumberingPlanIndicator.UNKNOWN, null));
LOG.info("Session has been created.Session id is "+smppSession.getSessionId());
} catch (Exception e) {
LOG.error(CommonUtilities.getExceptionString(e));
}
System.out.println("Thread "+Thread.currentThread().getName() +" got "+smppSession.getSessionId());
LOG.info("Thread "+Thread.currentThread().getName() +" got "+smppSession.getSessionId());
return smppSession;
}
}
//This method pushes conenction back to queue ,to make it available for other threads.
public static void pushConenction(SMPPSession smppSession)
{
boolean isInserted=connectionPool.offer(smppSession);
if(isInserted)
{
LOG.info("Pushed the conenction back to queue");
System.out.println("Pushed the conenction back to queue");
}
else
{
LOG.info("Failed to push the session back to queue");
System.out.println("Failed to push the session back to queue");
}
}
public static void closeSessions()
{
while(connectionPool!=null && connectionPool.size()>0)
{
SMPPSession session=connectionPool.poll();
session.unbindAndClose();
LOG.info("Closed the session");
}
}
}
我只想知道这个实现有什么问题。请指教。我想为JDBC连接池的实现做同样的事情
我在实施过程中看到的一些问题如下:
> < li>
没有为connectAndBind配置超时。在网络分区或数据包丢失的情况下,getConnection调用很可能会停滞。
在网络中断的情况下,数据源和客户端之间的 TCP 连接可能会中断。因此,池所持有的连接将过时。似乎没有一种机制可以“刷新”连接。许多连接池框架都提供了测试连接,可以在后台执行,也可以在检查连接之前执行(这当然会增加整个 getConnection 调用的延迟)来应对这种情况。
1)boolean is inserted = connection pool . offer(smppSession);和后续分析没有意义,因为ConcurrentLinkedQueue是无界的,其offer()始终返回true。参见API
2)我会使用阻塞队列,并让线程等待活动线程返回对池的连接,如果达到最大活动threds
3)我会这样初始化静态字段
static ConcurrentLinkedQueue<SMPPSession> connectionPool = new ConcurrentLinkedQueue<SMPPSession>();
static Logger LOG = LogManager.getLogger(SMPPConnectionPool.class);
4)为了避免不必要的字符串连接,您可以使用这个成语
if (LOG.isInfoEnabled()) {
LOG.info("Thread "+Thread.currentThread().getName() +" got "+smppSession.getSessionId());
}
5) 这似乎是可疑的
} catch (Exception e) {
LOG.error(CommonUtilities.getExceptionString(e));
}
System.out.println("Thread "+Thread.currentThread().getName() +" got "+smppSession.getSessionId());
你抓住异常并继续,好像一切都好
我已经启动了zoo的管理员,Kafka服务器,Kafka生产者和Kafka消费者,我已经把jdbc sql连接器罐下载从合流,并把罐子的路径,我已经提到plugin.path连接独立properties.and我已经运行connect-standalone.bat……\config\connect-standalone.properties…\config\sink-quickstart-mysq
本文向大家介绍java连接Mongodb实现增删改查,包括了java连接Mongodb实现增删改查的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java连接Mongodb实现增删改查的具体代码,供大家参考,具体内容如下 1.创建maven项目 2.编写代码 1.查询所有 2.添加数据 3.删除 4.修改 5.条件查询 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多
本文向大家介绍Java实现JSP在Servelt中连接Oracle数据库的方法,包括了Java实现JSP在Servelt中连接Oracle数据库的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java实现JSP使用Servelt连接Oracle数据库的方法。为了实现在Servlet 中连接数据库,必须编写Servlet 的类程序。将Servlet 类程序放到WEB 服务器的servl
问题内容: 如何创建实现此接口的Clojure对象,然后从Java代码调用它? 问题答案: 是实现接口的首选- 重型,较旧且较慢,因此应尽可能避免。一个实现看起来像:
问题内容: 我正在尝试在我的项目中实现连接Mqtt Broker的目的(同时订阅和发布)。问题是,当我使用订阅功能(实现接口)时,我无法弄清楚如果连接断开,我该如何重新连接。MqttCallback接口具有connectionLost方法,但是对于调试导致连接丢失的调试很有用。我进行了搜索,但找不到建立自动重新连接的方法。您可以提出有关此问题的方法或文档吗? 问题答案: 最好的方法是构造连接逻辑,
我正在尝试使用Java over SSL连接到MySQL服务器。我得到以下异常: 这是我的代码: 我生成了keystore和truststore,如下所示: null