【消息队列开发】 虚拟主机设计——操作绑定

🍃前言

本次开发任务:

  • 实现对绑定的添加与绑定

🌲添加绑定

对于绑定的操作相较于前面对交换机和队列的操作就会麻烦一点了

我们分为以下七步来实现:

  1. 对传入的队列名与交换机名字进行重命名

  2. 获取绑定是否存在,若存在,直接返回即可

  3. 验证 bindingKey 是否合法.

    1. 该步骤我们另外创建一个类,创建相应的方法,来判定验证 bindingKey 是否合法.
    2. 这里先不关心具体实现细节,后面会一一实现
    3. 在这里插入图片描述
    4. 在这里插入图片描述
  4. 创建bing对象

  5. 获取相应的交换机与队列对象,若有一个不存在,则不存在绑定关系

  6. 写入硬盘时,我们需要交换机与队列都持久化,才将该绑定写入硬盘

  7. 写入内存

同样我们需要为了线程安全,我们需要进行加锁操作,由于我们该操作既涉及了交换机,有涉及了队列。所以我们这里需要进行双重加锁。

同时不要忘了进行异常处理,代码实现如下:

//添加绑定
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;
    }
}

🌳删除绑定

关于删除绑定,我们分为以下四步实现:

  1. 对传入的队列名与交换机名字进行重命名
  2. 查询相应绑定是否存在,若不存在,直接返回即可
  3. 若存在,无论绑定是否持久化了, 都尝试从硬盘删一下. 就算不存在, 这个删除也无副作用.
  4. 删除内存数据

需要特别注意的是,为了线程安全,我们依旧需要进行加锁操作。

而且加锁顺序一定要与上面增加绑定的顺序相同,不然可能会出现死锁。

最后不要忘了处理异常即可,代码实现如下:

//删除绑定
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;
    }

⭕总结

关于《【消息队列开发】 虚拟主机设计——操作绑定》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遇事问春风乄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值