文章目录
- 🍃前言
- 🌲添加绑定
- 🌳删除绑定
- ⭕总结
🍃前言
本次开发任务:
- 实现对绑定的添加与绑定
🌲添加绑定
对于绑定的操作相较于前面对交换机和队列的操作就会麻烦一点了
我们分为以下七步来实现:
-
对传入的队列名与交换机名字进行重命名
-
获取绑定是否存在,若存在,直接返回即可
-
验证 bindingKey 是否合法.
- 该步骤我们另外创建一个类,创建相应的方法,来判定验证 bindingKey 是否合法.
- 这里先不关心具体实现细节,后面会一一实现
-
创建bing对象
-
获取相应的交换机与队列对象,若有一个不存在,则不存在绑定关系
-
写入硬盘时,我们需要交换机与队列都持久化,才将该绑定写入硬盘
-
写入内存
同样我们需要为了线程安全,我们需要进行加锁操作,由于我们该操作既涉及了交换机,有涉及了队列。所以我们这里需要进行双重加锁。
同时不要忘了进行异常处理,代码实现如下:
//添加绑定
public boolean queueBind(String queueName, String exchangeName, String bindingKey) {queueName = virtualHostName + queueName;exchangeName = virtualHostName + exchangeName;try {synchronized (exchangeLocker) {synchronized (queueLocker) {// 1. 判定当前的绑定是否已经存在了.Binding existsBinding = memoryDataCenter.getBinding(exchangeName, queueName);if (existsBinding != null) {throw new MqException("[VirtualHost] binding 已经存在! queueName=" + queueName+ ", exchangeName=" + exchangeName);}// 2. 验证 bindingKey 是否合法.if (!router.checkBindingKey(bindingKey)) {throw new MqException("[VirtualHost] bindingKey 非法! bindingKey=" + bindingKey);}// 3. 创建 Binding 对象Binding binding = new Binding();binding.setExchangeName(exchangeName);binding.setQueueName(queueName);binding.setBindingKey(bindingKey);// 4. 获取一下对应的交换机和队列. 如果交换机或者队列不存在, 这样的绑定也是无法创建的.MSGQueue queue = memoryDataCenter.getQueue(queueName);if (queue == null) {throw new MqException("[VirtualHost] 队列不存在! queueName=" + queueName);}Exchange exchange = memoryDataCenter.getExchange(exchangeName);if (exchange == null) {throw new MqException("[VirtualHost] 交换机不存在! exchangeName=" + exchangeName);}// 5. 先写硬盘if (queue.isDurable() && exchange.isDurable()) {diskDataCenter.insertBinding(binding);}// 6. 写入内存memoryDataCenter.insertBinding(binding);}}System.out.println("[VirtualHost] 绑定创建成功! exchangeName=" + exchangeName+ ", queueName=" + queueName);return true;} catch (Exception e) {System.out.println("[VirtualHost] 绑定创建失败! exchangeName=" + exchangeName+ ", queueName=" + queueName);e.printStackTrace();return false;}
}
🌳删除绑定
关于删除绑定,我们分为以下四步实现:
- 对传入的队列名与交换机名字进行重命名
- 查询相应绑定是否存在,若不存在,直接返回即可
- 若存在,无论绑定是否持久化了, 都尝试从硬盘删一下. 就算不存在, 这个删除也无副作用.
- 删除内存数据
需要特别注意的是,为了线程安全,我们依旧需要进行加锁操作。
而且加锁顺序一定要与上面增加绑定的顺序相同,不然可能会出现死锁。
最后不要忘了处理异常即可,代码实现如下:
//删除绑定
public boolean queueUnbind(String queueName, String exchangeName) {queueName = virtualHostName + queueName;exchangeName = virtualHostName + exchangeName;try {synchronized (exchangeLocker) {synchronized (queueLocker) {// 1. 获取 binding 看是否已经存在~Binding binding = memoryDataCenter.getBinding(exchangeName, queueName);if (binding == null) {throw new MqException("[VirtualHost] 删除绑定失败! 绑定不存在! exchangeName=" + exchangeName + ", queueName=" + queueName);}// 2. 无论绑定是否持久化了, 都尝试从硬盘删一下. 就算不存在, 这个删除也无副作用.diskDataCenter.deleteBinding(binding);// 3. 删除内存的数据memoryDataCenter.deleteBinding(binding);System.out.println("[VirtualHost] 删除绑定成功!");}}return true;} catch (Exception e) {System.out.println("[VirtualHost] 删除绑定失败!");e.printStackTrace();return false;}
⭕总结
关于《【消息队列开发】 虚拟主机设计——操作绑定》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下