开篇 | 模块化与解耦式开发在蚂蚁金服 mPaaS 深度实践探讨

本文主要是介绍开篇 | 模块化与解耦式开发在蚂蚁金服 mPaaS 深度实践探讨,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

今天很高兴有机会给大家分享支付宝的开发经验,具体的内容将分成三个部分展开:

  1. 支付宝架构设计与发展;
  2. 支付宝的敏捷发布与稳定性保障;
  3. 支付宝架构的优势与赋能。

1. 支付宝架构设计与发展

首先看一下支付宝的发展历史,最开始支付宝只是作为支付功能支持淘宝业务,后来逐步发展成为独立的 App,并从简单的支付功能衍生出转账、水电煤支付等生活服务,现在的支付宝已经成为一个多应用生态的超级 App。生活中你想做任何事情,几乎都可以在支付宝上实现。

_1010_V3_final_001

截止目前,支付宝实名注册用户已经超过了 8 亿,日活数亿。在研发上面,仅 Android、iOS 客户端开发人员近千人,客户端代码行数超过了数百万行,Android 版本支付宝的工程数业已近千个,每个工程都有独立的开发 owner 负责某一个具体的模块。虽然工程师团队及工程量越发庞大,支付宝依旧能够做到日发布的频率以确保业务快速迭代。即使业务功能日益复杂,但 App 闪退率仅 0.01%。

那么,为了达到这样的业务指标,我们做了什么呢?

随着互联网的应用场景进一步丰富,用户对交互、体验的要求也越来越高。由此,我们需要在 App 的各方面下足功夫,比如客户端的运行流畅性最大努力降低电量流量的能耗

我们最近在推的一个项目便是支付宝的网络统一:在客户端建立一条与服务端的长连接,通过这个长连接通道进行网络通讯协议的封装,进行业务网络请求的通讯。一般情况下咱们每次发网络请求都会建立一个 HTTP 三次握手,这样会有一定的网络延迟和没必要的流量浪费,支付宝为了解决这样的问题做了网络统一库,提升了网络通讯效率。

此外,支付宝针对扫一扫功能的性能优化,不仅体现在扫码的及时反馈,也包括对于二维码的识别范围相对竞品会更广。同时,国内有著名手机厂商直接在自身的手机系统中集成了支付宝的扫一扫组件,作为系统默认的扫码能力,这从侧面反映了支付宝在细分领域的优势。

再来谈谈支付宝如何应对复杂的使用环境:我认为最典型的复杂使用环境的即手机没网的情况下支付宝如何做到顺利打开付款码?

一般情况下,出于安全考虑,付款码仅在几个小时内有效。但支付宝内置了阿里大安全部门提供的黑匣子,通过黑匣子能够有效保障移动端安全,因此即使你在弱网环境或长时间未开启付款页面,支付宝依然能够顺利完成支付。

_1010_V2_005

接下来,我们来了解看看这一系列性能优化的背后,技术架构是如何设计和实现的。

_1010_V2_006

这是支付宝客户端的总体架构图,从下往上看:

  • 最底层是支付宝框架的容器层,包括类加载资源加载和安全模块;
  • 第二层是我们抽离出来的组件层,包括网络库,日志库,缓存库,多媒体库,日志等等,简单说这些是一些通用的能力层;
  • 第三层是我们定制的框架层,这是关键部分,是我们得以实现上千人,上千多个工程共同开发一个 App 的基础;
  • 第四层是基于框架封装出来的业务服务层;
  • 第五层便是具体的业务模块,其中每一个模块都是一个或多个具体的工程。为了搭建超级 App 的并行开发模式,我们必须保证模块与模块之间的低耦合,实现插件式灵活的开发,因此整体业务分为了上千多个工程。

上千个工程低耦合逻辑上是没有问题,比如你开发网络库工程,他开发扫一扫工程,我开发动态发布工程,咱们代码可以完全没有耦合性,但又能如何做到相互依赖?

_1010_V2_007

支付宝移动端的技术架构设计灵感便来源于 Java 的 OSGi 模块化思想:内部对每个工程都叫做 bundle 工程,每个 bundle 有相应代码和开发资源。实际上,每个 bundle 工程都是一个 apk 工程,只是比 apk 多了一个 bundle 描述文件。这三个东西非常关键,回到刚才说的工程与工程之间存在依赖,对方要如何引用?

工程之间的依赖关系只有两种:

  • 第一种:代码层面的依赖(即我需要调用对方写的代码);
  • 第二种:资源层面的依赖(即我需要引用对方定义的资源,比如布局或者样式等)。

从代码转成可运行的程序可以简单分成两个时期:

    1. 编译期
    1. 运行期

在支付宝的架构里,编译参与的部分是和运行期参与的部分是分离的:编译期使用 bundle 的接口包,运行期使用 bundle 包本身。bundle 的接口包是 bundle 包的一部分,即刚才说的 bundle 的代码部分。bundle 的资源包同时打进接口包,在编译期提供给另一个 bundle 引用。

传统模式中,依赖的 SDK 既参与编译,也参与运行。我们定制了编译流程,使得编译与运行的依赖内容分离。

问题来了,如何保证 App 在运行期代码和资源不缺失呢?支付宝有一个容器工程(即 portal 工程),该工程中配置了所有 bundle 包的引用,在 portal 中把所有 bundle 包本身合并,最终形成 apk 包本身。这样 bundle 引用 bundle 的接口包,仅参与编译,最终所有 bundle 在 portal 中汇集,这样编译期没问题,运行期也没问题,从而实现了工程与工程之间依赖的解耦。

完成工程间的解耦,那么如何解决代码之间存在的强依赖关系?

