APP下载

“天擎”预报服务客户端开发及接口应用技巧

2022-04-28董良淼李宇中覃月凤李莹蓝盈

气象科技 2022年2期
关键词:调用客户端服务

董良淼 李宇中 覃月凤 李莹 蓝盈

(1 广西壮族自治区气象台,南宁 530022;2 广西壮族自治区气象局,南宁530022;3 广西壮族自治区气象信息中心,南宁530022)

引言

气象大数据云平台“天擎”(CMADaaS)是全国气象综合信息共享系统(CIMISS)的功能升级和服务扩充版本。“天擎”平台不仅全面继承了CIMISS规范、数据种类和接口服务标准,还在数据质量、资料存储时间序列、数据处理时效等方面有显著提升。作为当前业务流程整体最优、数据服务统一高效的全国气象部门信息化系统的核心[1-2],自2020年12月业务试运行以来,“天擎”所展现出的“云+端”集约化、标准化、开放性的业务模态得到了气象预报服务人员的特别关注;如何将现有气象业务系统升级改造以便有效利用“天擎”平台优势,进而融入新一代气象大数据云平台,充分发挥“数算一体、统一高效”的应用服务能力,已成为各级气象业务应用研发单位努力的重点方向。

预报服务系统应用“天擎”服务的关键在于使用“接口”与大数据云平台交互[3-7]。按照融入标准,应用系统中所有涉及与用户交互的功能都由“端”来实现[1-2]:前端应用(如产品交互制作、业务交互操作等)接收用户交互指令,向“云”发出请求、并由后者完成相应动作(如任务调度、产品生成、数据存储等);获取“云”返回的处理结果后,“端”将进一步对输出数据进行加工处理,以提供或呈现用户所需的服务产品(文件、表格或图形图像等)。因此,对于大多数预报服务应用研发人员而言,“天擎”服务接口的掌握程度和应用能力就决定了系统模块改造融入云平台的效率水平。

本文以气象行业数据分析和应用研发中广泛使用的Python(3.x版本)语言[8-10]环境为例,探讨“天擎”大数据云平台服务环境下适用于预报服务客户端系统开发的服务接口应用技巧,作为官方推荐方法和客户端开发工具(SDK)的有益补充,供云平台迁移融入研发人员参考。

1 平台服务接口特点及本地应用存在的问题

服务接口(Service Interface)是系统间数据交换的边界。采用接口机制能够实现系统核心服务端与应用端的业务逻辑隔离、降低模块间相互依赖、减少构件耦合度、提高单元内聚性,从而有效提高系统整体灵活性、可维护性和可扩展性。服务接口是一种中间件,可封装各种网络通信协议、确保功能可跨平台使用。服务接口同时也是安全屏障,通过容纳验证、授权模块可充当系统的信任边界、满足特定使用者的不同安全需求。服务接口还可实现缓存、有效缩短响应时间并减少I/O带宽消耗;在一组负载均衡处理节点上部署多个服务接口实例,可满足系统高可用性和故障容错要求。可以说,基于接口中间件的数据存取访问功能“接口化”,是现代信息支撑平台提供多用户、高并发、高安全可靠性应用服务的最主要方式[11-16]。

1.1 服务接口特点

“天擎”服务接口在沿用(兼容)气象数据统一服务接口(MUSIC)的CIMISS标准基础上进行了功能扩展和安全性扩充,减轻了应用服务升级改造和迁移融入的程序代码修改调整幅度。相比较CIMISS接口,“天擎”服务具有以下几个方面突出特点:①增加了安全认证模块,“天擎”接口采用了基于查询参数+时间戳的数字签名加密(AK/SK)认证方式,显著提高了数据服务的安全性,可有效防止非法用户伪造查询请求、篡改检索参数甚至尝试网络渗透攻击等问题。与CIMISS查询相比,其直观差别体现在接口检索URL中出现了时间戳(time-stamp)、本机随机数(nonce)和数字签名(MD5 sign)这3个参数。②采用负载均衡集群和分布式缓存技术,服务性能显著提升。作为直接支撑“云+端”数算一体化应用的新一代平台,“天擎”每一个重要功能模块都依托高性能+高可用性的Linux集群系统来实现,采用了分布式内存缓存数据库(Redis)、高性能流式处理并行框架(Storm/Spark)、高吞吐量消息系统(Kafka/RabbitMQ)等能够有效降低数据传输处理时延、显著提升数据服务性能的成熟集群服务技术。测试表明,在高并发场景下“天擎”访问时效明显高于CIMISS,部分服务性能优于CIMISS平台10倍以上[1-2]。③提供更丰富的数据序列化输出格式,“天擎”接口提供多种可选数据返回格式。其中,“内存对象”和“数据文件”这两种返回格式只在客户端开发包中提供,适用于大数据量获取计算;而“序列化字符串”适用于数据快速解析和前端显示应用,是预报服务应用最常用到的接口数据格式。与早期CIMISS接口相比,“天擎”可返回序列化字符串除XML/HTML/TEXT类型外还新增了JSON/JSONP这两种新的数据格式。④强化系统接口服务资源占用管控,为保障实时业务优先执行,“天擎”平台强化了对系统资源的占用管控,除优化任务调度和均衡负载外,还会监视分析算法模块和客户端对系统资源的占用情况,对超用、滥用资源现象进行限制。针对用户的接口调用请求,管理模块设置了MUSIC接口访问频次限制:个人/科研用户的限额大约是400~500次/min、2000~2500次/h左右。一旦超出调用上限,系统将拒绝执行查询操作并返回超限额错误信息,以确保系统资源合理分配。⑤服务接口数量种类进一步丰富,目前已配置可用的系统内置访问接口有300余个、供接口选择的检索条件参数近120个,接口使用场景已涵盖绝大多数预报服务应用需求。

