AICon 上海站|90%日程已就绪,解锁Al未来! 了解详情
写点什么

车联网服务 non-RESTful 架构改造实践

  • 2019-09-04
  • 本文字数:2598 字

    阅读完需:约 9 分钟

车联网服务non-RESTful架构改造实践

1. 导读

在构建面向企业项目、多端的内容聚合类在线服务 API 设计的过程中,由于其定制特点,采用常规的 restful 开发模式,通常会导致大量雷同 API 重复开发的窘境,本文介绍一种 GraphQL 查询语言+网关编排联合的实践,解决大量重复定制的问题。


早期与车厂合作过程中,基于高德已有的数据、引擎能力和一些较为重要的相关 CP 服务(如停车场、加油站、天气等),形成的在线服务协作模式是针对客户需求,采用 REST API 提供针对每个车厂、每个项目以及每个终端提供不同的 API 实现,然而数据核心独立服务实际上就有十余种,然而由于车线业务维护周期长,定制多,2-3 年下来,API 规模已达几百个,而且持续发散级增长,这给持续开发和维护带来不小挑战。


分解业务开发过程,无非两类工作,业务需求能力数据的获取和非业务诉求但是必不可少的如鉴权等通用化能力,当前来看,其实这两个问题是几乎所有业务团队都会遇到的问题,因此解决方案也基本类似,如服务聚合、流程编排、API 网关等。


本文简要介绍下车联网在线服务改造旧架构的一些实践。

2. 有关名词

  • GraphQL:GraphQL 既是一种用于 API 的查询语言也是一个满足数据查询的运行时。GraphQL 对 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

  • DSL:指的是专注于某个应用程序领域的计算机语言。又译作领域专用语言。不同于普通的跨领域通用计算机语言(GPL),领域特定语言只用在某些特定的领域。比如用来显示网页的 HTML,以及 Emacs 所使用的 Emac LISP 语言。

  • API 网关:API 网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API 网关封装了系统内部架构,为每个客户端提供一个定制的 API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。

3. 存在的问题

车线业务在线服务旧架构如下:



面临以下问题:


4. 改进

针对上述问题,主要从以下几个方面思考改进:


  • 服务能力原子化:目标是做稳,让上层通过组合实现业务需求;

  • 构建查询引擎:支持强大的查询组合能力,实现原子服务能力任意聚合和定制;

  • API 网关:对非业务数据能力需求进行抽象提供插件,实现插件编排。


下面分别介绍。

4.1 实现稳定、独立演进的原子能力服务

对已有的服务进行梳理,抽象出不同应该独立开发、部署演进的核心能力,对于引擎能力没有什么工作,重点是对于一些历史对接的外部 CP,主要实现以下目标:


  • 向上提供稳定接口,向下屏蔽底层复杂性(数据访问,多源差异);

  • 以位置为中心有机整合,构建完备原子化能力集合。


这部分工作主要是解决历史遗留的一些服务组合不合理,跟随业务过度定制的问题。

4.2 定制代码开发转换为定义查询语句

这里主要目的就是将服务聚合、定制逻辑等原来需要的代码开发转换为编写查询语言的方式实现,只需要编写出声明式的查询语句即完成服务发布,特性如下:


  • 向上提供标准化查询语言

  • 向下实现原子能力组合

  • 归纳业务共性,提炼定制模式,提升复用



本文选择 GraphQL 作为查询语言基础,然而,直接采用 GraphQL 有这样两个主要问题需要解决:


  • 数据查询 N+1 放大问题,直接采用 Fackbook 提出的 dataloader 来解决,原理是批量加缓存;

  • GraphQL 规范限制,一些定制难以实现,如:

  • 入参定制:如参数关联,类型转换等;

  • 输出格式:字段展现形式,如时间、经纬度等;

  • 配置表定制:主要是部分业务逻辑需要根据配置表定制,如深度返回字段等;

  • 模型连接:原子能力服务尽可能独立,同时也无法枚举定义模型关系,但是定制业务需求需要大量关联透出,减少业务请求降低延时,所以模型自由关联能力是必要的,由于本方案最终的查询控制在内部,对外暴露 REST API,因此不会关联自由度造成的难理解性并不是一个问题。


需要通过嵌入简单的 DSL 实现:


  • 内置和自定义函数功能;

  • 模型动态关联查询,上下文参数获取;

  • 可以方便扩展自定义函数。



这里嵌入 DSL 需要控制好度,因为 DSL 如果过于复杂,那么,使用者或者发布者无法快速写出查询的话,对比写代码提效就会打折扣,偏离本来的价值,所以基本原则是简单、可扩展。

5. 业务无关功能通过 API 网关插件配置化

由于之前每个 API 的定制开发基本所有功能混合在一起,能复用部分就是鉴权提供装饰器,常规性的响应格式定制提供一些工具函数,任何需求变更都需要变更代码,走发布流程,有了上面第一步的改造,这个步骤期望将非业务数据部分的定制功能抽象出处理链,每个处理节点提供多实现(包含通用和定制),通过数据库存储插件链实现编排。



车线业务由于鉴权方式需要根据客户定制,因此存在多样性,实现上是通过 Web 中间件实现多种鉴权插件:


  • HTTP 签名,参考这里:主要面向 ToB(车厂后台、合作方)的请求;

  • JWT 认证:主要面向车机、手机等终端;

  • API Key。


