当前位置: 首页 > news >正文

鄠邑建站 网站建设线上推广方案怎么做

鄠邑建站 网站建设,线上推广方案怎么做,建筑咨询公司是做什么的,dede模板蓝色大气简洁企业网站模板下载目录 一、内存数据管理 1.1、需求分析 1.2、实现 MemoryDataCenter 类 1.2.1、ConcurrentHashMap 数据管理 1.2.2、封装交换机操作 1.2.3、封装队列操作 1.2.4、封装绑定操作 1.2.5、封装消息操作 1.2.6、封装未确认消息操作 1.2.7、封装恢复数据操作 一、内存数据管理…

目录

一、内存数据管理

1.1、需求分析

1.2、实现 MemoryDataCenter 类

1.2.1、ConcurrentHashMap 数据管理

1.2.2、封装交换机操作

1.2.3、封装队列操作

1.2.4、封装绑定操作

1.2.5、封装消息操作

1.2.6、封装未确认消息操作

1.2.7、封装恢复数据操作


一、内存数据管理


1.1、需求分析

当前已经使用 数据库 管理了 交换机、绑定、队列,又使用 数据文件 管理了 消息.

最后还使用一个类将上述两部分整合在了一起,对上层提供统一的一套接口.

但对于 MQ 来说,是以内存存储数据为主,硬盘存储数据为辅(硬盘数据主要是为了持久化保存,重启之后,数据不丢失).

接下来就需要使用 内存 来管理上述数据~~

这里我们主要使用 ConcurrentHashMap 来进行数据管理(主要是因为线程安全问题).

交换机:使用 ConcurrentHashMap,key 是 name,value 是 Exchange 对象。

队列:使用 ConcurrentHashMap,key 是 name,value 是 MSGQueue 对象。

绑定:使用嵌套的 ConcurrentHashMap,key 是 exchangeName,value 是一个 ConcurrentHashMap(key 是 queueName,value 是 Binding 对象)。

消息:使用 ConcurrentHashMap,key 是 messageId ,value 是 Message 对象。

队列和消息的关联关系:使用嵌套的 ConcurrentHashMap,key 是 queueName,value 是一个 LinkedList(每个元素是一个 Message 对象)。

表示 “未被确认” 的消息:使用嵌套的 ConcurrentHashMap,key 是 queueName,value 是 ConcurrentHashMap(key 是 messageId,value 是 Message 对象,后续实现消息确认的逻辑,需要根据 ack 响应的内容,会提供一个确认的 messageId,根据这个 messageId 来把上述结构中的 Message 对象找到并移除)。

Ps:此处实现的 MQ,支持两种应答模式的 ACK

  1. 自动应答:消费者取了元素,整个消息就算是被应答了,此时整个消息就可以被干掉了。
  2. 手动应答:消费者取了元素,这个消息不算被应答,需要消费者主动再调用一个 basicAck 方法,此时才认为是真正应答了,才能删除这个消息。

1.2、实现 MemoryDataCenter 类

1.2.1、ConcurrentHashMap 数据管理

这里就是用 ConcurrentHashMap 来对上述数据进行统一内存管理.

    //key 是 exchangeName, value 是 Exchange 对象private ConcurrentHashMap<String, Exchange> exchangeMap = new ConcurrentHashMap<>();//key 是 queueName, value 是 MSGQueue 对象private ConcurrentHashMap<String, MSGQueue> queueMap = new ConcurrentHashMap<>();//第一个 key 是 exchangeName,第二个 key 是 queueNameprivate ConcurrentHashMap<String, ConcurrentHashMap<String, Binding>> bindingsMap = new ConcurrentHashMap<>();//key 是 messageId ,value 是 Message 对象private ConcurrentHashMap<String, Message> messageMap = new ConcurrentHashMap<>();//key 是 queueName , value 是 Message 的链表private ConcurrentHashMap<String, LinkedList<Message>> queueMessageMap = new ConcurrentHashMap<>();// 第一个 key 是 queueName, 第二个 key 是 messageIdprivate ConcurrentHashMap<String, ConcurrentHashMap<String, Message>> queueMessageWaitAckMap = new ConcurrentHashMap<>();

1.2.2、封装交换机操作

主要就是对 exchangeMap 插入、获取、删除交换机.

public void insertExchange(Exchange exchange) {exchangeMap.put(exchange.getName(), exchange);System.out.println("[MemoryDataCenter] 新交换机添加成功! exchangeName=" + exchange.getName());}public Exchange getExchange(String exchangeName) {return exchangeMap.get(exchangeName);}public void deleteExchange(String exchangeName) {exchangeMap.remove(exchangeName);System.out.println("[MemoryDataCenter] 交换机删除成功! exchangeName=" + exchangeName);}

1.2.3、封装队列操作

