vb.net - Visual Basic Web API 使用 mq 系列消息传递,但从不释放连接
问题描述
我正在研究一个遗留系统,并负责修改使用 mq 系列(现在称为 IBM websphere)从大型机系统发送和接收数据的 Visual Basic API。我的网络管理员通知我,他看到来自 API 的 97 个连接。在队列管理器级别,最大通道设置为 100。他说这很好,但问题是 API 建立了客户端通道连接但从未释放它。我假设必须有一个 close() 操作,一旦我从队列中检索响应,我就可以执行该操作,但我不知道语法是什么。这是我执行以发送和接收数据的代码:
Dim passedmqRequest = mqRequest
Dim Session_mq_put_array As Object
Dim Session_mq_get_array As Object
Dim Session_MqResponse As String = ""
Dim Session_error_code As String = ""
Dim Session_plan_id As String = Mid(passedmqRequest, 15, 4)
Dim ipAddress As String = "xxx.xxx.xxx.xxx"
Dim mq_get_error As String = "N"
Dim mq_put_array(2) As String
Dim mq_get_array(2) As String
Dim Response_queue As String = ""
Dim Response_queue_mgt As String = ""
' send messages to TOSSMQT1
Response_queue = "ARI.GW1TEST.RESPONSES"
Response_queue_mgt = "ARIT"
mq_put_array(0) = "ARI.TEST.QUEUE"
Response_queue = "ARI.TEST.RESPONSES"
mq_put_array(1) = "VRU4300b"
mq_put_array(2) = "SVRCONN//" & ipAddress & "(1414)" '* internal
mq_put_array(2) = "SVRCONN//" & ipAddress & "(1414)" '* internal
Session_mq_put_array = mq_put_array
mq_get_array(0) = "ARI.TEST.HOST.RESPONSES"
mq_get_array(1) = "VRU4300b"
mq_get_array(2) = "SVRCONN//" & ipAddress & "(1414)" '* internal
mq_get_array(2) = "SVRCONN//" & ipAddress & "(1414)" '* internal
Session_mq_get_array = mq_get_array
Dim CmdArgs() As String
CmdArgs = Session_mq_put_array
Dim CmdResponse() As String
CmdResponse = Session_mq_get_array
Dim mqQMgr As MQQueueManager '* MQQueueManager instance
Dim mqQueue As MQQueue '* MQQueue instance
Dim responseQueue As MQQueue
Dim mqMsg As MQMessage '* MQMessage instance
Dim responseMSG As MQMessage
Dim mqPutMsgOpts As MQPutMessageOptions '* MQPutMessageOptions instance
Dim queueName As String '* Name of queue to use
Dim responsequeueName As String '* Name of response queue to use
Dim message As String '* Message buffer
Dim mqError As String = ""
queueName = CmdArgs.GetValue(0)
responsequeueName = CmdResponse(0)
'*
'* Try to create an MQQueueManager instance
'*
Dim channelDefinition As String = CmdArgs.GetValue(2)
Dim channelName As String = ""
Dim transportType As String = ""
Dim connectionName As String = ""
Dim separator As Char() = "/"
Dim parts As String()
Try
'* queue name, queue manager name, channel definition all provided
'* Break down the channel definition,
'* which is of the form "channel-name/transport-type/connection-name".
channelDefinition = CmdArgs.GetValue(2)
parts = channelDefinition.Split(separator)
If (parts.Length > 0) Then
channelName = parts(0)
End If
If (parts.Length > 1) Then
transportType = parts(1)
End If
If (parts.Length > 2) Then
connectionName = parts(2)
End If
mqQMgr = New MQQueueManager(CmdArgs.GetValue(1), channelName, connectionName)
Try
mqQueue = mqQMgr.AccessQueue(queueName, MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING) '* open queue for output but not if MQM stopping
message = passedmqRequest
'* put the next message to the queue
mqMsg = New MQMessage()
mqMsg.WriteString(message)
mqMsg.Format = MQC.MQFMT_STRING
mqPutMsgOpts = New MQPutMessageOptions()
mqMsg.ReplyToQueueName = Response_queue
mqMsg.ReplyToQueueManagerName = Response_queue_mgt
Try
mqQueue.Put(mqMsg, mqPutMsgOpts)
responseQueue = mqQMgr.AccessQueue(mq_get_array(0), MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING)
Dim MQGetMessageOptions As New MQGetMessageOptions()
MQGetMessageOptions.Options = IBM.WMQ.MQC.MQGMO_WAIT + IBM.WMQ.MQC.MQGMO_FAIL_IF_QUIESCING + IBM.WMQ.MQC.MQGMO_CONVERT
MQGetMessageOptions.WaitInterval = 20000
MQGetMessageOptions.MatchOptions = MQC.MQMO_MATCH_MSG_ID
responseMSG = New MQMessage
responseMSG.MessageId = mqMsg.MessageId
Try
responseQueue.Get(responseMSG, MQGetMessageOptions)
Session_MqResponse = responseMSG.ReadString(responseMSG.DataLength)
Session_error_code = "0"
'
' at this point a response has been received and I should close
' the client channel connection
'
Catch mqe As MQException
'* report the error
Session_MqResponse = "MQQueue::get ended with " & mqe.Message & "<br/>"
mq_get_error = "Y"
Session_error_code = "1"
End Try
Catch mqe As MQException
'* report the error
Session_MqResponse = "MQQueue::Put ended with " & mqe.Message & "<br/>"
Session_error_code = "2"
End Try
Catch mqe As MQException
'* stop if failed
Session_MqResponse = "MQQueueManager::AccessQueue ended with error message = " & mqe.Message & "<br/>"
Session_MqResponse = Session_MqResponse & "create of MQQueueManager ended with error reason = " & mqe.Reason & "<br/>"
Session_error_code = "3"
End Try
Catch mqe As MQException
'* stop if failed
Session_MqResponse = "create of MQQueueManager ended with error message = " & mqe.Message & "<br/>"
Session_MqResponse = Session_MqResponse & "create of MQQueueManager ended with error reason = " & mqe.Reason & "<br/>"
Session_error_code = "4"
End Try
解决方案
浏览您的代码:
mqQMgr = New MQQueueManager(...)
这将创建一个 MQQueueManager 对象,但也作为客户端连接连接到目标队列管理器 - 这将是网络管理员正在谈论的连接
mqQueue = mqQMgr.AccessQueue(queueName, MQC.MQOO_OUTPUT, ...)
这会在目标队列管理器上打开一个队列以进行输出
responseQueue = mqQMgr.AccessQueue(mq_get_array(0), MQC.MQOO_INPUT_SHARED, ...)
这会在目标队列管理器上打开一个队列以供输入。
此时,您在目标队列管理器上打开了 2 个队列和一个连接。如果您只是进入其他代码,那么您在服务器上持有资源。我的理解是,当对象超出范围时,它们会被销毁,但我可能对这种语言是错误的(不实践!)。
要显式释放资源,您只需关闭 qmgr 连接(因为它持有的任何队列都将被释放)并进行适当的错误检查:
mqQMgr.Disconnect()
如果您真的想显式清理队列然后清理队列管理器,您可以在断开连接之前执行以下操作(使用适当的错误检查):
mqQueue.Close()
responseQueue.Close()
推荐阅读
- mysql - MySQL select 语句没有按名称查找列,我错过了什么?
- python-3.x - 在一行上进行多个字符替换(在字符串中)
- c# - 在运行单元测试时将作为参数传递给注入接口时验证对 Func 的调用
- mysql - MySQL查询返回多行
- ios - Xcode 10.2.1 界面生成器 - 无法在视图控制器(或文档大纲)上移动(拖动)UI 元素
- android - 未来
- > 迭代图像列表时返回 null
- javascript - 从 Node API 到 PHP 服务器的 Axios 调用导致套接字挂断
- r - 将变量名作为参数传递给 data.table
- css - react-native 中的样式化组件大小和性能
- yaml - 创建时间戳 YAML 日志文件