导读

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

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

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

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

有关名词

  • GraphQL:GraphQL既是一种用于API的查询语言也是一个满足数据查询的运行时。GraphQL对API中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让API更容易地随着时间推移而演进,还能用于构建强大的开发者工具。
  • DSL:指的是专注于某个应用程序领域的计算机语言。又译作领域专用语言。不同于普通的跨领域通用计算机语言(GPL),领域特定语言只用在某些特定的领域。 比如用来显示网页的HTML,以及Emacs所使用的Emac LISP语言。
  • API网关:API网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。

存在的问题

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

面临以下问题:

改进

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

  • 服务能力原子化:目标是做稳,让上层通过组合实现业务需求;
  • 构建查询引擎:支持强大的查询组合能力,实现原子服务能力任意聚合和定制;
  • API网关:对非业务数据能力需求进行抽象提供插件,实现插件编排。

下面分别介绍。

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

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

  • 向上提供稳定接口,向下屏蔽底层复杂性(数据访问,多源差异);
  • 以位置为中心有机整合,构建完备原子化能力集合。

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

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

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

  • 向上提供标准化查询语言
  • 向下实现原子能力组合
  • 归纳业务共性,提炼定制模式,提升复用

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

  • 数据查询N+1放大问题,直接采用Fackbook提出的dataloader来解决,原理是批量加缓存;
  • GraphQL规范限制,一些定制难以实现,如:
  1. 入参定制:如参数关联,类型转换等;
  2. 输出格式:字段展现形式,如时间、经纬度等;
  3. 配置表定制:主要是部分业务逻辑需要根据配置表定制,如深度返回字段等;
  4. 模型连接:原子能力服务尽可能独立,同时也无法枚举定义模型关系,但是定制业务需求需要大量关联透出,减少业务请求降低延时,所以模型自由关联能力是必要的,由于本方案最终的查询控制在内部,对外暴露REST API,因此不会关联自由度造成的难理解性并不是一个问题。

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

  • 内置和自定义函数功能;
  • 模型动态关联查询,上下文参数获取;
  • 可以方便扩展自定义函数。

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

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

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

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

  • HTTP签名,参考这里:主要面向ToB(车厂后台、合作方)的请求;
  • JWT认证:主要面向车机、手机等终端;
  • API Key。

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

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

  • 入参变换:使用REST API参数填充GraphQL查询模板;
  • Header变换:主要用于适配不同客户规范;
  • JSON变换,使用场景如下:
  1. 可复用标准接口,但是不同客户的响应结构规范不一致
  2. 定制非标接口,需要对GraphQL输出进行转换

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

改造后的新架构如下:

小结

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

  • 提效开发:正交化原子能力编排,通过轻量级定义取代定制化代码开发:
  1. 定制化开发占比下降60%;
  2. 单接口开发从2-3人日→2-3人时。
  • 协议兼容:混合REST方案,对外提供标准协议、支持既有适配协议。

原文链接
本文为云栖社区原创内容,未经允许不得转载。

