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

2023-10-22 13:50

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

前言


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

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

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

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


1

支付宝架构设计与发展


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

640?wx_fmt=png


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


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


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


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


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


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


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


640?wx_fmt=png


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


640?wx_fmt=png


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


  • 最底层是支付宝框架的容器层,包括类加载资源加载和安全模块;


  • 第二层是我们抽离出来的组件层,包括网络库,日志库,缓存库,多媒体库,日志等等,简单说这些是一些通用的能力层;


  • 第三层是我们定制的框架层,这是关键部分,是我们得以实现上千人,上千多个工程共同开发一个 App 的基础。


  • 第四层是基于框架封装出来的业务服务层;

  • 第五层便是具体的业务模块,其中每一个模块都是一个或多个具体的工程。为了搭建超级 App 的并行开发模式,我们必须保证模块与模块之间的低耦合,实现插件式灵活的开发,因此整体业务分为了上千多个工程。


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


640?wx_fmt=png


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


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

第一种:代码层面的依赖(即我需要调用对方写的代码);

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


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

    1.编译期;

    2.运行期。


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


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


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


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


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


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


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


640?wx_fmt=png


微服务是通过面向接口开发、引用,然后在框架中动态注册的方式来实现的接口隔离解耦。


微应用是通过预先定义好一个数字来唯一标识一个业务模块,然后动态注册到框架中,具体这个业务模块中有什么,入口叫什么,完全由开发负责人自己决定。


所有框架注册的微应用微服务最终会在框架启动中动态加载。


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


2

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


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


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


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

640?wx_fmt=png


既然发布确保了效率,那么支付宝又是如何保证发布稳定性的?


传统的开发模式是:开发测试、全量发版,然后进入下个版本的迭代,继续开发测试修 bug、全量发版。这样做有几个缺点:

1、如果测试阶段未发现缺陷,很可能导致线上用户出现大规模异常;

2、出现大规模异常没有修复能力,造成用户损失;

3、随着业务的迭代,业务越来越多,功能越来越复杂,卡顿现象频出,用户体验变差;

4、关键业务监控不到位,不知道用户怎么使用 App,或者出现业务异常无感知,传统的开发模式里开发测试的比重基本上占到了 90% 甚至 100%。


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


640?wx_fmt=png


3

支付宝架构的优势与赋能


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


640?wx_fmt=png


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


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


640?wx_fmt=jpeg


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



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

相关文章

mysql_mcp_server部署及应用实践案例

《mysql_mcp_server部署及应用实践案例》文章介绍了在CentOS7.5环境下部署MySQL_mcp_server的步骤,包括服务安装、配置和启动,还提供了一个基于Dify工作流的应用案例... 目录mysql_mcp_server部署及应用案例1. 服务安装1.1. 下载源码1.2. 创建独立

VSCode开发中有哪些好用的插件和快捷键

《VSCode开发中有哪些好用的插件和快捷键》作为全球最受欢迎的编程工具,VSCode的快捷键体系是提升开发效率的核心密码,:本文主要介绍VSCode开发中有哪些好用的插件和快捷键的相关资料,文中... 目录前言1、vscode插件1.1 Live-server1.2 Auto Rename Tag1.3

Agent开发核心技术解析以及现代Agent架构设计

《Agent开发核心技术解析以及现代Agent架构设计》在人工智能领域,Agent并非一个全新的概念,但在大模型时代,它被赋予了全新的生命力,简单来说,Agent是一个能够自主感知环境、理解任务、制定... 目录一、回归本源:到底什么是Agent?二、核心链路拆解:Agent的"大脑"与"四肢"1. 规划模

SpringBoot简单整合ElasticSearch实践

《SpringBoot简单整合ElasticSearch实践》Elasticsearch支持结构化和非结构化数据检索,通过索引创建和倒排索引文档,提高搜索效率,它基于Lucene封装,分为索引库、类型... 目录一:ElasticSearch支持对结构化和非结构化的数据进行检索二:ES的核心概念Index:

Python数据验证神器Pydantic库的使用和实践中的避坑指南

《Python数据验证神器Pydantic库的使用和实践中的避坑指南》Pydantic是一个用于数据验证和设置的库,可以显著简化API接口开发,文章通过一个实际案例,展示了Pydantic如何在生产环... 目录1️⃣ 崩溃时刻:当你的API接口又双叒崩了!2️⃣ 神兵天降:3行代码解决验证难题3️⃣ 深度

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

Python+wxPython开发一个文件属性比对工具

《Python+wxPython开发一个文件属性比对工具》在日常的文件管理工作中,我们经常会遇到同一个文件存在多个版本,或者需要验证备份文件与源文件是否一致,下面我们就来看看如何使用wxPython模... 目录引言项目背景与需求应用场景核心需求运行结果技术选型程序设计界面布局核心功能模块关键代码解析文件大

SQL 注入攻击(SQL Injection)原理、利用方式与防御策略深度解析

《SQL注入攻击(SQLInjection)原理、利用方式与防御策略深度解析》本文将从SQL注入的基本原理、攻击方式、常见利用手法,到企业级防御方案进行全面讲解,以帮助开发者和安全人员更系统地理解... 目录一、前言二、SQL 注入攻击的基本概念三、SQL 注入常见类型分析1. 基于错误回显的注入(Erro

C++多线程开发环境配置方法

《C++多线程开发环境配置方法》文章详细介绍了如何在Windows上安装MinGW-w64和VSCode,并配置环境变量和编译任务,使用VSCode创建一个C++多线程测试项目,并通过配置tasks.... 目录下载安装 MinGW-w64下载安装VS code创建测试项目配置编译任务创建 tasks.js

MySQL存储过程实践(in、out、inout)

《MySQL存储过程实践(in、out、inout)》文章介绍了数据库中的存储过程,包括其定义、优缺点、性能调校与撰写,以及创建和调用方法,还详细说明了存储过程的参数类型,包括IN、OUT和INOUT... 目录简述存储过程存储过程的优缺点优点缺点存储过程的创建和调用mysql 存储过程中的关键语法案例存储