1.2 服务接口应用问题

在系统服务得到全面强化升级的同时,“天擎”接口在本地应用过程中也存在一些潜在问题:①服务接口安全认证机制使得用户应用技术门槛有相当程度的提升、非计算机专业出身的预报服务人员在开发接口调用程序时普遍遇到困难;其次,服务调用会出现一些原CIMISS环境下不常出现的查询失败等问题;②新的接口调用限额机制对需要对代码进行频繁修改调试的开发过程不利,容易触碰上限、从而影响到“天擎”平台的研发应用体验;③丰富的数据接口和查询输出参数在某种程度上也造成了选择困难,难以把握哪种接口方式才是特定应用最便捷高效的选择。

2 服务接口调用技巧及应用开发实现

丰富的服务接口为“天擎”数据服务应用开发提供了多样化的可能。以下结合广西省级平台系统业务试运行近一年来的测试运维和应用迁移研发经验,从气象预报服务人员的技术视角给出几个客户端应用开发暨服务接口调用技巧。

2.1 简化服务接口调用

官方提供的签名认证调用基于一系列SDK开发包,在编写调用代码时须首先引入(import)cma.music.DataQueryClient类、生成client客户端对象并根据需要初始化各种客户端参数,然后再使用该对象的特定方法、指明方法需调用的接口名称(interfaceId),最后执行方法获取返回结果数据。习惯过程式开发的非计算机软件专业气象预报服务人员对上述“面向对象”的程序设计理念和代码执行过程难免有些困惑,无形中拔高了“天擎”服务接口使用难度。为解决上述难题,可采用基于Python 3函数的接口调用方案。

(1)构造两个函数。分别用于生成加密数字签名(getSign)和组装加密检索URL(createApiUrl)。其中,前者是将官方开发包DataQueryClient模块类方法getSign(self,signParams)简化成普通函数(去除self参数,用in操作符替代has_key()函数、并对signParams.keys()函数返回值做强制类型转换,以适应Python 3编码环境);后者则是对官方包中的getConcateUrl类方法进行函数式改造,用来根据“天擎”接口查询参数生成客户端(浏览器)完整查询url链接,完整代码如下:

def createApiUrl(params,baseUrl,pwd):

paramsUrl = baseUrl

for key in params:

paramsUrl += "%s=%s&" %(key,params[key])

timestamp = str(int(round(time.time()* 1000))) #生成查询时刻的时间戳

nonce = str(uuid.uuid1()) #生成本次查询对应的本机随机数

params['timestamp']= timestamp

params['nonce']= nonce

params['pwd']= pwd #用户密码只出现在加密计算中,不能出现在查询url中

sign = getSign(params) #调用数字签名函数,生成查询对应的AK/SK加密认证数字

paramsUrl += "timestamp=%s&nonce=%s&sign=%s" %(timestamp,nonce,sign)

#---将接口基本查询信息(baseUrl)拼接上时间戳timestamp、随机数nonce、加密认证签名sign后即成为完整查询链接---

return paramsUrl

上述函数需提前引入uuid和hashlib这两个Python 3标准内置模块。

(2)将服务节点名serviceNodeId、调用接口名interfaceId、用户名userId以及接口返回的序列化字符串格式名dataFormat等参数,与其他接口服务查询参数一起在程序中赋值,并存储在一个字典型(dict)变量params中,而官方调用方案中上述参数的获取相对分散,部分设置需从配置文件client.config中读取、另有个别参数则隐含反映在对客户端对象的不同方法调用过程中。