车联网服务non-RESTful架构改造实践相关推荐

  1. dubbo k8s 服务发现_服务化改造实践(二)| Dubbo + Kubernetes

    原标题:服务化改造实践(二)| Dubbo + Kubernetes 摘要: "没有最好的技术,只有最合适的技术."我想这句话也同样适用于微服务领域,没有最好的服务框架,只有最适合 ...

  2. dubbo k8s 服务发现_服务化改造实践(二)| Dubbo + Kubernetes-阿里云开发者社区

    "没有最好的技术,只有最合适的技术."我想这句话也同样适用于微服务领域,没有最好的服务框架,只有最适合自己的服务改造.在Dubbo的未来规划中,除了保持自身技术上的领先性,关注性能 ...

  3. 如何删除网关的session_微服务安全认证架构是如何演进而来的?坐好小板凳一起来听一听...

    之前有同事问为何要用基于JWT令牌的认证架构,然后近期又有童鞋在后台留言问微服务安全认证架构的实践,因此我决定花两篇推文来解答一下.为了答好这个话题,我们先来看看微服务的安全认证架构是如何演进而来的, ...

  4. 《微服务架构与实践》读书笔记

    第一章 单块架构及其面临的挑战 经典的三层架构: 表示层:聚焦数据显示和用户交互: 业务逻辑层:聚焦业务逻辑处理: 数据访问层:聚焦数据的存储和访问. 传统的单块架构应用的表现: 功能集中.代码和数据 ...

  5. vivo亿级微服务 API 网关架构实践

    一.背景介绍 网关作为微服务生态中的重要一环,由于历史原因,中间件团队没有统一的微服务API网关,为此准备技术预研打造一个功能齐全.可用性高的业务网关. 二.技术选型 常见的开源网关按照语言分类有如下 ...

  6. 系统部署文档_惊喜!Alibaba架构师终于发布“微服务架构与实践”文档

    前言: 对于微服务架构的概念,相信大家应该都不陌生,无论使用 Apache Dubbo.还是 Spring Cloud,都可以去尝试微服务,把复杂而庞大的业务系统拆分成一些更小粒度且独立部署的 Res ...

  7. pb 执行存储过程带参数_PB级海量数据服务平台架构设计实践

    基于PB级海量数据实现数据服务平台,需要从各个不同的角度去权衡,主要包括实践背景.技术选型.架构设计,我们基于这三个方面进行了架构实践,下面分别从这三个方面进行详细分析讨论: 实践背景 该数据服务平台 ...

  8. 单体应用微服务改造实践

    [摘要] 本文介绍了如何采用一种持续迭代演进的方法将单体应用改造为微服务应用.重点介绍了如何通过自动测试服务和网关服务来构造持续迭代演进的基础设施.文末介绍了如何使用CSE更好的完成这个过程. 微服务 ...

  9. 一个近乎完美基于Dubbo的微服务改造实践

    网易考拉(以下简称考拉)是网易旗下以跨境业务为主的综合型电商,自 2015 年 1 月 9 日上线公测后,业务保持了高速增长,这背后离不开其技术团队的支撑. 微服务化是电商 IT 架构演化的必然趋势, ...

最新文章

  1. plotly基于dataframe数据绘制柱状图(bar plot)
  2. python不能处理excel文件-别以为Python的pandas不能处理非规范Excel数据
  3. python 环形链表
  4. 编码压缩新思路:面向QoE的感知视频编码
  5. mysql is null走索引_Mysql数据库索引IS NUll ,IS NOT NUll ,!= 是否走索引
  6. 【软件设计师】2020-08-06
  7. eureka 集群失败的原因_Eureka集群的那些坑
  8. java try的用法_Java中try、catch的使用方法
  9. mysql获取当前时间,前一天,后一天
  10. 草蟒python汉化版_草蟒首页、文档和下载 - Python 汉化版 - OSCHINA - 中文开源技术交流社区...
  11. Froala 编辑器设置表格页脚
  12. Word怎么在空白处添加下划线
  13. InnoDB一棵B+树能存多少行数据?为什么要用B+树?而不是其他树?
  14. 接口调用正常却返回404
  15. 达内python培训靠谱吗
  16. 活动时长计算尝试用Lambada 实现责任链的代码优化
  17. 焊接过程计算机模拟研究,焊接过程的数值模拟
  18. html精灵图坐标如何确定,CSS实现精灵图与字体图标
  19. 科技新品 | 第一视角沉浸式飞行无人机;全球首款可折叠165英寸电视;新一代增强现实智能眼镜...
  20. Ubuntu下安装mer-gx系列相机驱动

热门文章

  1. java io 缓存读取_Java 文件IO写入读取四种方法
  2. css3正方体选中父层 子层解体_CSS3 :nth-child(n)选择器 匹配属于其父元素的第N个子元素...
  3. android studio聊天跳转_Android 第三方应用跳转到QQ进行聊天
  4. go 连接服务器 并存放图片_基于 Go 语言开发在线论坛(二):通过模型类与MySQL数据库交互...
  5. 【LeetCode笔记】215. 数组中的第K个最大元素(Java、快排、堆排、并发快排)
  6. cuda卸载_Ubuntu18.04英伟达显卡驱动、Cuda安装
  7. matlab中右三角形方向,《有限元基础教程》_【MATLAB算例】4.7.1(2) 基于3节点三角形单元的矩形薄板分析(Triangle2D3Node)...
  8. php字符长度函数漏洞 ctf,CTF中常见php-MD5()函数漏洞
  9. 先出报表还是先计提所得税_一道大综合题搞定“与子公司的内部交易合并报表抵销分录”的逻辑...
  10. opencomm在c语言中的作用,使用OpenMPI从Fortran调用C语言