🍃前言
本次开发目标:
创造一个虚拟机类 VirtualHost 类,每个虚拟主机下面都管理着自己的 交换机, 队列, 绑定, 消息 数据,对前面的所有操作进行整合封装,同时提供 api 供上层调用.
同时呢,我们前面所抛出的异常在这里我们就要进行处理了。
本次我们先来实现一些基础属性的注入,和创建交换机与删除交换机的操作。
🌳基础属性与基础方法
首先我们有一个String类型的变量表示该虚拟机的名字。
我们还需要注入两个对象,分别为我们前面封装好的两个类
- MemoryDataCenter
- DiskDataCenter
并对以上属性提供get方法以供进行访问
另外,为了保证线程安全,还提供了两个锁对象
代码实现如下:
🎋初始化操作
在我们进行初始化时,需要做以下三件事儿:
- 根据传入的参数,为该虚拟机命名
- 调用DiskDataCenter 类的初始化方法
- 调用 MemoryDataCenter 的方法将硬盘的数据读到内存上
代码实现如下:
public VirtualHost(String name) { this.virtualHostName = name; // 对于 MemoryDataCenter 来说, 不需要额外的初始化操作的. 只要对象 new 出来就行了 // 但是, 针对 DiskDataCenter 来说, 则需要进行初始化操作. 建库建表和初始数据的设定. diskDataCenter.init(); // 另外还需要针对硬盘的数据, 进行恢复到内存中. try { memoryDataCenter.recovery(diskDataCenter); } catch (IOException | MqException | ClassNotFoundException e) { e.printStackTrace(); System.out.println("[VirtualHost] 恢复内存数据失败!"); } }
🎍创建交换机
对于创建交换机
- 如果交换机不存在, 就创建, 如果存在, 直接返回.
- 返回值是 boolean.,创建成功, 返回 true,失败返回 false。
这里我们为了保证不同虚拟机内可以含有相同类,我们对传入的交换机名字进行简单加工下。
使现在 交换机的名字 = 虚拟机名字 + 传入交换机的名字
创建交换机我们可以分为以下五步
- 判定该交换机是否已经存在.,直接通过内存查询,若存在,打印一个日志,返回true即可
- 真正创建交换机.,根据传入的参数先构造 Exchange 对象
- 把交换机对象写入硬盘
- 把交换机写入内存中
- 返回true
需要注意的是:
- 上面操作3与操作4最好不要调换,先写硬盘, 后写内存。 目的就是因为硬盘更容易写失败. 如果硬盘写失败了, 内存就不写了。要是先写内存, 内存写成功了, 硬盘写失败了, 还需要把内存的数据给再删掉. 就比较麻烦了。
- 上述操作现在并不是线程安全的,所以我们需要利用上面创建的锁对象进行加锁操作
- 除此之外,我们需要对该层的异常进行一个处理,不再往上抛了
代码实现如下:
// 创建交换机 // 如果交换机不存在, 就创建. 如果存在, 直接返回. // 返回值是 boolean. 创建成功, 返回 true. 失败返回 false public boolean exchangeDeclare(String exchangeName, ExchangeType exchangeType, boolean durable, boolean autoDelete, Map<String, Object> arguments) { // 把交换机的名字, 加上虚拟主机作为前缀. exchangeName = virtualHostName + exchangeName; try { synchronized (exchangeLocker) { // 1. 判定该交换机是否已经存在. 直接通过内存查询. Exchange existsExchange = memoryDataCenter.getExchange(exchangeName); if (existsExchange != null) { // 该交换机已经存在! System.out.println("[VirtualHost] 交换机已经存在! exchangeName=" + exchangeName); return true; } // 2. 真正创建交换机. 先构造 Exchange 对象 Exchange exchange = new Exchange(); exchange.setName(exchangeName); exchange.setType(exchangeType); exchange.setDurable(durable); exchange.setAutoDelete(autoDelete); exchange.setArguments(arguments); // 3. 把交换机对象写入硬盘 if (durable) { diskDataCenter.insertExchange(exchange); } // 4. 把交换机对象写入内存 memoryDataCenter.insertExchange(exchange); System.out.println("[VirtualHost] 交换机创建完成! exchangeName=" + exchangeName); // 上述逻辑, 先写硬盘, 后写内存. 目的就是因为硬盘更容易写失败. 如果硬盘写失败了, 内存就不写了. // 要是先写内存, 内存写成功了, 硬盘写失败了, 还需要把内存的数据给再删掉. 就比较麻烦了. } return true; } catch (Exception e) { System.out.println("[VirtualHost] 交换机创建失败! exchangeName=" + exchangeName); e.printStackTrace(); return false; } }
🍀删除交换机
删除交换机的逻辑,我们分为四步进行:
- 修改交换机的名字
- 查询是否有该交换机
- 删除硬盘上的数据
- 删除内存上的数据
同样,为了线程安全,我们同样利用我们前面提供的交换机对象进行加锁操作。
代码实现如下:
// 删除交换机 public boolean exchangeDelete(String exchangeName) { exchangeName = virtualHostName + exchangeName; try { synchronized (exchangeLocker) { // 1. 先找到对应的交换机. Exchange toDelete = memoryDataCenter.getExchange(exchangeName); if (toDelete == null) { throw new MqException("[VirtualHost] 交换机不存在无法删除!"); } // 2. 删除硬盘上的数据 if (toDelete.isDurable()) { diskDataCenter.deleteExchange(exchangeName); } // 3. 删除内存中的交换机数据 memoryDataCenter.deleteExchange(exchangeName); System.out.println("[VirtualHost] 交换机删除成功! exchangeName=" + exchangeName); } return true; } catch (Exception e) { System.out.println("[VirtualHost] 交换机删除失败! exchangeName=" + exchangeName); e.printStackTrace(); return false; } }
⭕总结
关于《【消息队列开发】虚拟主机设计——操作交换机》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下