智联招聘App架构

一、智联招聘App架构模式简介

智联App前身

智联App一开始是只有一个单独工程在运行的App模式,里面掺杂着各种设计模式,诸如MVC、MVP、MVVM等等,还有各种不知道是什么来着的设计模式。模块代码耦合度高,业务代码历史包袱沉重等问题。

智联App现在

现在智联App采用了组件化的方式,将一个臃肿,复杂的单一工程的项目,根据功能或者业务进行分解,拆分成为各个独立的功能模块或者组件,最后统一组合成完整的App。解决了原来高耦合、易冲突、并行开发效率低下的问题。

关于什么是组件化开发,我在之前一篇文章里iOS组件化之路有提到,大家可以移步过去看一下(Android遍稍后补上)。

二、智联招聘App架构图解

app结构En.png

每个业务模块都是一个独立存在、可独立运行和打包的子工程,原来的主工程则变成一个壳工程。
不同的子工程可以根据需求依赖其他子工程来独立运行,每个子工程都有他自己的版本号,比如子工程A,v1.1.0版本可以和子工程B的v2.1.0版本组合打包,也可以和子工程C的v1.3.1版本组合打包。
这样的好处是加快编译速度(不用编译主工程那一大坨代码了),减少对主工程的依赖,更方便QA同学去针对性测试。而且加快业务线发版效率(每个子工程都有自己的Git仓库和版本号,可以更方便的进行版本管理,多版本的并行开发)

Shell Project.png

三、路由组件

要实现这些单模块的拆分和组合,其中一个最主要也是最核心的组件,就是这个Router,所有模块间的交互和联调,都要经过这个Router。

Router.png

Router在组件化工程中的作用是什么,从上图可以看出,其实路由所做的工作,就是把各个模块的互相依赖和耦合给抽离出来。

智联App路由组件

iOS组件ZPRouter
屏幕快照 2018-09-13 下午3.56.53.png
一、功能介绍
  1. 支持解析标准URL进行跳转,支持传递参数
  2. 支持回调传值
  3. 支持用户指定全局降级与局部降级策略
  4. 支持添加多个全局拦截器和某个页面自定义拦截
  5. 支持动态修改路径
  6. 支持模块解耦(供应者)
  7. 支持第三方APP跳转
二、典型应用
  1. 从外部URL映射到内部页面,以及参数传递与解析
  2. 跨模块页面跳转,模块间解耦
  3. 拦截跳转过程,处理登陆、埋点等逻辑
  4. 跨模块API调用,通过控制反转来做组件解耦
Android组件ARouter

Android的路由组件是基于阿里巴巴的ARouter进行的二次开发,具体ARouter的使用,可以参考ARouter的Git库的介绍

另外iOS的路由组件,具体大家可以移步看一下我们的另一篇文章,iOS路由组件

四、智联招聘网络框架

iOS网络框架ZPMNetwork

ZPMNetwork 是什么

ZPMNetwork 是智联招聘 iOS 研发团队基于 AFNetworking 封装的 iOS 网络库,其实现了一套 High Level 的 ZPMNetwork 现在同时被使用在公司的所有产品的 iOS 端,包括:智联招聘智联企业版

ZPMNetwork 提供了哪些功能

相比 AFNetworking,ZPMNetwork 提供了以下更高级的功能:

  • 支持按时间缓存网络请求内容
  • 支持按版本号缓存网络请求内容
  • 支持统一设置服务器和 CDN 的地址
  • 支持检查返回 JSON 内容的合法性
  • 支持文件的断点续传
  • 支持 blockdelegate 两种模式的回调方式
  • 支持批量的网络请求发送,并统一设置它们的回调(实现在 ZPMBatchRequest 类中)
  • 支持方便地设置有相互依赖的网络请求的发送,例如:发送请求 A,根据请求 A 的结果,选择性的发送请求 B 和 C,再根据 B 和 C 的结果,选择性的发送请求 D。(实现在 ZPMChainRequest 类中)
  • 支持网络请求 URL 的 filter,可以统一为网络请求加上一些参数,或者修改一些路径。
  • 定义了一套插件机制,可以很方便地为 ZPMNetwork 增加功能。例如,可以在某些网络请求发起时,在界面上显示“正在加载”的 HUD。

ZPMNetwork 的基本思想

ZPMNetwork 的基本的思想是把每一个网络请求封装成对象。所以使用 ZPMNetwork,你的每一个请求都需要继承 ZPMRequest 类,通过覆盖父类的一些方法来构造指定的网络请求。

把每一个网络请求封装成对象其实是使用了设计模式中的 Command 模式,它有以下好处:

  • 将网络请求与具体的第三方库依赖隔离,方便以后更换底层的网络库。
  • 方便在基类中处理公共逻辑,例如版本号信息就统一在基类中处理。
  • 方便在基类中处理缓存逻辑,以及其它一些公共逻辑。
  • 方便做对象的持久化。

ZPMNetwork架构图

ZPMNetwork.png

Android网络架构ZhaopinHttp

ZhaopinHttp 是什么

ZhaopinHttp是智联招聘 Android 研发团队基于 [okhttp-OkGo][okhttp-OkGo] 封装的Android 网络库,提供给智联android 开发团队使用,包括:智联招聘、智联企业版。

ZhaopinHttp 提供了哪些功能

