system: [SYSTEM]

user: 2. 关键技术研究 采集前置性能涉及多个方面，影响因素也很多，本文从影响采集前置性能的关键环节进行研究处理，包括通信任务分级管理、采集任务并行执行、高并发通信处理、规约动态适配、采集数据入库并行处理等方面。 2.1. 通信任务分级管理 当前采集前置按接收顺序依次对所有下行请求指令进行报文封装处理，即按照“先到先行”的执行策略，当出现下行请求阻塞引起的指令排队等待情况时，重要指令下发的实时性得不到保证，从而影响某项相关业务的正常开展。 针对此问题，首先需要对通信任务进行分级管理。根据通信任务的紧急程度、重要性、用户体验等方面的不同，通信优先级分为高、中、低三个档次。基本的分级原则是：控制指令优先级最高，页面操作高于自动任务。为首先保证主站业务，外部系统操作发起的通信任务的优先级在每个分档中处于中下段。按表1对所有通信指令进行了优先级分级。 Table 1 The task instruction priority lis 优先级 任务类型 说明 1 控制 优先级1~5，前台网页操作 2 参数设置 3 保留 4 召测 5 巡测 6 自定义 优先级6~9，自动任务 7 8 9 10 终端升级 耗时操作，优先级最低 表1. 任务指令优先级表 确定了各通信任务的优先级，接下来进行任务优先级处理，包括两个方面：不同优先级自动任务之间的调度与同一终端下不同优先级通信任务的处理。处理原则是：自动任务的优先级处理是多个任务先后启动时，先执行优先级高的通信任务，即使是优先级高的任务后启动，也需要优先执行优先级高的任务，暂停优先级低的任务发送。同一终端多个任务排队执行时，优先执行优先级高的任务，但为了保证通信任务时序性与连续性，当前正在通信的任务不能被高优先级任务中断。 具体实现方案是采用Kafka消息队列主题分区功能，合理设定多个指令优先级主题，在发生请求阻塞时，采集前置按照优先级来处理指令，从而满足重要指令的快速下发需求。例如，将费控指令放在优先级为A的分区中，召测指令放在优先级为D的分区中，当费控下发前排有大量召测请求时，采集前置也会优先处理费控指令。基于Kafka消息队列实现优先级划分后，可以实时调整某类请求的优先级别，保证重要命令下发的实时性。 2.2. 采集任务并行执行 当前采集前置中自动任务和WEB手动任务全部通过任务调度执行，互相影响效率。 针对此问题，本文将自动任务模块从任务调度拆分出来，专门生成和处理自动任务。任务处理结构如图1所示： 图1. 任务处理结构图 数据采集任务执行主要执行模块为自动任务模块、任务调度模块以及前置机模块。自动任务模块主要负责采集任务定时启动与通信任务的生成，该模块的执行效率直接关系到通信任务生成效率和发送效率；任务调度模块是连接应用服务器和前置机的中间系统，担任着任务的接收、生成、参数配置、组帧、传递、解帧、返回发送的角色，主要负责整个采集系统的任务调度工作，由于处理任务的多样性，与应用服务器和前置机交互频繁，会有大量异步操作和线程管理。 为提高任务发送和接收的速度，使用Kafka消息中间件，其不仅拥有超高吞吐量、毫秒级的延迟、极高的可用性和可靠性，而且分布式可以任意扩展。 自动任务集群节点间通信使用JGroups，使用TCP连接，实现多服务器之间的通信，包括维护群组状态、群组通信协议、群组数据可靠性传输等。JGroups集群中的某个节点会提供在一段时间内维护状态信息和消息可靠性监测的功能。 自动任务采用集群设计但只有一个主系统，主系统比其他系统多了任务分发和任务统计功能，负责任务的启动、运行和监控、结束和取消。主系统的选举和维护通过Redis存储，主系统定时更新心跳至Redis，其他备系统通过读取Redis中的心跳信息获悉主系统的信息。 任务调度与前置机的通信采用socket连接。为确保同一终端的任务始终发送到同一台前置机，使用终端ID跟当前连接的前置机数量取模方式获取发送前置机的连接信息。 2.3. 高并发通信处理 当前采集前置机程序采用select方式对并发通信链路进行报文收发管理，前置机进程每次查看是否有数据接收时，需要将所有连接的套接字传送给操作系统，将大量用户态内存拷贝到内核态内存，增加内存开销的同时，由于每次要对所有管理的连接进行遍历，查看是否有数据接收事件发生，造成巨大的资源浪费。 高效并发通信能力是采集系统数据采集与交互能力的根本，针对采集前置机程序采用select方式存在的问题，采用EPOLL技术来开发管理终端连接处理组件，提升前置机的终端接入及并发通信能力。 Linux内核的Epoll提供了更高效的处理大量并发连接通信的方式，它在Linux内核中申请了一个简易的文件系统，将原来select调用分成“建立一个Epoll对象”、“向Epoll对象中添加链接套接字”、“收集发生事件的连接”3个部分，这样只需要在进程启动时建立1个Epoll对象，并在需要的时候向它添加或删除连接就可以了。因此，在实际收集事件时，epoll_wait的效率就会非常高，因为调用epoll_wait时并没有向它传递全部的连接，内核也不需要去遍历全部的连接，有效降低内存与CPU的使用率。Epoll适合管理大量连接但同一时刻只有少量连接在应用的场景，因此非常适合数据采集这样的并行通信场景。 Epoll提供的操作方法epoll_wait每次只返回有事件发生(如接收到数据)的连接，并将发生的数量返回，因此epoll_wait接收数据比select方法高效。 2.4. 规约动态扩展及适配 当前采集前置的规约处理功能与前置服务耦合度过高。一方面使得规约处理模块程序的更新要求采集前置必须重启；另一方面当规约处理模块程序异常时，还可能联动引发其它异常。 针对此问题，将规约处理模块进行组件化拆分，降低规约处理组件间的耦合度，并基于热插拔理念进行组件管理功能的研发，满足单个规约解析包更新不影响整体采集前置服务的要求。 前置机规约库包含在运行所有采集设备、计量设备或感知器的通信规约，为提升通信过程中规约匹配效率，可根据每通信信道所带现场设备实际规约类型进行选配。新增规约时，只需按前置机约定的接口规范开发新的规约插件，将插件放入前置机规约库即可实现使用新规约与现场设备通信。 前置机进行规约适配采用两种规则：一种是根据下行通信任务指定的规约，另一种是根据上行的报文逐个规约插件解析帧结构适配确定规约类型。 前置机记录有过通信交互的终端的规约类型，在主站与现场设备通信时，主站会将档案配置中的规约类型下发给前置机，前置机按指定的规约插件进行报文组装，并记录该终端的规约类型，在终端返回时，就直接调用相同的插件进行解析。 当终端第一次与前置机建立通信链路请求时，前置机根据发送的报文和该通信信道下配置的规约插件逐个解析帧结构，如果帧结构匹配，则认为该协议适用，前置机记录当前终端的通信协议为该规约类型。除非主站发起通信任务指定的规约类型与识别的规约类型不一样才会修改前置机记录的该终端规约类型，否则将一直使用识别的规约类型与现场设备进行交互通讯。 2.5. 采集数据入库并行处理 当前采集数据一般存储在Oracle数据库中，海量高频数据入库会造成数据库瞬时压力过大的问题。数据库瞬时压力过大不仅造成数据入库的不及时，甚至可能导致数据丢失等其他异常，进而影响相关业务的正常开展。 针对高频数据采集引起的高并发入库处理瓶颈，通过重构系统存储体系来解决处理。引入分布式关系库存储框架，搭建大规模并行处理能力的分布式关系库(作为高频数据，如15分钟一个点的曲线采集的存储)，如图2所示。 图2. 分布式关系库 分布式关系库使用MyCat中间件 + MySQL数据库构建MPP (Massively Parallel Processor)数据库，采用分库分表存储方式，实现数据高效智能的水平拆分与分布式存储。例如，分布式关系库分布在8台MySQL主机的16个分片上，通过mycat rule.xml设定分片规则，通过schema.xml集成各个DataNode (分布式MySQL数据库)来构建逻辑库和逻辑表从而供应用使用，如以正向有功示值为例，该表采用ID mod 16的分片规则，将16个MySQL数据库上的实际存在的表格构建成一个虚拟的逻辑表，应用直接使用该逻辑表进行入库，入库时套用分片规则，根据ID mod 16的规则将数据均匀的存储到16个数据节点上。利用分布式关系库通过分库分表以及扩展节点增加并发处理能力的特点，缓解短时间周期内大量数据入库的压力，满足了大规模高频采集数据入库时高并发处理能力的需求。