举个简单例子,你引用了某个 Bundle 接口包中类 A 里的方法 m,这个方法 m 因为一些业务原因需要变动,那么你就被迫需要同时改动代码。针对这样的问题,我们通过框架层面提供的微服务来解决,简单来说,即面向接口编程:具体实现与调用的接口分离,因此只要保证接口包不变,具体实现可以由开发者任意调整而不影响使用方。

以上是代码与代码之间的解耦,接下来再看看业务与业务之间的解耦:

假设某个业务首页一开始叫 ActivityA,后来因为业务优化导致这个业务首页的入口被改,那么跳转到业务首页的使用方同样跟进改动。同理,对于 H5 前端来说,在不同平台想要跳转到同一个业务,但这两个平台跳转的入口是不一样的,前端怎么跳转?支付宝是通过框架层面的微服务和微应用来实现解耦的:

_1010_V2_008

微服务是通过面向接口开发、引用,然后在框架中动态注册的方式来实现的接口隔离解耦。
微应用是通过预先定义好一个数字来唯一标识一个业务模块,然后动态注册到框架中,具体这个业务模块中有什么,入口叫什么,完全由开发负责人自己决定。
所有框架注册的微应用微服务最终会在框架启动中动态加载。

那么大家是否会有疑问,支付宝这么多工程师团队和工程量,微服务微应用之间仍需要协同配合,那么支付宝发布一个版本是不是很麻烦?

2. 支付宝的敏捷发布与稳定性保障

传统的开发模式下大家势必互相影响,假如你提交的代码闪退了或者业务异常了,那么你业务关联的开发测试一定会受到影响,一般我们称这样的开发模式是「串行开发,互相等待」。而支付宝的工程解耦,代码解耦能给工程效能带来多大的效益?接下来我们来聊一聊支付宝的「并行开发模式」。

支付宝每次发布一个版本,都是由若干个 bundle 工程组成。若干个 bundle 工程合并在一起叫基线,每次发布版本之后,参与下一个版本迭代的同学都基于这个稳定的基线做独立的开发。而之所以能够支持独立开发,归功于我们介绍的工程解耦代码解耦

比如这张框架图,余额宝业务、ofo 小程序、蚂蚁森林、网络库等可以同时开发测试完成之后进入某一个大版本发布即可,如果存在依赖关系,只需要找和自己相关同学一起进发布,正因为如此支付宝做到了每天都有很多业务进基线,每天都在同时迭代业务。

_1010_V2_011

既然发布确保了效率,那么支付宝又是如何保证发布稳定性的?
传统的开发模式是:开发测试、全量发版,然后进入下个版本的迭代,继续开发测试修 bug、全量发版。这样做有几个缺点:

  1. 如果测试阶段未发现缺陷,很可能导致线上用户出现大规模异常;
  2. 出现大规模异常没有修复能力,造成用户损失;
  3. 随着业务的迭代,业务越来越多,功能越来越复杂,卡顿现象频出,用户体验变差;
  4. 关键业务监控不到位,不知道用户怎么使用 App,或者出现业务异常无感知,传统的开发模式里开发测试的比重基本上占到了 90% 甚至 100%。

而对于支付宝来说,开发测试仅占整体工程量 25%,以下即相应的工作拆解:

_1010_V2_012

3. 支付宝架构的优势与赋能

最后,支付宝所有在移动端开发方面的技术积累和架构实践,已经作为蚂蚁金服金融科技的一部分对外开放,即我们今天见到的蚂蚁金服 mPaaS。mPaaS(Mobile Platform As A Service),源于支付宝 App 的移动开发平台,为移动开发、测试、运营及运维提供云到端的一站式解决方案,能有效降低技术门槛、减少研发成本、提升开发效率,协助企业快速搭建稳定高质量的移动 App。

_1010_V2_016

秉承着「给世界带来小而美的变化」的理念,我们通过 mPaaS 帮助 12306 这样的国民级 App 重构了客户端,使得大家可以用上一个好的体验的 App 进行出行购票,用 mPaaS 这样成熟的底层框架搭建一个 12306 仅需要 2-3 个月的时间。除了 12306 还有支付宝香港版,广发银行发现精彩客户端,同样在短短几个月的时间内便完成了业务重构。

蚂蚁金服 mPaaS 客户案例

那么,对你来说,模块化与解耦式开发是否还有更好的方式?欢迎留言与我们一起探讨。

关注我们公众号「mPaaS」,获得第一手 mPaaS 技术实践干货

这篇关于开篇 | 模块化与解耦式开发在蚂蚁金服 mPaaS 深度实践探讨的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/261843

相关文章

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

五大特性引领创新! 深度操作系统 deepin 25 Preview预览版发布

《五大特性引领创新!深度操作系统deepin25Preview预览版发布》今日,深度操作系统正式推出deepin25Preview版本,该版本集成了五大核心特性:磐石系统、全新DDE、Tr... 深度操作系统今日发布了 deepin 25 Preview,新版本囊括五大特性:磐石系统、全新 DDE、Tree

Linux中Curl参数详解实践应用

《Linux中Curl参数详解实践应用》在现代网络开发和运维工作中,curl命令是一个不可或缺的工具,它是一个利用URL语法在命令行下工作的文件传输工具,支持多种协议,如HTTP、HTTPS、FTP等... 目录引言一、基础请求参数1. -X 或 --request2. -d 或 --data3. -H 或

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

Docker集成CI/CD的项目实践

《Docker集成CI/CD的项目实践》本文主要介绍了Docker集成CI/CD的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、引言1.1 什么是 CI/CD?1.2 docker 在 CI/CD 中的作用二、Docke