相比 B/C端老旧网络框架,ZhaopinHttp 提供了以下更高级的功能:

  • 一般的 get,post,put,delete,head,options请求
  • 基于Post的大文本数据上传
  • 多文件和多参数统一的表单上传
  • 支持一个key上传一个文件,也可以一个Key上传多个文件
  • 大文件下载和下载进度回调
  • 大文件上传和上传进度回调
  • 支持cookie的内存存储和持久化存储,支持传递自定义cookie
  • 支持304缓存协议,扩展四种本地缓存模式,并且支持缓存时间控制
  • 支持301、302重定向
  • 支持可信证书和自签名证书的https的访问,支持双向认证
  • 支持根据Tag取消请求
  • 支持自定义泛型Callback,自动根据泛型返回对象
  • 支持可信证书和自签名证书的https的访问,支持双向认证

ZhaopinHttp 的基本思想

ZhaopinHttp 的基本的思想是把每一个网络请求形成一个实例,以Builder的模式进行功能扩展及暴露方法,链式请求传入APi、MAP等可配置信息回调。支持泛型和实体类两种方式,解析层有内部解析和Response 回传的方式外部String 解析,便于外部根据业务建立项目的拦截机制。

ZhaopinHttp架构图

AndroidNetworkFramework.png

五、持续集成CI系统

什么是持续集成

持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

没有CI之前的流程图

App开发-旧.png

使用CI之后的流程图

模块开发-新.png

智联App的iOS的持续集成

CI-iOS.png

智联App的Android的持续集成

单模块-Android.png

智联移动App持续集成系统结构图:

Android移动APP持续集成系统.png

集成软件的过程不是新问题,如果项目开发的规模比较小,比如一个人的项目,如果它对外部系统的依赖很小,那么软件集成不是问题,但是随着软件项目复杂度的增加(即使增加一个人),就会对集成和确保软件组件能够在一起工作提出了更多的要求-要早集成,常集成。早集成,频繁的集成帮助项目在早期发现项目风险和质量问题,如果到后期才发现这些问题,解决问题代价很大,很有可能导致项目延期或者项目失败。

持续化构建带来的自动化发布和自动化测试,可以避免人为发包忘记环境切换或者参数配置出错的问题。同时减少开发人员的打包时间,提升了开发效率。

六、降级方案

一个完整的App,除了有路由、网络、CI系统、还必须有对应的降级方案。所谓的降级方案,就是当一个线上页面(或模块)出问题后,使用某种方法对这个页面(或模块)进行降级处理,比如Native页面切换成h5或者weex,甚至灰度的关闭该模块等方式,去保护线上App的稳定性和用户体验,以保障用户使用App的流程完整性。

智联的四级通道

四级通道.png

智联的降级方案从上往下分为四种:

  • App级别
  • 路由级别
  • 模块级别
  • 单独模块内部级别

App级别分为版本升级和App本身的容错处理,此级别为最上层级别,当发生了不可控的错误,只能通过版本升级来处理时,采取此方法;
路由级别可以灵活的通过服务下发的命令,自由调度页面间的跳转,甚至模块间的调度方式。比如A页面出现了问题(App崩溃等不可控的情况),可以通过服务器下发的命令,暂时关闭此模块;
模块级别通过页面的切换来确保线上流程的完整性,比如A页面是Weex页,服务器出现问题后,可通过配置切换到Native或者h5页面去支持线上完整的业务流程(淘宝的订单页也会经常性的切换到h5);

七、其他提升

1、版本管理

之前的App升级提示只能按照小于某个版本来提示,比如最新版本是7.9.0,选择7.9.0之后,那么小于这个版本的诸如7.8.9等版本都会收到升级提示。看似合理,但是实际上无法做到自由控制版本的提示,比如在7.9.0之前有几个版本,比如7.7.0,7.8.1有严重bug,其他版本没有此类bug,就无法做到我只提示这2个版本升级,而其他版本不提示。
另外还有一点就是老的升级只能控制是强制升级还是普通升级。但是一旦选了强制升级,其他版本就无法显示普通升级。比如我想7.8.5以下版本都提示强制升级,但是7.8.6、7.8.7等小于7.9.0版本普通升级,就无法做到。
新架构版本的App升级提示优化了这一点,既可以控制哪个版本升级提示,还能选定是强制还是普通升级。除此之外,还能自由控制每个版本的提示文案、升级App的下载地址。


WX20181029-113622@2x.png

图片.png

这个安装包地址,是为了防止你的App哪天被下架了,而你又有一个小号App在上面,那么你就可以利用这个升级提示,把用户引导到你的另一个App上。

2、标签管理

图片.png

这个标签,实际上是底部的tabbar,通过这个标签管理,可以在后台随时配置App底部tabbar的item的是否显示、显示的位置,显示多少个item,还有进入App后优先显示哪个tabbar的页面等,都可以自由控制。
另外还支持按比例来灰度显示,比如让百分之多少的用户这样显示,另外的百分之几的用户显示其他的item。


图片.png

3、路由控制

可以自由配置页面间的跳转,甚至层级关系,比如原来A页面是要跳转到B页面的,可以通过后台配置,将A页面的跳转改为跳到C页面。甚至还可以改变他们直接的层级关系,比如原来的A页面是一级页面,B页面属于二级页面,可以通过路由控制,让B页面变成一级,A变成二级页面(当然,技术上是可行的,但要考虑到业务逻辑,所以还是得提前适配的)。
有了这个自由控制,诸如一些模块的某个页面出现了问题,就可以通过这个路由控制来替换其他页面,或者关闭这个有问题的模块。

4、业务管理

用来控制具体页面模块的灰度分发比例、模块的显示内容、显示数量等。比如首页列表的样式、列表的长度是20个还是40个还是100个。还可以根据灰度分发比例,让不同的用户看到的内容是不一样的。

推荐阅读更多精彩内容