RabbitMQ之动态删除exchange和queue

星期五 下午 15:22 狂奔的蜗牛 RabbitMQ 10888 views
4
Comments

了解rabbitmq的都知道,它的交换器exchange和队列queue,和消息message都是可以持久化,但是如果我们第一次申明了一个持久化的交换器,队列和消息,那么断开连接rabbitmq还是会被保留我们申明的交换器、队列和消息。但是当我们想要申明非持久化的同名交换器或者队列就会报错,告诉你不能使用不同的参数申明同一个名称的队列。网上很多解决方法都说要登录rabbitmq web管理界面里面手动删除那些交换器或者队列。这个方法固然可行,但是不够灵活。

经过研究,我们可以在申明之前,新建立一个connection然后获取一个channel,使用这个channel尝试去申明交换器或者队列,如果发生了io异常,那么就是说明交换器或者队列已经存在,而且申明的参数和现在不一样,我们只需要使用channelexchangeDelete和queueeDelete方法删除即可,然后关闭这个channel。接着我们正常使用我们的channel去申明即可,就不会再报错。这样就可以达到动态修改交换器和队列的持久化是我们的程序更加灵活满足不断变化的业务。

下面给出我写的申明exchange和queue的代码:

public static AMQP.Queue.DeclareOk declearQueue(Channel channel, String queueName) throws IOException, TimeoutException {
		//queueDeclare queue名字,是否持久化,独占的queue(仅供此连接),不使用时是否自动删除,其他参数
		Connection connection1 = Misc.connectionFactory().newConnection();
		Channel channel1 = connection1.createChannel();
		AMQP.Queue.DeclareOk declareOk;
		try {
			channel1.queueDeclare(queueName, durable(null, queueName), false, !durable(null, queueName), null);
		} catch (IOException e) {
			try {
				channel1.close();
			} catch (Exception ex) {
			}
			try {
				connection1.close();
			} catch (Exception ex) {
			}
			connection1 = Misc.connectionFactory().newConnection();
			channel1 = connection1.createChannel();
			channel1.queueDelete(queueName);
			try {
				channel1.close();
			} catch (Exception ex) {
			}
			try {
				connection1.close();
			} catch (Exception ex) {
			}
		} finally {
			try {
				channel1.close();
			} catch (Exception ex) {
			}
			try {
				connection1.close();
			} catch (Exception ex) {
			}
		}
		declareOk = channel.queueDeclare(queueName, durable(null, queueName), false, !durable(null, queueName), null);
		return declareOk;
	}
	
	public static AMQP.Exchange.DeclareOk declearExchange(Channel channel, String exchangeName, String exchangeMode) throws IOException, TimeoutException {
		//exchangeDeclare 交换机名字,类型,是否持久化,不使用时是否自动删除,是否是内部的(不能被客户端使用),其他参数
		Connection connection1 = Misc.connectionFactory().newConnection();
		Channel channel1 = connection1.createChannel();
		AMQP.Exchange.DeclareOk declareOk;
		try {
			channel1.exchangeDeclare(exchangeName, exchangeMode, durable(exchangeName, null), !durable(exchangeName, null), false, null);
		} catch (IOException e) {
			try {
				channel1.close();
			} catch (Exception ex) {
			}
			try {
				connection1.close();
			} catch (Exception ex) {
			}
			connection1 = Misc.connectionFactory().newConnection();
			channel1 = connection1.createChannel();
			channel1.exchangeDelete(exchangeName);
			try {
				channel1.close();
			} catch (Exception ex) {
			}
			try {
				connection1.close();
			} catch (Exception ex) {
			}
		} finally {
			try {
				channel1.close();
			} catch (Exception ex) {
			}
			try {
				connection1.close();
			} catch (Exception ex) {
			}
		}
		declareOk = channel.exchangeDeclare(exchangeName, exchangeMode, durable(exchangeName, null), !durable(exchangeName, null), false, null);
		return declareOk;
	}

2016/05/19 15:22:31
评论(4)
4楼 小窗口的浪漫 评论时间:2016-11-01 14:26:11 引用
这文章不错。解决了。傻B牛
3楼 小窗口的浪漫 评论时间:2016-11-01 14:06:07 引用
我在一个操作里要往mq的两个队列里插分别插一条数据。为什么插入第二个队列时会同时在第一个队列插入一条? 我关闭channel close也不可以,connection close也不可以。应该怎么做呢???
2楼 母婴B2b 评论时间:2016-05-26 10:41:15 引用
感谢博主的分享~
1楼 小鱼 评论时间:2016-05-19 15:24:21 引用
66666,膜拜大神
共 4 个评论 1/1 页

发表评论

引用成功取消引用×

昵称*: 邮箱*: 网址:

最多可输入300字符 验证码*:


Process: 0.115s | DB :18 queries | UseMem:2,329 kb