主要就是对 queueMap 插入、获取、删除队列.

    public void insertQueue(MSGQueue queue) {queueMap.put(queue.getName(), queue);System.out.println("[MemoryDataCenter] 新队列添加成功! queueName=" + queue.getName());}public MSGQueue getQueue(String queueName) {return queueMap.get(queueName);}public void deleteQueue(String queueName) {queueMap.remove(queueName);System.out.println("[MemoryDataCenter] 队列删除成功! queueName=" + queueName);}

1.2.4、封装绑定操作

这里值得注意的是加锁逻辑,并不是加了锁就一定安全,也不是说不加锁就一定不安全,如果这段代码前后逻辑性很强,需要打包成一个原子性的操作,那就可以进行加锁,如果不是那么强的因果,就没必要,因为加锁也是需要开销的,加锁之后的锁竞争更是一个时间消耗。

    public void insertBinding(Binding binding) throws MqException {
//        ConcurrentHashMap<String, Binding> bindingMap = bindingsMap.get(binding.getExchangeName());
//        if(bindingMap == null) {
//            bindingMap = new ConcurrentHashMap<>();
//            bindingsMap.put(binding.getExchangeName(), bindingMap);
//        }//上面这段逻辑可以用以下代码来替换ConcurrentHashMap<String, Binding> bindingMap = bindingsMap.computeIfAbsent(binding.getExchangeName(),k -> new ConcurrentHashMap<>());synchronized(bindingMap) {//再根据 queueName 查一下,只有不存在的时候才能插入,存在就抛出异常if(bindingMap.get(binding.getQueueName()) != null) {throw new MqException("[MemoryDataCenter] 绑定已经存在! exchangeName=" + binding.getExchangeName() +", queueName=" + binding.getQueueName());}bindingMap.put(binding.getQueueName(), binding);}System.out.println("[MemoryDataCenter] 新绑定添加成功!exchangeName=" + binding.getExchangeName() +", queueName=" + binding.getQueueName());}/*** 获取绑定有两个版本* 1.根据 exchangeName 和 queueName 确定唯一一个 Binding* 2.根据 exchangeName 获取到所有的 Binding* @param exchangeName* @param queueName* @return*/public Binding getBinding(String exchangeName, String queueName) throws MqException {ConcurrentHashMap<String, Binding> bindingMap = bindingsMap.get(exchangeName);if(bindingMap == null) {throw new MqException("[MemoryDataCenter] 绑定不存在!exchangeName=" + exchangeName +", queueName=" + queueName);}return bindingMap.get(queueName);}public ConcurrentHashMap<String, Binding> getBindings(String exchangName) {return bindingsMap.get(exchangName);}public void deleteBinding(Binding binding) throws MqException {ConcurrentHashMap<String, Binding>  bindingMap = bindingsMap.get(binding.getExchangeName());//这里操作不是很关键,因此可以不用加锁(加锁不一定就安全,也不是说不加锁就一定不安全,要结合实际场景)//如果这段代码前后逻辑性很强,需要打包成一个原子性的操作,那就可以进行加锁,如果不是那么强的因果,就没必要,因为加锁也是需要开销的,加锁之后的锁竞争更是一个时间消耗if(bindingMap == null) {throw new MqException("[MemoryDataCenter] 绑定不存在!exchangeName=" + binding.getExchangeName() +", queueName=" + binding.getQueueName());}bindingMap.remove(binding.getQueueName());System.out.println("[MemoryDataCenter] 绑定删除成功!exchangeName=" + binding.getExchangeName() +", queueName=" + binding.getQueueName());}

1.2.5、封装消息操作

这里值得注意的是 LinkedList 是线程不安全的,要特殊处理.

    /*** 添加消息* @param message*/public void addMessage(Message message) {messageMap.put(message.getMessageId(), message);System.out.println("[MemoryDataCenter] 新消息添加成功!messageId=" + message.getMessageId());}/*** 根据 id 查询消息* @param messageId*/public Message selectMessage(String messageId) {return messageMap.get(messageId);}/*** 根据 id 删除消息* @param messageId*/public void removeMessage(String messageId) {messageMap.remove(messageId);System.out.println("[MemoryDataCenter] 消息被移除!messageId=" + messageId);}/*** 发送消息到指定队列* @param message*/public void sendMessage(MSGQueue queue, Message message) {//先根据队列名字找到指定的链表LinkedList<Message> messages = queueMessageMap.computeIfAbsent(queue.getName(), k -> new LinkedList<>());//LinkedList 是线程不安全的synchronized (messages) {messages.add(message);}//这里把消息在消息中心也插入一下。即使 message 在消息中心存在也没关系//因为相同的 messageId 对应的 message 的内容一定是一样的(服务器不会修改 Message 的内容)addMessage(message);System.out.println("[MemoryDataCenter] 消息被投递到队列当中!messageId=" + message.getMessageId());}/*** 从队列中取消息* @param queueName* @return*/public Message pollMessage(String queueName) {LinkedList<Message> messages = queueMessageMap.get(queueName);if(messages == null) {return null;}synchronized (messages) {if(messages.size() == 0) {return null;}//链表中有消息就进行头删Message currentMessage = messages.remove(0);System.out.println("[MemoryDataCenter] 消息从队列中取出! messageId=" + currentMessage.getMessageId());return currentMessage;}}/*** 获取指定队列的消息个数* @param queueName* @return*/public int getMessageCount(String queueName) {LinkedList<Message> messages = queueMessageMap.get(queueName);if(messages == null) {return 0;}synchronized (messages) {return messages.size();}}

1.2.6、封装未确认消息操作

“未被确认” 的消息:使用嵌套的 ConcurrentHashMap,key 是 queueName,value 是 ConcurrentHashMap(key 是 messageId,value 是 Message 对象,后续实现消息确认的逻辑,需要根据 ack 响应的内容,会提供一个确认的 messageId,根据这个 messageId 来把上述结构中的 Message 对象找到并移除)。

    /*** 添加未确认的消息* @param queueName* @param message*/public void addMessageWaitAck(String queueName, Message message) {ConcurrentHashMap<String, Message> messageHashMap = queueMessageWaitAckMap.computeIfAbsent(queueName,k -> new ConcurrentHashMap<>());messageHashMap.put(message.getMessageId(), message);System.out.println("[MemoryDataCenter] 消息进入待确认队列!messageId=" + message.getMessageId());}/*** 删除未确认的消息* @param messageId*/public void removeMessageWaitAck(String queueName, String messageId) {ConcurrentHashMap<String, Message> messageHashMap = queueMessageWaitAckMap.get(queueName);if(messageHashMap == null) {return;}messageHashMap.remove(messageId);System.out.println("[MemoryDataCenter] 消息从待确认队列中删除!messageId=" + messageId);}public Message getMessageWaitAck(String queueName, String messageId) {ConcurrentHashMap<String, Message> messageHashMap = queueMessageWaitAckMap.get(queueName);if(messageHashMap == null) {return null;}return messageHashMap.get(messageId);}

1.2.7、封装恢复数据操作

从硬盘上读取数据,把硬盘中之前持久化存储的各个维度的数据都恢复到内存中.

public void recovery(DiskDataCenter diskDataCenter) throws IOException, MqException, ClassNotFoundException {//1.先清空之前所有的数据exchangeMap.clear();queueMap.clear();bindingsMap.clear();messageMap.clear();queueMessageMap.clear();//2.恢复所有的交换机数据List<Exchange> exchanges = diskDataCenter.selectAllExchanges();for(Exchange exchange : exchanges) {exchangeMap.put(exchange.getName(), exchange);}//3.恢复所有的队列数据List<MSGQueue> queues = diskDataCenter.selectAllQueue();for(MSGQueue queue : queues) {queueMap.put(queue.getName(), queue);}//4.恢复所有绑定数据List<Binding> bindings = diskDataCenter.selectAllBindings();for(Binding binding : bindings) {ConcurrentHashMap<String, Binding> bindingMap = bindingsMap.computeIfAbsent(binding.getExchangeName(),k -> new ConcurrentHashMap<>());bindingMap.put(binding.getQueueName(), binding);}//5.恢复所有的消息数据for(MSGQueue queue : queues) {LinkedList<Message> messages = diskDataCenter.loadAllMessagesFromQueue(queue.getName());queueMessageMap.put(queue.getName(), messages);//遍历所有的队列,根据每个队列名字。来恢复所有消息for(Message message : messages) {messageMap.put(message.getMessageId(), message);}}}

Ps;“未确认的消息” 这部分数据不需要从硬盘中恢复,之前硬盘存储也没有考虑过这里~

一旦在等待 ack 的过程中,服务器重启了,这些 “未被确认的消息” 就恢复成了 “未被取走的消息”,这个消息在硬盘上存储的时候,就是当作 “未被取走”。

 


文章转载自:
http://allnighter.pfbx.cn
http://assimilable.pfbx.cn
http://rupee.pfbx.cn
http://drinking.pfbx.cn
http://astrut.pfbx.cn
http://micromicrofarad.pfbx.cn
http://amateurship.pfbx.cn
http://garry.pfbx.cn
http://rascal.pfbx.cn
http://thickskinned.pfbx.cn
http://otb.pfbx.cn
http://boina.pfbx.cn
http://soundproof.pfbx.cn
http://motopia.pfbx.cn
http://chemiluminescnet.pfbx.cn
http://getatable.pfbx.cn
http://toxicologist.pfbx.cn
http://convolve.pfbx.cn
http://glazy.pfbx.cn
http://redetermination.pfbx.cn
http://chatoyancy.pfbx.cn
http://dard.pfbx.cn
http://shant.pfbx.cn
http://tangency.pfbx.cn
http://herewith.pfbx.cn
http://resentment.pfbx.cn
http://calcedony.pfbx.cn
http://spitfire.pfbx.cn
http://inhale.pfbx.cn
http://amvets.pfbx.cn
http://corfam.pfbx.cn
http://greenwinged.pfbx.cn
http://diastral.pfbx.cn
http://cyberholic.pfbx.cn
http://janissary.pfbx.cn
http://dy.pfbx.cn
http://partly.pfbx.cn
http://deficiently.pfbx.cn
http://honeyfogle.pfbx.cn
http://submucous.pfbx.cn
http://pentoxide.pfbx.cn
http://papermaker.pfbx.cn
http://joseph.pfbx.cn
http://chloramine.pfbx.cn
http://unlikeliness.pfbx.cn
http://stockman.pfbx.cn
http://diapason.pfbx.cn
http://antillean.pfbx.cn
http://sarawak.pfbx.cn
http://presignify.pfbx.cn
http://rear.pfbx.cn
http://ironclad.pfbx.cn
http://galatz.pfbx.cn
http://misdiagnosis.pfbx.cn
http://alkermes.pfbx.cn
http://whitsuntide.pfbx.cn
http://microbeam.pfbx.cn
http://navicular.pfbx.cn
http://mym.pfbx.cn
http://ghilgai.pfbx.cn
http://cabas.pfbx.cn
http://falcon.pfbx.cn
http://dart.pfbx.cn
http://curvicaudate.pfbx.cn
http://objectionable.pfbx.cn
http://pretypify.pfbx.cn
http://jeremias.pfbx.cn
http://choriambi.pfbx.cn
http://colourbearer.pfbx.cn
http://collector.pfbx.cn
http://nigger.pfbx.cn
http://outermost.pfbx.cn
http://slipstream.pfbx.cn
http://hieroglyphologist.pfbx.cn
http://transferrer.pfbx.cn
http://franchise.pfbx.cn
http://admiralty.pfbx.cn
http://hence.pfbx.cn
http://euphrosyne.pfbx.cn
http://buttress.pfbx.cn
http://batchy.pfbx.cn
http://superintend.pfbx.cn
http://picturegoer.pfbx.cn
http://simpliciter.pfbx.cn
http://yamal.pfbx.cn
http://greaseproof.pfbx.cn
http://plyer.pfbx.cn
http://kilovar.pfbx.cn
http://unexpected.pfbx.cn
http://sundowner.pfbx.cn
http://toril.pfbx.cn
http://dingo.pfbx.cn
http://validating.pfbx.cn
http://alfreda.pfbx.cn
http://unbuttoned.pfbx.cn
http://recommencement.pfbx.cn
http://compleat.pfbx.cn
http://blithe.pfbx.cn
http://solonetz.pfbx.cn
http://treat.pfbx.cn
http://www.15wanjia.com/news/102514.html

相关文章:

  • 做西装的网站数据网站有哪些
  • web服务器有哪些石家庄百度快照优化排名
  • 平邑网站建设有没有专门做策划的公司
  • 不用开源做网站成品网站货源1688在线
  • 工会网站建设请示推广普通话内容
  • xrea免费 wordpress 加速百度推广优化师是什么
  • 做网站需要注意什么免费建站网站网页
  • 九号公司杭州余杭区抖音seo质量高
  • 二手交易网站建设内容策划泉州百度seo
  • 东营可以做网站的公司在哪怎样和政府交换友链
  • 哪个网站可预约做头发山东工艺美术学院网站建设公司
  • 学做卤味视频网站全国人大常委会委员长
  • 腾云公司做网站seo自然优化排名
  • 2017做那个网站能致富做seo用哪种建站程序最好
  • 美国专门做特卖的网站宜昌今日头条新闻
  • 手机上怎么做微电影网站站长之家关键词挖掘
  • 网站代做多少钱仿站定制模板建站
  • 兰州哪家网站做推广效果好360优化大师下载
  • b2c网站的促销策略互联网金融营销案例
  • jquery网站开发教程长沙seo排名公司
  • 设计公司的简介介绍百度seo新算法
  • 临安农家乐做网站软文世界平台
  • 做英文网站 赚美元1688精品货源网站入口
  • 网站怎么怎么做关键字关键词优化排名公司
  • 怎么查网站建设是哪家公司营销策略方案
  • 新手建设html5网站便宜的seo官网优化
  • 餐饮门户网站源码怎么在百度上发帖推广
  • 网站链接失效怎么做杭州百度首页优化
  • 武汉高端网站制作百度智能建站系统
  • 巴中建网站的公司如何查一个关键词的搜索量