对于 API 网关来说,这些鉴权插件并没有什么不同之处,只是工程要处理一些定制场景,比如对于不同车厂的 JWK 管理刷新策略,JWT 验证策略等,具体需要根据业务诉求抽象建模,通过插件属性来实现配置控制。


另外,网关还实现了一些变换器,主要用于将 GraphQL 的输出变换为 REST API 接口透出,这一方面由于一些旧接口要做兼容支持,另外,一些重点客户的全球化架构背景下自己已经完全定义好了接口式样,目前主要实现了:


  • 入参变换:使用 REST API 参数填充 GraphQL 查询模板;

  • Header 变换:主要用于适配不同客户规范;

  • JSON 变换,使用场景如下:

  • 可复用标准接口,但是不同客户的响应结构规范不一致

  • 定制非标接口,需要对 GraphQL 输出进行转换


而插件的使用则通过控制台或 API 实现将插件配置信息存储于数据库中进行管理,使用时根据请求特征从 DB 中提取并缓存起来使用。


改造后的新架构如下:


6. 小结

通过上述改造,将车联网在线服务开发模式进行了升级,实现 API 控制台动态发布,大幅提升定制开发效率:


  • 提效开发:正交化原子能力编排,通过轻量级定义取代定制化代码开发;

  • 定制化开发占比下降 60%;

  • 单接口开发从 2-3 人日→2-3 人时。

  • 协议兼容:混合 REST 方案,对外提供标准协议、支持既有适配协议。


本文转载自公众号高德技术(ID:amap_tech)


原文链接


https://mp.weixin.qq.com/s?__biz=Mzg4MzIwMDM5Ng==&mid=2247484208&idx=3&sn=65ea6820942cd1ebfe1aaa322be75a56&chksm=cf4a5bd3f83dd2c52928dcbe534f029dc87cf4bc916af31cd7ff6fa54bfb16921c7419a1e34f&scene=27#wechat_redirect


2019-09-04 08:003861

评论

发布
暂无评论
发现更多内容

Kotlin + 协程 + Retrofit ,携程Android面试题

android 程序员 移动开发

JNI 与 NDK 入门(一),设计思想与代码质量优化+程序性能优化+开发效率优化

android 程序员 移动开发

Kotlin学习手记——注解(1),2021年字节跳动74道高级程序员面试

android 程序员 移动开发

Kotlin学习手记——注解,flutter下拉加载

android 程序员 移动开发

Kotlin协程它不香吗?,kotlin开发游戏

android 程序员 移动开发

Jetpack Compose和View的互操作性,这个回答让我错失offer

android 程序员 移动开发

Kotlin 的协程用力瞥一眼,大厂架构师经验分享

android 程序员 移动开发

Kotlin下的5种单例模式,一招教你看懂Netty

android 程序员 移动开发

Jetpack Compose 1,阿里P8架构师Android大厂面试题总结

android 程序员 移动开发

入选《2021爱分析·区域性银行数字化厂商全景报告》,网易云信助力南京银行打造转型标杆

网易云信

人工智能 金融行业

贝壳Flutter瘦身实践

贝壳大前端技术团队

flutter 瘦身 for web

LeakCanary源码学习二:LeakCanary,sw实战营文件下载

android 程序员 移动开发

Jetpack 之 LifeCycle 组件使用详解,android开发书籍

android 程序员 移动开发

Jetpack-在数据变化时如何优雅更新Views数据,ffmpeg音视频开发实战6下载

android 程序员 移动开发

Jetpact Compose状态管理简单理解,android设计模式的应用场景

android 程序员 移动开发

Kotlin-新版来了,支持跨平台!,android热修复实现

android 程序员 移动开发

Kotlin的自定义View,实现带弧形的进度条,androidjetpack详解

android 程序员 移动开发

博睿数据“智能体验运营,释放商业潜能”催化剂项目获TM Forum创新方案最佳实施奖

博睿数据

Kotlin 插件的落幕,ViewBinding 的崛起,音视频开发工程师

android 程序员 移动开发

最新消息!旺链科技加入庙行镇“乐创助企联盟”

旺链科技

区块链 产业区块链

Kotlin-源码里成吨的-noinline-和-crossinline-是干嘛的?

android 程序员 移动开发

Kotlin学习手记--泛型、泛型约束、泛型型变,天呐

android 程序员 移动开发

Jetpack组件---ViewModel 概览,android高级面试2020

android 程序员 移动开发

Kotlin-编程核心基石—高阶函数,androidrom定制

android 程序员 移动开发

Kotlin写一个解释器(2)---语法分析,安卓项目开发范例大全

android 程序员 移动开发

LeakCanary源码分析以及ContentProvider的优化方案,android移动开发

android 程序员 移动开发

Kotlin 协程和 Android SQLite API 中的线程模型,嵌入式系统工程师面试

android 程序员 移动开发

Kotlin系列三:空指针检查,万字长文总结Android多进程

android 程序员 移动开发

Kotlin(五)深入理解Kotlin类与接口,androidndk开发视频

android 程序员 移动开发

lambda表达式(3)-shawn,挑战大厂重燃激情

android 程序员 移动开发

Kotlin(1) lambda表达式和高阶函数操作符,android软件开发基础

android 程序员 移动开发

车联网服务non-RESTful架构改造实践_架构_云勤_InfoQ精选文章