Ibm mq v9_客户端和v6_服务器之间的WMQ连接套接字持续关闭
我们有一个独立的java应用程序,使用第三方工具来管理连接池,它在v6_客户端+v6_服务器设置中为我们工作了很长一段时间 现在,我们正在尝试从v6迁移到v9(是的,我们来晚了……),发现v9_客户端到v6_服务器的连接不断中断,这意味着:Ibm mq v9_客户端和v6_服务器之间的WMQ连接套接字持续关闭,ibm-mq,Ibm Mq,我们有一个独立的java应用程序,使用第三方工具来管理连接池,它在v6_客户端+v6_服务器设置中为我们工作了很长一段时间 现在,我们正在尝试从v6迁移到v9(是的,我们来晚了……),发现v9_客户端到v6_服务器的连接不断中断,这意味着: XAQueueConnectionFactory#createXAConnection()创建的套接字总是立即关闭,并且创建的XAConnection似乎没有意识到这一点 由于上面提到的套接字关闭,从XAConnection.createXASession
- XAQueueConnectionFactory#createXAConnection()创建的套接字总是立即关闭,并且创建的XAConnection似乎没有意识到这一点李>
- 由于上面提到的套接字关闭,从XAConnection.createXASession()创建的XASession始终会创建一个新套接字,并在XASession.close()之后关闭套接字
- 考虑到v6_服务器端没有SHARECNV属性,我们尝试了setShareVallowed(WMQConstants.WMQ_SHARE_CONV_ALLOWED_uu[YES/NO]),这并不奇怪
- 我们通过setProviderVersion(“[6/7/8”)([7/8]抛出异常,正如预期的那样…)尝试了“迁移/限制/正常模式”
其他详细信息/更新
[更新-1] --[播放区设置] v9_客户端JAR:
javax.jms-api-2.0.jar
com.ibm.mq.allclient(-9.0.0.[1/5]).jar
v6_客户端JAR:
此外在v9_客户端JAR中,在eclipse类路径中引入了以下JAR
com.ibm.dhbcore-1.0.jar
com.ibm.mq.pcf-6.0.3.jar
com.ibm.mqjms-6.0.2.2.jar
com.ibm.mq-6.0.2.2.jar
com.ibm.mqetclient-6.0.2.2.jar
connector.jar
jta-1.1.jar
测试代码-单线程:
import javax.jms.*;
import com.ibm.mq.jms.*;
import com.ibm.msg.client.wmq.WMQConstants;
public class MQSeries_simpleAuditQ {
private static String queueManager = "QM.RCTQ.ALL.01";
private static String host = "localhost";
private static int port = 26005;
public static void main(String[] args) throws JMSException {
MQXAQueueConnectionFactory queueFactory= new MQXAQueueConnectionFactory();
System.out.println("\n\n\n*******************\nqueueFactory implementation version: " +
queueFactory.getClass().getPackage().getImplementationVersion() + "*****************\n\n\n");
queueFactory.setHostName(host);
queueFactory.setPort(port);
queueFactory.setQueueManager(queueManager);
queueFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
if (queueFactory.getClass().getPackage().getImplementationVersion().split("\\.")[0].equals("9")) {
queueFactory.setProviderVersion("6");
//queueFactory.setShareConvAllowed(WMQConstants.WMQ_SHARE_CONV_ALLOWED_YES);
}
XASession xaSession;
javax.jms.QueueConnection xaQueueConnection;
try {
// Obtain a QueueConnection
System.out.println("Creating Connection...");
xaQueueConnection = (QueueConnection)queueFactory.createXAConnection(" ", "");
xaQueueConnection.start();
for (int counter=0; counter<2; counter++) {
try {
xaSession = ((XAConnection)xaQueueConnection).createXASession();
xaSession.close();
} catch (Exception ex) {
System.out.println(ex);
}
}
System.out.println("Closing connection.... ");
xaQueueConnection.close();
} catch (Exception e) {
System.out.println("Error processing " + e.getMessage());
}
}
}
[更新-4] 我尝试将MCAUSER()设置为
mqm
,然后从客户端同时使用
(空白)和mqm
,两者都可以创建连接,但仍然看到使用v9_client+v6_user关闭相同的意外套接字。更新MCAUSER()后,我始终添加了刷新安全性
,并重新启动qmgr
在使用blank user创建连接之前,我还尝试在eclipse中将系统变量设置为blank,但也没有帮助
[更新-5] 将我们的讨论局限于v9_客户端+v9_服务器。下面的异步测试代码使用有限数量的现有连接生成大量xasession创建/关闭请求。使用SHARECNV(1)我们也将导致无法承受的高时间等待计数,但使用大于1的SHARECNV(如10)可能会带来额外的性能损失 异步测试代码
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import javax.jms.*;
import com.ibm.mq.jms.*;
import com.ibm.msg.client.wmq.WMQConstants;
public class MQSeries_simpleAuditQ_Async_v9 {
private static String queueManager = "QM.ALPQ.ALL.01";
private static int port = 26010;
private static String host = "localhost";
private static int connCount = 20;
private static int amp = 100;
private static ExecutorService amplifier = Executors.newFixedThreadPool(amp);
public static void main(String[] args) throws JMSException {
MQXAQueueConnectionFactory queueFactory= new MQXAQueueConnectionFactory();
System.out.println("\n\n\n*******************\nqueueFactory implementation version: " +
queueFactory.getClass().getPackage().getImplementationVersion() + "*****************\n\n\n");
queueFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
if (queueFactory.getClass().getPackage().getImplementationVersion().split("\\.")[0].equals("9")) {
queueFactory.setProviderVersion("9");
queueFactory.setShareConvAllowed(WMQConstants.WMQ_SHARE_CONV_ALLOWED_YES);
}
queueFactory.setHostName(host);
queueFactory.setPort(port);
queueFactory.setQueueManager(queueManager);
//queueFactory.setChannel("");
ArrayList<QueueConnection> xaQueueConnections = new ArrayList<QueueConnection>();
try {
// Obtain a QueueConnection
System.out.println("Creating Connection...");
//System.setProperty("user.name", "mqm");
//System.out.println("system username: " + System.getProperty("user.name"));
for (int ct=0; ct<connCount; ct++) {
// xaQueueConnection instance of MQXAQueueConnection
QueueConnection xaQueueConnection = (QueueConnection)queueFactory.createXAConnection(" ", "");
xaQueueConnection.start();
xaQueueConnections.add(xaQueueConnection);
}
ArrayList<Double> totalElapsedTimeRecord = new ArrayList<Double>();
ArrayList<FutureTask<Double>> taskBuffer = new ArrayList<FutureTask<Double>>();
for (int loop=0; loop <= 10; loop++) {
try {
for (int i=0; i<amp; i++) {
int idx = (int)(Math.random()*((connCount)));
System.out.println("Using connection: " + idx);
FutureTask<Double> xaSessionPoker = new FutureTask<Double>(new XASessionPoker(xaQueueConnections.get(idx)));
amplifier.submit(xaSessionPoker);
taskBuffer.add(xaSessionPoker);
}
System.out.println("loop " + loop + " completed");
} catch (Exception ex) {
System.out.println(ex);
}
}
for (FutureTask<Double> xaSessionPoker : taskBuffer) {
totalElapsedTimeRecord.add(xaSessionPoker.get());
}
System.out.println("Average xaSession poking time: " + calcAverage(totalElapsedTimeRecord));
System.out.println("Closing connections.... ");
for (QueueConnection xaQueueConnection : xaQueueConnections) {
xaQueueConnection.close();
}
} catch (Exception e) {
System.out.println("Error processing " + e.getMessage());
}
amplifier.shutdown();
}
private static double calcAverage(ArrayList<Double> myArr) {
double sum = 0;
for (Double val : myArr) {
sum += val;
}
return sum/myArr.size();
}
// create and close session through QueueConnection object passed in.
private static class XASessionPoker implements Callable<Double> {
// conn instance of MQXAQueueConnection. ref. QueueProviderService
private QueueConnection conn;
XASessionPoker(QueueConnection conn) {
this.conn = conn;
}
@Override
public Double call() throws Exception {
XASession xaSession;
double elapsed = 0;
try {
final long start = System.currentTimeMillis();
// ref. DualSessionWrapper
// xaSession instance of MQXAQueueSession
xaSession = ((XAConnection) conn).createXASession();
xaSession.close();
final long end = System.currentTimeMillis();
elapsed = (end - start) / 1000.0;
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println(e);
}
return elapsed;
}
}
}
import java.util.ArrayList;
导入java.util.concurrent.Callable;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.FutureTask;
导入javax.jms.*;
导入com.ibm.mq.jms.*;
导入com.ibm.msg.client.wmq.WMQConstants;
公共类MQSeries\u simpleAuditQ\u Async\u v9{
私有静态字符串queueManager=“QM.ALPQ.ALL.01”;
专用静态int端口=26010;
私有静态字符串host=“localhost”;
私有静态int connCount=20;
专用静态输入amp=100;
专用静态Executor服务放大器=Executors.newFixedThreadPool(amp);
公共静态void main(字符串[]args)引发JMSException{
MQXAQueueConnectionFactory queueFactory=新MQXAQueueConnectionFactory();
System.out.println(“\n\n\n******************\n查询属性实现版本:”+
queueFactory.getClass().getPackage().getImplementationVersion()+“*********************\n\n”);
setTransportType(WMQConstants.WMQ\u CM\u客户端);
if(queueFactory.getClass().getPackage().getImplementationVersion().split(“\\”)[0]。等于(“9”)){
queueFactory.setProviderVersion(“9”);
queueFactory.SetShareVallowed(WMQConstants.WMQ\u SHARE\u CONV\u ALLOWED\u YES);
}
setHostName(主机);
queueFactory.setPort(端口);
setQueueManager(queueManager);
//queueFactory.setChannel(“”);
ArrayList xaQueueConnections=新建ArrayList();
试一试{
//获取队列连接
System.out.println(“创建连接…”);
//System.setProperty(“user.name”、“mqm”);
//System.out.println(“系统用户名:”+System.getProperty(“用户名”);
对于(int-ct=0;ct我们发现根本原因是,不再使用会话池
+bitronix TM不提供跨TX的会话池
。具体来说(在我们的例子中),bitronix管理JmsPooledConnection
池,但每次使用(xa)会话时(在JmsPooledConnection
下),将创建一个新套接字(createXASession()
)并关闭(xaSession.close()
)
一种解决方案是用(xa)会话
池包装jms连接
,类似于在
还建议SpringCachingConnectionFactory
运行良好,这听起来像是第一个解决方案的一个特例。评论不用于扩展讨论;本次对话一直是。作为本次讨论的受益者,我非常感谢您的热情、知识和帮助,这肯定会促进我对这一点的理解mq产品作为一个新手用户。同时,我将尝试分享我在mq服务器端使用的示例脚本,以防它有助于全面描述我们遇到的问题。我知道v6是一个非常旧的版本,不再受支持,因此非常感谢您的支持!请不要让它让您的日常工作分心太多,因为我的目的是试图更好地理解我们遇到的问题。我们的目标是使用v9 cli+svr。我承认#1和#2超出了我的知识范围,但您所支持的
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import javax.jms.*;
import com.ibm.mq.jms.*;
import com.ibm.msg.client.wmq.WMQConstants;
public class MQSeries_simpleAuditQ_Async_v9 {
private static String queueManager = "QM.ALPQ.ALL.01";
private static int port = 26010;
private static String host = "localhost";
private static int connCount = 20;
private static int amp = 100;
private static ExecutorService amplifier = Executors.newFixedThreadPool(amp);
public static void main(String[] args) throws JMSException {
MQXAQueueConnectionFactory queueFactory= new MQXAQueueConnectionFactory();
System.out.println("\n\n\n*******************\nqueueFactory implementation version: " +
queueFactory.getClass().getPackage().getImplementationVersion() + "*****************\n\n\n");
queueFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
if (queueFactory.getClass().getPackage().getImplementationVersion().split("\\.")[0].equals("9")) {
queueFactory.setProviderVersion("9");
queueFactory.setShareConvAllowed(WMQConstants.WMQ_SHARE_CONV_ALLOWED_YES);
}
queueFactory.setHostName(host);
queueFactory.setPort(port);
queueFactory.setQueueManager(queueManager);
//queueFactory.setChannel("");
ArrayList<QueueConnection> xaQueueConnections = new ArrayList<QueueConnection>();
try {
// Obtain a QueueConnection
System.out.println("Creating Connection...");
//System.setProperty("user.name", "mqm");
//System.out.println("system username: " + System.getProperty("user.name"));
for (int ct=0; ct<connCount; ct++) {
// xaQueueConnection instance of MQXAQueueConnection
QueueConnection xaQueueConnection = (QueueConnection)queueFactory.createXAConnection(" ", "");
xaQueueConnection.start();
xaQueueConnections.add(xaQueueConnection);
}
ArrayList<Double> totalElapsedTimeRecord = new ArrayList<Double>();
ArrayList<FutureTask<Double>> taskBuffer = new ArrayList<FutureTask<Double>>();
for (int loop=0; loop <= 10; loop++) {
try {
for (int i=0; i<amp; i++) {
int idx = (int)(Math.random()*((connCount)));
System.out.println("Using connection: " + idx);
FutureTask<Double> xaSessionPoker = new FutureTask<Double>(new XASessionPoker(xaQueueConnections.get(idx)));
amplifier.submit(xaSessionPoker);
taskBuffer.add(xaSessionPoker);
}
System.out.println("loop " + loop + " completed");
} catch (Exception ex) {
System.out.println(ex);
}
}
for (FutureTask<Double> xaSessionPoker : taskBuffer) {
totalElapsedTimeRecord.add(xaSessionPoker.get());
}
System.out.println("Average xaSession poking time: " + calcAverage(totalElapsedTimeRecord));
System.out.println("Closing connections.... ");
for (QueueConnection xaQueueConnection : xaQueueConnections) {
xaQueueConnection.close();
}
} catch (Exception e) {
System.out.println("Error processing " + e.getMessage());
}
amplifier.shutdown();
}
private static double calcAverage(ArrayList<Double> myArr) {
double sum = 0;
for (Double val : myArr) {
sum += val;
}
return sum/myArr.size();
}
// create and close session through QueueConnection object passed in.
private static class XASessionPoker implements Callable<Double> {
// conn instance of MQXAQueueConnection. ref. QueueProviderService
private QueueConnection conn;
XASessionPoker(QueueConnection conn) {
this.conn = conn;
}
@Override
public Double call() throws Exception {
XASession xaSession;
double elapsed = 0;
try {
final long start = System.currentTimeMillis();
// ref. DualSessionWrapper
// xaSession instance of MQXAQueueSession
xaSession = ((XAConnection) conn).createXASession();
xaSession.close();
final long end = System.currentTimeMillis();
elapsed = (end - start) / 1000.0;
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println(e);
}
return elapsed;
}
}
}