热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

订阅+定时任务重构后台主机操作任务

主机状态一直显示有问题,去向动态链接库请求数据时,除了第一台主机访问成功外,以后的每一台主机返回的结

问题描述

主机状态一直显示有问题,去向动态链接库请求数据时,除了第一台主机访问成功外,以后的每一台主机返回的结果都是 9(HOST_NOT_FOUND)

订阅 + 定时任务重构后台主机操作任务

研究了很久也没研究明白,最后求助潘老师。

订阅 + 定时任务重构后台主机操作任务

潘老师指出是指针有问题,主机的指针是我们构造出来的,虽然该指针指向对象的 namecontext 与动态链接库服务那边的都一样,但是他那里可能是按地址处理的,不是同一个地址,就报主机找不到了。

经过测试,确实是这样。

不能直接构造指针,需要使用同步计算机数据时返回的指针进行操作。

订阅 + 定时任务重构后台主机操作任务

所以,获取计算机状态,操作计算机都需要重新同步一下计算机,将指针同步过来。

假设用户操作很频繁的话,对动态链接库的压力就很大。指不定啥时候就炸了。

虽然我想到了这点,但也没想到好的解决方案。

潘老师最终的设计方案非常好,采用定时任务,当有计算机的操作时,不实时进行操作,而是先存起来,每隔一段时间统一进行操作,从而减轻服务器压力。

实现

设计

对主机进行关机或重启时,不立即执行,而是将其添加到一个要执行的任务列表中,当定时任务触发后,再统一执行。

订阅 + 定时任务重构后台主机操作任务

定时任务

定时任务很简单,之前在计量中写过一个每天晚上定时统计数据的定时任务,这次写这个没什么难度,都不需要看文档了。

注释很详尽,相信聪明的你完全可以理解。

这里的存储计算机状态设置了一个主机名到计算机状态映射的 HashMap ,这里没有用 ConcurrentHashMap ,因为只有定时任务一个线程进行 put ,其他接口调用该 Map 只负责查询,不会出现冲突。

@Async
@Scheduled(fixedRate = 10000)        // 每隔10s执行
public void hostHandle() {
    logger.info("--- 开始执行定时任务 ---");

    logger.debug("获取关机重启的订阅者");
    Set shutdownSubscribers = this.cloneStringSetAndClear(hostService.getShutdownSubscribers());
    Set rebootSubscribers = this.cloneStringSetAndClear(hostService.getRebootSubscribers());

    logger.debug("获取主机结构体指针Map");
    List byReferenceList = baseService.getHostStructReferenceList();
    Map byReferenceMap = baseService.getHostStructReferenceMap(byReferenceList);

    if (!shutdownSubscribers.isEmpty()) {
        logger.info("存在关机订阅,执行关机操作");

        for (String name : shutdownSubscribers) {
            logger.debug("获取结构体指针并关机");
            HostStruct.ByReference byReference = byReferenceMap.get(name);
            baseService.shutdown(byReference);
        }
    }

    if (!rebootSubscribers.isEmpty()) {
        logger.info("存在重启订阅,执行重启操作");

        for (String name : rebootSubscribers) {
            logger.debug("获取结构体指针并重启");
            HostStruct.ByReference byReference = byReferenceMap.get(name);
            baseService.reboot(byReference);
        }
    }

    logger.debug("查询主机列表");
    for (HostStruct.ByReference byReference : byReferenceList) {
        logger.debug("查询主机指针,同时获取主机信息");
        Integer status = baseService.getHostStatus(byReference);

        logger.debug("添加到Map中");
        hostService.getHostStatusMap().put(Native.toString(byReference.name), status);
    }

    logger.info("--- 定时任务执行完毕 ---");
}

/**
 * 克隆字符串集合并清空原集合
 * @param primarySet 原集合
 * @return 克隆的字符串集合
 */
private Set cloneStringSetAndClear(Set primarySet) {
    logger.debug("新建集合");
    Set set = new HashSet<>(primarySet);

    logger.debug("清空原集合");
    primarySet.clear();

    logger.debug("返回");
    return set;
}

todo

目前是用 Set 存储要操作的主机,但是经过查询, HashSetLinkedHashSetTreeSet 都是线程不安全的。

这里就怕执行定时任务的时候,突然来了一个关机的指令,两个线程同时访问 Set ,定时任务要克隆一个 Set 然后把这个清空,关机需要在 Set 中添加元素,两个线程如果交替执行,结果就很难说了。

订阅 + 定时任务重构后台主机操作任务

concurrent 包下找,也没找到合适的。看了看,有第三方库实现的线程安全的 Set ,以后引入进来。

订阅 + 定时任务重构后台主机操作任务

这里不知道是不是我用的有问题,是并发场景下不推荐用 Set 吗?为什么 concurrent 包下没有相关的实现类?

总结

感叹一句: C++ 还是难啊!

C++ 老师对我的评价是字写得还不错,哈哈哈。佩服 C++ 工程师!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 我们


推荐阅读
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • OO第一单元自白:简单多项式导函数的设计与bug分析
    本文介绍了作者在学习OO的第一次作业中所遇到的问题及其解决方案。作者通过建立Multinomial和Monomial两个类来实现多项式和单项式,并通过append方法将单项式组合为多项式,并在此过程中合并同类项。作者还介绍了单项式和多项式的求导方法,并解释了如何利用正则表达式提取各个单项式并进行求导。同时,作者还对自己在输入合法性判断上的不足进行了bug分析,指出了自己在处理指数情况时出现的问题,并总结了被hack的原因。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
author-avatar
陳小勳2502936731
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有