确定查询参数名称及其具体取值的方法是,在气象大数据云平台集成界面(PORTAL网站)的“接口测试工具”页面手选接口账户、数据类别、数据名称和要测试的服务接口,并根据页面提示信息补充所需接口参数、选择返回值类型,最后点选“生成并执行URL”以解析服务端构建出的完整的查询URL信息(图1)。该查询URL串中前面包含“天擎”平台服务节点接口查询标识的“http://10.*.*.*/music-ws/api?”部分为baseUrl段,其后每个查询参数都体现为一个以“=”相连接、以“&”为间隔的“键-值”参数对。以按时间段和经纬度区域查询站点地面气象要素的接口URL为例,Portal网站构建出的完整查询信息是:

图1 使用“天擎”PORTAL网站构建接口服务完整查询URL信息

http://10.159.90.120/music-ws/api?

serviceNodeId=NMIC_MUSIC_CMADAAS&userId=USR_GCC_LYZ&interfaceId=getSurfEleInRectByTimeRange&dataCode=SURF_CHN_MUL_HOR&elements=Station_Name,Year,Mon,Day,Hour,PRE,TEM,PRS,RHU&timeRange=[20210830000000,20210830010000]&minLon=104&maxLon=115&minLat=20&maxLat=27&dataFormat=text×tamp=1630399491741

&nonce=fb27ce93-fc82-472e-8b4a-8e85e3882855

&sign=F58C7B2D70523102ADFA5F7960DD53FC

除第一行“基础信息”段和最后两行“时间戳、随机数和数字签名”段,中间以下划线标识部分中的每一组以“=”相连、“&”为间隔的“键-值”参数对都须显式赋值到params变量中,示例如下:

params = {'serviceNodeId':'NMIC_MUSIC_CMADAAS',

'userId': 'USR_GCC_LYZ',

'interfaceId': 'getSurfEleInRectByTimeRange',

'dataCode': 'SURF_CHN_MUL_HOR',

'elements': 'Station_Name,Year,Mon,Day,Hour,PRE,TEM,PRS,RHU',

'timeRange': '[20210830000000,20210830010000]',

'minLat':'20',

'minLon':'104',

'maxLat':'27',

'maxLon':'115',

'dataFormat':'text',

}

为避免服务端接口调用URL解码程序误解查询参数信息,建议所有赋值的“key:value”参数严格复现Portal接口测试工具给出的字符大小写特征。

(3)以查询参数params来调用createApiUrl函数生成接口检索URL,然后推荐采用Python第三方requests库(或异步框架httpx库)对该URL执行HTTP请求操作,即可正常获取“云”服务端返回的查询结果信息,用以开展客户端应用后续加工处理和产品输出工作。程序流程如下:

……(程序初始化)

baseUrl ='http://' + serviceIp + '/music-ws/api?' #初始化服务接口基础URL

params = {…… } #设定接口查询参数

queryUrl = createApiUrl(params,baseUrl,pwd)#生成完整的服务接口加密检索URL

res = httpx.get(queryUrl) #用通用查询框架执行标准HTTP请求,获取返回信息

……

CMADaaS_Data_Proc() #数据后处理及产品输出

……

上述函数式“天擎”服务接口调用方式可将官方SDK限定的一系列客户端操作处理过程缩减到一个只有数十行代码的脚本文件中集约化实现,显著降低云平台数据接口服务应用门槛。

2.2 提升接口服务调用成功率

广西省级“天擎”平台业务试运行初期,接口应用测试时不时会出现访问失败情况(返回“CLUSTERDOWN The cluster is down”错误提示、或查询超时无任何信息返回);而短时内再重复同样查询,故障往往又消失不见、重新可以获取正常结果数据。为解决上述偶发性接口查询访问迟滞问题、保证服务调用成功率,可在代码中引入“超时重试”机制,requests包本身就支持重试功能,使用前只需对requests.adapters.HTTPAdapter 进行相应设置即可(代码略);另一种更好的方法是使用Python包装器、借助功能更为强大的第三方“重试”模块 tenacity(retry)来包装正常的接口处理函数,无需更改原函数内部代码就可增添超时重试功能:

from tenacity import retry ……

#---包装3个重试条件:①出现“连接超时”异常时才进行重试;②等待3 s后才重试;③重试过3次、或时长超过10 s后就不再重试---

@retry(retry = retry_if_exception_type(requests.exceptions.Timeout), wait = wait_fixed(3), stop=(stop_after_delay(10)|stop_after_attempt(3)))

def CMADaaS_DayProc_Retry(datestr): # 带有“重试机制”的包装器函数

CMADaaS_DayProc(datestr) # 原处理函数

2.3 改善接口返回数据处理效率

“天擎”平台服务提供了多种可选数据返回格式,其中新增的JSON格式常被当作“瘦身版XML”、在很多应用场景下都成功取代了XML数据。更深层次的原因是,JSON 数据格式完美对应了Python列表(list)和字典(dict)类型表达[17],尤其是“字典”这种基于散列表存储的高效数据结构,它的“键-值”映射检索时间效率近似于O(1),无论字典或集合元素数量增长到多巨大,所耗费的查询时间几乎可忽略不计,可完美适配伸缩度极大的数据交换场合。

