分布式服务架构在信号处理系统中的应用
2019-12-24叶江峰
文 豪,叶江峰,孙 磊,吴 辉
(中国工程物理研究院 电子工程研究所,四川 绵阳 621900)
0 引言
随着信息化进程的加快,电磁环境的日趋复杂,新的信号体制及应用需求层出不穷,以往那种功能单一、灵活性不足的无线电信号处理系统已远不能适应当前灵活多变的应用需求[1]。为此,软件无线电(SDR)技术从20世纪90年代以后逐渐兴起[2]。其思想是通过构造一个具有开放性、标准化和模块化的通用硬件平台,使无线通信系统具有高度灵活性、开放性[3]。由此,美军通过联合战术无线电系统(JTRS)制定了软件体系结构(SCA)规范[4],该标准体系结构为开发提供统一的、开放式的底层支持和服务,保证了软件组件的可移植性和可重用性[5]。但SCA规范仅能用于指导软件无线电通信系统整体的设计开发,并没有给出具体的实现方法。目前,大多数SCA波形组件开发方法都较为繁琐复杂,技术门槛较高,由此势必给波形开发人员带来很大的开发难度,造成开发周期延长、开发成本上升和测试工作量显著增加等问题[6]。同时,传统波形组件不满足分布式部署与跨平台等需求,并不适用于搭建原理性的验证系统。
针对上述问题,本文引入SOA(Service Oriented Architecture)的设计理念,将其应用于信号处理领域,采用更加简洁优秀的ICE(Internet Communications Engine)中间件技术构建出新的信号处理系统架构模型。该模型不仅具有很好的可移植性和可重用性,还具备自动化服务组件封装能力,极大简化了组件开发过程。
另一方面,随着集群技术的发展,以通用的计算机平台来替代专用的DSP和FPGA等硬件来进行软件数字信号处理也成为业界热门的研究方向[7]。本文设计采用“分布式”的服务架构,解决并行化处理、平台异构等问题,使系统能通过增加处理节点提高处理能力,以满足大数据量信号处理的实时性要求。
1 基于服务架构的信号处理系统模型
1.1 系统架构分析及特点
系统的分层体系结构参考模型如图1所示,其主要包括:软硬件资源、分布式服务总线、服务集成开发环境、基础服务层、服务组件层、业务服务层和应用系统层。
图1 模型分层体系结构
软硬件资源:为实现最大的性能提升及硬件扩展能力,模型支持相对复杂软硬件资源,主要包括数据库、分布式文件系统、GPP资源和GPU资源等。这些资源用来为系统提供计算资源、数据存取资源,支撑上层各类服务和应用的运行。
分布式服务总线:作为服务框架的核心组成,主要负责适配并连接各服务组件执行系统业务功能,包括服务管理、服务注册中心、基础数据服务、接口适配和消息分发(基于ZeroMQ)等模块。
服务集成开发环境:服务组件开发工具。支持C++语言框架代码自动生成,帮助开发者完成服务的开发。更重要的是能够实现Matlab文件的服务自动转换,直接生成满足ICE接口规范的服务发布包。
基础服务层:由各种基础服务组成,包括数据分发、数据存储、数据源、异常处理和资源调度等。其主要作用是通过服务封装把软硬件资源抽象成服务对象,使调用者不必关心底层驱动和数据管理。
服务组件层:服务组件是开发人员需要自行设计实现的最小系统组成单元,通常为不可以再拆分且可复用的算法单元。应用服务集成开发环境可实现服务组件的快速开发。
业务服务层:通常由服务组件组合而成,通过组合和流程编排形成业务服务(也称为组合服务),实现具体的业务功能。
应用系统层:作为直接面向用户的应用系统,接收来自服务端的推送信息予以显示。用户界面开发采用了QT插件框架技术,可实现界面的灵活布局,具备良好扩展性和跨平台能力。
分布式服务架构拥有以下特性:
简便的开发过程:可以对符合格式规范的算法源代码进行直接的服务转化,而不用针对该平台重新设计开发服务组件,极大地降低了系统开发难度,也节省了开发时间。
多语言支持:通过使用标准的接口定义,使得服务组件支持C++,Matlab,Java语言开发。
跨平台特性:服务组件可以运行在不同的操作系统和机器架构上,并且可以使用多种网络协议进行通信。
良好的系统伸缩性:服务组件可任意分布在多个服务器上,系统的最大运算效率可以随着系统硬件资源的增加而提高。
整体而言,该架构具有良好的开放性,能够适应将来的业务拓展需求,有效地提高服务利用率,减少开发成本。
1.2 服务组件的封装
新信号处理系统的研发,通常需要在Matlab仿真基础上,再进行软件应用程序的开发或者硬件设备的研制,从而评估新系统架构的合理性[8]。但这一过程通常需要多次迭代,使得这种研发模式面临着周期长、成本高的困境。本文设计了一种名为“服务集成开发环境”的软件,可方便地把C++和Matlab程序转化为服务组件,部署于分布式服务架构中就可快速验证系统的可行性。
因为ICE本身对C++具有良好的支持[9],通过C++源代码生成服务组件,本文不做赘述。而Matlab却是信号处理领域实现系统仿真应用最多的工具,所以,解决Matlab程序的服务快速开发才是简化组件开发的关键。Matlab程序转化的服务包封装结构如图2所示。
图2 Matlab程序转化的服务包封装结构
Matlab程序转化的服务包封装的步骤如下:
① 为实现服务的转化,Matlab程序编写必须符合一定规范,其具体函数形式如下:
function[strRes,Output1,...] = 函数名(Input1,Input2,Input3,...)
函数参数被分别定义为输出参数、输入参数和配置参数。输出参数在等号左侧,strRes被定义为调试信息输出结构体;输入参数在等号右侧;配置参数也是输入参数,但在注释中加入了Config关键字用来识别。
② 本文设计的服务集成开发环境会对文件内容及注释信息进行格式检查,对满足规范的文件则调用Matlab自带的mcc编译器,编译出符合C语言规范的DLL文件及头文件形成一层封装。
③ 实现DLL文件向ICE服务转化。这个过程比较复杂,但最关键的就是数据类型的转化。我们知道,Matlab所有的计算都基于一种名为mxArray的数据结构,虽然Matlab提供了数据转换函数mlfScalar()和mxGetPr(),但其依赖Matlab环境,不便于系统独立运行。为被上层的ICE函数调用,必须把ICE函数输入参数从C数据类型转化为mwArray类型并传递给DLL中的函数。本文设计了一组“mwArrayEx”的模板类,通过该模板类解决了输入参数的数据类型转化。示例如下:
template<>
classmwArrayEx
{
public:
mwArrayEx(const string& data)
:m_Data(data)
{
}
~mwArrayEx(void)
{
}
operator mwArray()
{
return mwArray(m_Data.c_str());
∥不同数据类型,获取方式不同
}
private:
const string m_Data;
};
相反,ICE函数的输出参数则需要从mwArray类型转化为C数据类型。本文通过设计定义一组名为“Dataconvert”的模板函数转化Matlab矩阵数据为数组结构来解决上述问题。由于原理类似,这里不做赘述。2种模板解决了Matlab程序与C++数据类型的相互转化问题,使得函数能够严格按照ICE规范实现服务的封装。
依照以上设计原理,服务集成开发环境被设计为一个自动化的开发转化工具,系统集成人员不需要了解具体算法,只需要应用该工具转化目标文件(m文件或Cpp文件)为服务包,发布并部署于集群服务器,再通过服务管理软件对服务流程组合编排就可以完成系统开发。开发环境的服务转化流程如图3所示。
图3 服务开发环境服务转化实现流程
具体步骤如下:
① 开发人员首先选择需要转化的目标文件,可以是C++或Matlab语言。
② 软件验证目标文件并根据函数定义及其注释生成ICE接口文件[10]。同时,生成“mwArrayEx”和“Dataconvert”源文件,供类型转化函数调用。
③ 软件判断需要转化的源程序语言类型,如果是C++源程序直接通过ICE接口文件生成对应的*I.h和*I.cpp、*ServerI.h和*IServer.cpp等服务源文件;如果是Matlab语言源程序需要通过调用mcc生成动态链接库,并进行数据类型转化后再生成服务源程序。
④ 软件生成XML格式的服务配置文件,主要包括:服务名称、服务类型、配置参数、出入参数和输出参数等信息。
⑤ 软件生成整个服务工程文件(.sln),自动调用VS2010编译器对工程进行编译,生成服务包。
不难看出,本文设计开发的服务集成开发环境为用户提供了自动化的服务开发能力。使得系统开发人员不需要了解具体算法设计及ICE开发规范就可以自动生成服务开发包(包括服务框架代码、服务描述文件以及接口定义文件等)用以组合成业务系统。通过让算法设计、组件开发和系统集成3个过程的相互分离,降低了服务开发及系统集成的难度。
2 分布式服务架构设计及技术实现
2.1 架构设计
当前信号处理系统通常具有高吞吐率、大数据量的特点,从而要求系统具备高速的数据处理能力。现在很多基于通用硬件的软件无线电平台(如GNU Radio+USRP组合、微软的SORA等),由于基于组件模型设计思想,仅仅只有通过优化CPU访问来提高运算效率,导致运算能力始终有限[11]。为解决运算性能瓶颈的问题,通过把各个计算任务分发到多个处理节点,充分利用计算机集群的计算机资源实现并行运算,才是比较有效的解决方案。
本文服务架构模型的基础思想是就是让业务组件以服务的形式存在于分布式系统中,服务间相对独立、自包含、可重用,业务流程及系统功能由服务组装和流程编排来实现[12]。为实现这种设计理念,本文的系统架构可大致分为核心框架、注册中心和应用客户端3个部分,如图4所示。
图4 架构原理
核心框架扮演“服务提供者”角色,为请求者提供服务[11]。核心框架不仅作为服务部署的容器,还实现了服务管理、状态监控、流程编排与执行、计算资源的负载均衡以及服务节点故障容错等功能。
注册中心采用ZooKeeper实现诸如统一命名服务、配置管理、分布式服务锁以及集群管理等功能[12]。
应用系统作为“服务请求者”,通过服务访问模块向注册中心查询服务信息,并调用服务框架中的相应服务。
服务作为实现不同功能单元的自包容实体部署于核心框架中,通过服务组合的方式实现彼此的交互及数据交换,最终实现应用系统的业务功能[13]。
2.2 负载均衡管理
为实现较高的资源利用率,本文采用前置负载计算的方式,在服务调用之前根据负载均衡策略,将任务请求转发到具体的服务框架节点上[14]。
首先,服务节点会定时将服务的运行信息(CPU占用率、线程数、服务调用次数、平均处理时间以及调用失败次数等)上报到注册中心的资源调度模块上。资源调度模块维护着一个负载信息表(LIT),该表存放着服务器ID、服务器IP、当前线程数Si、最大线程数max(Si)、负载参数Li、当前负载LSi以及最大负载max(LSi)等信息。
资源调度模块根据服务节点的运行信息,假设有4项:C1,C2,C3,C4,负载参数各自的权值为Ki,其负载参数计算公式为:
(1)
系统实时取得各服务器中的服务调用线程数Si,各服务器根据此数据与此服务器最大能接受的请求线程数的比值Si/max(Si)作为各服务器负载的初始数据。由于服务类型的不同,每个服务占用的服务器资源也有差别,Li作为周期性从各服务器收集到的负载信息,被用作纠偏因子,用来纠正负载信息的误差。集群中每个服务器最终负载计算公式为:
LSi=Si/max(Si)+KLi,
(2)
式中,K为Li的系数。
根据式(1)和式(2)计算出每个服务器最终的负载信息LSi,用LSi与服务器最大负载max(LSi)的比值来调整服务调用资源。采用服务调用平均时间最小为负载均衡策略,该比值越小,说明服务调用的平均时间越小,任务请求选择最小耗时的服务节点进行访问,从而达到负载均衡的目的。
3 应用实例及结果
为验证框架的有效性,基于该框架设计实现了1个并行处理2个业务流程的信号处理系统。如图5所示,其数据源是事先采集的数据文件,业务服务的处理结果通过通用数据处理服务推送给信号处理软件进行可视化界面展示。
图5 基于服务框架的验证应用系统
通用数据处理服务是本框架提供的基础服务(采用数据分发服务DDS实现),其功能是通过订阅分发机制[15],实现运算结果向用户界面、数据库和文件系统的订阅分发。该服务使得系统的界面显示或存储数据与数据处理业务服务解耦和[16],从而保证系统的数据处理性能不受影响。
服务管理软件能够(如图6所示)用可视化方式,把服务框架中已部署好的算法服务,按照实际业务流程连接组合起来,形成一组业务流程[17]。该软件是管理服务框架的核心软件,通过访问注册中心和服务容器可实现包括服务部署、注册、组合和状态监控等综合管理功能[18]。
图6 服务管理软件界面
在验证系统中准备了2台服务器,以验证分布式运行环境下框架性能。采用大小为1 GB的采样信号数据文件进行测试,设置服务处理每包数据缓存为100 KB。组合并配置业务流程1输出信号参数及频谱数据,业务流程2输出分析结果及星座图。具体测试环境为CPU E5-263 0 v3 2.40 GHz 8C(×2)、内存64 GB、操作系统Windows Server 2008 SP1,网络带宽100 MB/s。针对不同节点数(2个节点以上,等数量分别部署),不同线程数量,对该系统进行了性能测试,其测试结果如图7所示。
图7 算法性能测试结果
可以看出单一节点单一线程的应用计算耗时较长,但在开启多线程调用更多计算资源后[18],运算性能明显提升。这说明该分布式运行框架可通过扩展硬件资源,有效提高运行处理速度。
4 结束语
本文设计的分布式服务架构是一种针对信号处理领域的开放式体系架构,通过服务总线技术提高软件的复用度、系统的扩展性[19]。通过服务封装使工程师可以快速搭建基于计算机集群软件无线电系统,并通过分布式并行运算来提高系统运行效率[20]。实验结果表明,框架满足大数据应用处理需求,有一定的应用价值。