前言
选择windows安装测试是有必要的,IBM MQ不同于其他MQ,其运行与创建队列管理器很复杂,在打算部署linux之前,建议先把windows下的可视化操作理清,不至于踩坑!
安装 IBM MQ
网络配置选否,后续可以省去很多麻烦。
创建队列管理器报错:AMQ7252 :MQ服务必须正在运行,就是因为这个原因
选择启动IBM MQ,进行安装
选择典型只能安装在C盘,选择定制可以自定义文件夹,自定义数据存储
下一页
选择否,完成安装
进入可视化页面(或点击MQ资源管理器)
创建连接信息
创建队列管理器
一直下一步,选择创建服务器连接通道
指定一个监听端口,我们代码连接mq时用的端口,完成创建
创建通道,必选服务器连接通道
通道属性这里要添加MCA,这个用户要是你当前系统登录的用户,且这个用户要属于mqm组,mqm组已经默认给创建好了,我们只需要把用户移到mqm组下即可,win10直接搜索计算机管理,将当前用户添加到mqm组下,注意,如果没有本地用户和组,那么可能你的计算机是win10家庭版,两种方式。1)升级到win10专业版 2)装一个win10的虚拟机(我是这样的)
如果用户不能移到mqm组,后续会报各种错误。
创建好通道后,创建一个可以放消息的队列,直接点完成创建
在进行测试之前,还要再改两个地方,不然会报安全认证不通过的错误
1)通道认证记录这里不让它组织*MQADMIN,随便改个用户即可
2)点击队列管理器,进入属性,选择禁用通道认证记录,这两个地方做完,可以避免报安全认证失败错误
常见错误
这里列出常见的错误原因码,在之前已经提到过的不再赘述
错误一 Caused by: org.springframework.jms.IllegalStateException: JMSWMQ0018: 连接至队列管理器“QM_007”失败,连接方式为“Client”,主机名为“192.168.8.8(1414)”。; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ 调用失败,完成代码为“2”(“MQCC_FAILED”),原因码为“2538”(“MQRC_HOST_NOT_AVAILABLE”)。
解决 没有启动端口侦听器,指定一个可以telnet连通到的端口
错误二 Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2539;AMQ9547: 远程通道的类型不适合于所请求的操作。 [3=C]
解决 需要给通道定义的类型是“服务器连接类型”
错误三 Caused by: nested exception is com.ibm.msg.client.jms.DetailedInvalidDestinationException: JMSWMQ2008: 打开 MQ 队列“MQ_send”失败。
JMS 尝试执行 MQOPEN,但 IBM MQ 报告了错误。
使用链接的异常来确定此错误的原因。 请检查是否正确定义了指定的队列和队列管理器。; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ 调用失败,完成代码为“2”(“MQCC_FAILED”),原因码为“2085”(“MQRC_UNKNOWN_OBJECT_NAME”)。
解决 没有在队列管理器里建队列
错误四
MQRC_NOT_AUTHORIZED错误,原因码为“2035”
解决给通道指定MCA用户标识
springboot客户端连接MQ代码
<!--ibm mq--><dependency><groupId>org.springframework</groupId><artifactId>spring-jms</artifactId></dependency><dependency><groupId>javax.jms</groupId><artifactId>javax.jms-api</artifactId><version>2.0.1</version></dependency><dependency><groupId>com.ibm.mq</groupId><artifactId>com.ibm.mq.allclient</artifactId><version>9.1.1.0</version></dependency>
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsOperations;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;/*** ibm mq 消息发送者*/
@Component
public class SendMessage {@AutowiredJmsOperations jmsOperations;@PostConstructpublic void send() {for (int i = 0; i <= 10; i++) {jmsOperations.convertAndSend("QU", i + "my message...");}System.out.println("开始发送消息");}
}
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.connection.JmsTransactionManager;
import org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter;
import org.springframework.jms.core.JmsOperations;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.transaction.PlatformTransactionManager;import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.msg.client.wmq.WMQConstants;@Configuration
public class JmsConfig {/*** 注入连接参数:* 建立JmsConfig类,添加注解@Configuration,并将以上属性注入到此类*/@Value("${project.mq.host}")private String host;@Value("${project.mq.port}")private Integer port;@Value("${project.mq.queue-manager}")private String queueManager;@Value("${project.mq.channel}")private String channel;@Value("${project.mq.username}")private String username;@Value("${project.mq.password}")private String password;@Value("${project.mq.receive-timeout}")private long receiveTimeout;/*** 配置连接工厂:* CCSID要与连接到的队列管理器一致,Windows下默认为1381,* Linux下默认为1208。1208表示UTF-8字符集,建议把队列管理器的CCSID改为1208* @return*/@Beanpublic MQQueueConnectionFactory mqQueueConnectionFactory() {MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();mqQueueConnectionFactory.setHostName(host);try {mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);mqQueueConnectionFactory.setCCSID(1381);mqQueueConnectionFactory.setChannel(channel);mqQueueConnectionFactory.setPort(port);mqQueueConnectionFactory.setQueueManager(queueManager);} catch (Exception e) {e.printStackTrace();}return mqQueueConnectionFactory;}/*** 配置连接认证:* 如不需要账户密码链接可以跳过此步,直接将mqQueueConnectionFactory注入下一步的缓存连接工厂。* @param mqQueueConnectionFactory* @return*/@BeanUserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter(MQQueueConnectionFactory mqQueueConnectionFactory) {UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter = new UserCredentialsConnectionFactoryAdapter();userCredentialsConnectionFactoryAdapter.setUsername(username);userCredentialsConnectionFactoryAdapter.setPassword(password);userCredentialsConnectionFactoryAdapter.setTargetConnectionFactory(mqQueueConnectionFactory);return userCredentialsConnectionFactoryAdapter;}/*** 配置缓存连接工厂:* 不配置该类则每次与MQ交互都需要重新创建连接,大幅降低速度。*/@Bean@Primarypublic CachingConnectionFactory cachingConnectionFactory(UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter) {CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();cachingConnectionFactory.setTargetConnectionFactory(userCredentialsConnectionFactoryAdapter);cachingConnectionFactory.setSessionCacheSize(500);cachingConnectionFactory.setReconnectOnException(true);return cachingConnectionFactory;}/*** 配置事务管理器:* 不使用事务可以跳过该步骤。* 如需使用事务,可添加注解@EnableTransactionManagement到程序入口类中,事务的具体用法可参考Spring Trasaction。* @param cachingConnectionFactory* @return*/@Beanpublic PlatformTransactionManager jmsTransactionManager(CachingConnectionFactory cachingConnectionFactory) {JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();jmsTransactionManager.setConnectionFactory(cachingConnectionFactory);return jmsTransactionManager;}/*** 配置JMS模板:* JmsOperations为JmsTemplate的实现接口。* 重要:不设置setReceiveTimeout时,当队列为空,从队列中取出消息的方法将会一直挂起直到队列内有消息* @param cachingConnectionFactory* @return*/@Beanpublic JmsOperations jmsOperations(CachingConnectionFactory cachingConnectionFactory) {JmsTemplate jmsTemplate = new JmsTemplate(cachingConnectionFactory);jmsTemplate.setReceiveTimeout(receiveTimeout);return jmsTemplate;}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsOperations;
import org.springframework.jms.listener.adapter.MessageListenerAdapter;
import org.springframework.stereotype.Component;import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.TextMessage;/*** ibm mq 消息接受者*/
@Component
public class ReceiveMessage extends MessageListenerAdapter {@AutowiredJmsOperations jmsOperations;@Override@JmsListener(destination = "QU") //队列public void onMessage(Message message) {//必须转换如果不转换直接message.tostring消息的传输有限制。TextMessage textMessage= (TextMessage) message; //转换成文本消息try {System.out.println("MQ_send传来的值为:" +textMessage.getText());} catch (JMSException e) {e.printStackTrace();}}}
yml配置信息
#ibm mq 配置信息
project:mq:host: 172.16.70.49port: 1416#(队列管理器名称)queue-manager: MQ_TEST#(通道名称)channel: MQ_TD#创建的MQ用户username: liang#创建的MQ用户连接密码password: liang#连接超时receive-timeout: 20000
测试连接mq发送接收消息,搞定!
其他
推荐博文linux指令安装、部署、创建队列管理器
https://www.cnblogs.com/dahaoran/p/10836726.html