Python处理JSON类型数据非常简单,只需将返回结果提交给JSON内置对象的loads方法加载、解析,就可得到一个容纳全部记录信息的多重嵌套dict型对象;而在这个对象中,每一组记录数据段都能直接通过相应的“键名”来迅速获取。样例如下:

import json #引入Python标准内置JSON格式数据解析处理模块

……

res = webapi.get(newUrl) #向“天擎”服务接口查询站点观测数据

result = json.loads(res.text) #使用JSON模块loads方法再次加载返回数据

#---循环提取查询结果数据中的每一个观测站的要素信息---

for StaRecoder in result['DS']: #'DS'键值对应所有测站的观测记录列表

strStationNum = StaRecoder["Station_Id_C"] #台站站号

fStationPress = float(StaRecoder["PRS"]) #气压

……

若“天擎”接口返回数据是TEXT类型的序列化字符串,上述解码提取观测站要素信息的过程就会变成繁复多次的行、列、序号“拆分-解析”操作,不仅效率低下,而且由于缺乏明确的要素名与要素值对应关系,代码可读性差、程序易出错,软件质量无法保证。经简单对比,处理基于JSON格式的7~8万个测站记录比其它格式处理代码快0.3%~1%左右,看似微不足道,但若一并考虑系统长期运行以及代码的可读性、可维护性,效果相当可观。

2.4 合理规避接口服务访问限制

针对接口调用频次限制,虽可通过向系统管理员申请、适当提高特定用户访问限额来解决,但在应用端程序调试中避免突破用户限额还是应作为普遍性“规则”尽量遵守。通过合理选择服务接口、提高代码处理技巧可以有效缓解访问限额需求:①应尽可能合并查询检索条件,按“时段”而非按“时间/时次”、按“区域/站号段”而非按“台站号”来选择合适的服务接口,以便用尽可能少的接口调用次数来获取所需全部记录数据;②细粒度的时次、台站级记录筛选工作可对本机内存中的返回数据集执行二次操作来完成;③对调试期间尚未完善的接口服务调用部分,可适当添加类似“sleep(3)”休眠语句来避免频繁访问造成限额耗尽。

例如:某应用端服务需要统计近6 h广西境内自动气象站的累计雨量值,如果选用“按时间”或“按站号段”服务接口执行检索,至少需要12次接口调用(共6个时次、每个时次至少2个站号段);而改用“按时间段、经纬度范围”服务接口执行检索,设置好最近6 h的时段参数和广西区域的起止经纬度参数,只需要1次检索即可取回全部观测记录。再综合采用JSON型数据快速解码、定位功能,后续筛选和统计工作也能在本地高效完成。

3 结论与讨论

作为当前全国气象信息化平台的核心,“天擎”将成为今后支撑气象部门业务运行、科学研究、新技术开发的共享资源中心和安全空间,助力气象事业高质量协同创新发展。显然,促进平台高效安全使用、推动业务系统深度融入应用,仅靠信息网络专业人员在“云”端努力是远远不够的,气象预报服务及科研人员也需要在应用“端”充分发挥自身优势;从这个技术视角出发,可采用以下接口应用开发技巧:①用函数式编程简化“天擎”接口服务调用过程;②在大数据云平台服务“接口化”背景下,引入“超时重试”机制可进一步提高服务接口调用成功率;③以JSON格式作为预报服务应用接口的首选返回数据格式,信息解析效率更高、代码可维护性更强;④合理选择服务接口可显著缓解访问限额矛盾。

目前,“天擎”平台及其服务接口仍在持续升级改进,后续优化完善可从以下方面综合考虑:①对服务接口进行归类整理、对接口的不同适用场景及其性能差异予以描述,可指导基层正确选用合适的服务方式、提升应用体验;②随着系统软硬件性能的升级扩充,适当放宽系统资源(服务接口调用)管控限额能够更好地支撑采用多协程/线程/进程并行执行的高性能客户端应用程序在气象大数据云平台环境下运行;③对云服务端算法进一步开源共享,有利于技术人员更加深入理解“天擎”运行机制和服务理念,促进平台数据高效安全使用、推动业务系统深度融入融合。

猜你喜欢

调用客户端服务
核电项目物项调用管理的应用研究
如何看待传统媒体新闻客户端的“断舍离”?
服务在身边 健康每一天
服务在身边 健康每一天
服务在身边 健康每一天
LabWindows/CVI下基于ActiveX技术的Excel调用
县级台在突发事件报道中如何应用手机客户端
孵化垂直频道:新闻客户端新策略
大枢纽 云平台 客户端——中央人民广播电台的探索之路
招行30年:从“满意服务”到“感动服务”