作者:快如闪电的男人 - 宫城

背景

客户端大量的硬编码导致其灵活性大大降低,一些细小的改动只能通过发布版本解决,用户升级更新迭代速度慢,时效性差等原因,催生出了有赞 App 的动态化配置中心,它可以将配置,功能,界面,数据等各种配置数据统一进行管理下发,实时生效,极大地提升了客户端的灵活性。

同时配置中心不仅仅是简单的对配置数据进行修改、读取而已,更需要在容错性、流量优化、带宽节省等各方面的优化上下功夫。本文主要提供了有赞 App 的动态化配置中心解决方案,也总结了版本迭代中所做的优化。

配置中心设计

起初有赞各 App 内都散落着一些写死的链接,但随着 WWDC 16 中,Apple 表示将继续在 iOS 10 和 macOS 10.12 里收紧对普通 HTTP 的访问限制,并且无法使用 NSAllowsArbitraryLoads 来绕过 ATS 限制。我们只能很费时费力的把各 App 内所有访问 HTTP 的链接都修改成 HTTPS,这一个小小的改动就如此麻烦,那后续大的改动更难以想象,所以我们开始思考能否将这些重复且动态的工作抽象成一个配置中心,用它来支撑各个业务。

第一版

第一版设计的相对简单,我们只是专门设计了一个 API,通过 API 请求配置数据,并且每个业务单独维护一份配置文件。

具体流程:客户端进入到前台,也就是应用程序被激活的时候,通过配置中心的接口向服务端请求最新的配置数据,如果配置文件有更新,则下发最新的配置给客户端,并且客户端本地存储这份最新的配置,用于应用运行时使用。

但随着模块化的推进和应用数量的增加,配置文件的体积和数量会逐渐增大,每一次修改都会全量下发到客户端,这部分的流量累积起来是一个非常庞大的数字。并且使用配置文件去管理配置,只能维护到最新的配置,无法做到下发指定版本的配置。

所以针对这些弊端问题,我们衍生出了第二版配置中心。

第二版

为了解决第一版产生的流量浪费和配置管理弱的问题,我们优化了配置下发和管理流程,我们采取的策略是 增量更新 和 数据库存储配置 。

具体流程改动:

增量更新

增量更新的优势主要体现在业务增长的过程中。我们的配置文件可能会从几十 KB 增长到几百 KB 甚至更大,如果还继续使用全量更新,这部分流量对用户来说是非常浪费的。而使用增量更新之后,服务端只需要下发不同配置之间的差异补丁包,补丁包的大小相比于原始配置的大小是非常小的,可以节省下90%左右的流量,这是非常可观的。

增量更新我们目前使用的是 Google 出的 google-diff-match-patch ,支持 Java, JavaScript, Dart, C++, C#, Objective-C, Lua 和 Python,但是官网已经下掉了该 SDK(不明白为什么),需要到 GitHub 上搜索类似于 diff patch language:java 这样的关键词,就能找到对应平台下的 SDK 了,有人已经 fork 出来了,因为只是字符串的比较处理,所以可以放心使用。

该增量更新的原理是先通过比较首部和尾部的相同部分,目的是提升一定的效率,再比较中间差异的部分,差异的部分通过一些字符去表示该改动是 DEL 还是 ADD 还是 EQUAL ,这样最终形成的补丁包比改动部分要大一点,但是相比于全量更新已经减少很多了。

并且生成补丁包基本是毫秒级的,也不必担心接口请求的耗时问题。

服务端把前后配置的字符串进行比较即可得到一组补丁数据:

$dmp = new DiffMatchPatch();
$patches = $dmp->patch_make($oldConfigString, $latestConfigString);
$patchStrings = [];
foreach ($patches as $patchObject) {array_push($patchStrings, $patchObject->__toString());
}

生成的补丁以官方为例,补丁内包含两个字符串之间变动部分的 location 和 length,并最终下发给客户端:

@@ -16,21 +16,29 @@see
-yonder
+thecloud
+over there that
@@ -47,18 +47,19 @@almost
-in
+theshape o
@@ -86,24 +86,18 @@By
-the mass, and 't
+golly, it is l
@@ -129,21 +129,23 @@et:
-Me
+I think
-sit
-i
+looks li
@@ -177,12 +177,12 @@is
-back
+shaped l
@@ -234,11 +234,19 @@us:
-Ver
+It's totally li

以 iOS 为例,客户端获取补丁包后,根据补丁包内变动符号以及变动内容对本地配置文件内容进行字符串拼接或删除操作,形成最终的配置:

DiffMatchPatch *dmp = [[DiffMatchPatch alloc] init];
NSError *error = nil;
NSArray<NSString *> *patchStrings = configDic[@"patches"];
NSMutableArray<Patch *> *patches = [NSMutableArray array];
for (NSString *patchString in patchStrings) {NSArray<Patch *> *patch = [dmp patch_fromText:patchString error:&error];if (!error) {[patches addObjectsFromArray:patch];}
}
NSString *newCacheConfig = [[dmp patch_apply:patches toString:cacheConfig] objectAtIndex:0];

为了确保客户端最终生成的配置与服务端保持一致,客户端在打好补丁之后,用该配置生成 MD5 值,与我们在服务端下发补丁包时携带的最新配置的 MD5 值进行比较,在一致的情况下才去缓存配置,避免因为补丁造成 App 无法使用的问题。

数据库管理配置

实现增量更新的前提是我们需要有不同版本的配置记录,而用文件去管理是非常不可控的,取而代之的是我们可以通过数据库来管理,同时利于后期的横向扩展,可以针对不同平台,不同渠道,不同版本等规则下发。

目前我们是根据版本和应用来关联到配置,所以表结构设计的很简单,把应用、版本和配置放在一张表里面,后面针对多渠道和多平台等规则之后,表结构上会做一定调整。

由于需要 App 能及时获取到最新配置,我们选择在 App 激活的时机去获取配置,通过数据统计中心我们可以看到 App 当日启动次数的时段分析,再结合配置文件大小,我们可以预估所占带宽的大小,运维是非常担心你把他的带宽跑满,影响到其他业务,所以我们需要做两个优化,一个是压缩配置,一个是本地缓存。

压缩配置

为了不占用过多的带宽,我们需要在写入之前把配置压缩,读取之后解压配置。

这里我们通过 gzip 来压缩配置:

$data['config'] = base64_encode(gzcompress(json_encode($config)));

需要注意的是 gzip 可以设置压缩等级,范围是0 - 9,默认是6,但是提升压缩等级会占用较多 CPU 时间和内存,我们使用默认等级压缩之后,配置文件体积减少了75%,看来是配置内相同的部分比较多,所以压缩效果还是比较明显的。

本地缓存

对于相同的配置,我们可以不用频繁地去请求数据库,而将其缓存到本地,这样后续的请求可以直接从缓存中读取配置,当然请记得设置缓存的过期时间。

我们目前用的是 Redis 缓存,它对于复杂的数据结构和操作支持的相当不错,而且操作简单,对于前期只是key-value存储的话,可以考虑使用 Redis 。

可操作界面

为了方便业务方修改配置,我们在内部平台上提供了一个简单的可操作界面,通过顶部的Tab栏切换查看不同应用下的配置记录。

点击 查看详情 可以看到当前版本的配置内容,目前展示的效果并不友好,后面会进行优化。

在需要修改配置的时候,我们可以通过 新增配置 给指定应用修改配置,新增时会自动在版本上 +1。

后续优化

目前有赞 App 已经实现了动态化配置中心整一套流程,但是在一些细节方面还需要不断的改进优化,比如:

  • 更加丰富的配置下发规则
  • 可操作界面配置的有效性的校验
  • 可操作界面的视觉优化
  • 等等

也欢迎大家提出自己的意见和建议,我们一起探讨学习!

我们积极拥抱新技术,不给自己设边界,勇于跳出舒适区
iOS/Android 开发可投简历至 liangfei@youzan.com(微信:feelang )

yii 使用 有赞sdk_有赞 App 动态化配置中心实践相关推荐

  1. 不要写死!天猫App的动态化配置中心实践

    不要写死!天猫App的动态化配置中心实践 2016-03-15 高嘉峻 移动开发前线 版权声明 本文为天猫无线技术专家.苹果核博主高嘉峻的投稿,未经授权禁止转载 不要写死,一个永恒的话题.动态化,也是 ...

  2. yii 使用 有赞sdk_有赞移动如何做到并行灰度的复杂场景?

    ‍‍ ‍ 点击关注"有赞coder" 获取更多技术干货哦- 作者:时文涛部门:电商移动 使用场景 作为移动开发的我们经常会遇到两种需求: 展示逻辑线上需要随时变更,例如登录注册页面 ...

  3. yii 使用 有赞sdk_有赞ABTest系统:数据驱动增长实践

    ‍‍ 点击关注"有赞coder" 获取更多技术干货哦- 作者:子固部门:数据中台 一.背景 有赞是一个商家服务公司,致力于帮助每一位重视产品和服务的商家成功.随着移动互联网的流量增 ...

  4. 互联网晚报 | 11月27日 星期六 | 电子烟等新型烟草制品参照卷烟监管;有赞上线“有赞酒店”;法拉第未来收到退市通知...

    今日看点 ✦  <烟草专卖法实施条例>修改:电子烟等新型烟草制品参照卷烟有关规定执行 ✦ 拼多多第三季度营收215.1亿元同比增长51%,净利润16.4亿元 ✦ 顺丰控股:控股子公司同城实 ...

  5. Django模板、配置文件、静态文件及案例实现(创建模板、设置模板查找路径、模板接收视图传入的数据、模板处理数据、BASE_DIR、DEBUG、本地语言与时区、App应用配置)

    1.Django模板 网站如何向客户端返回一个漂亮的页面呢? 漂亮的页面需要html.css.js. 可以把这一堆字段串全都写到视图中, 作为HttpResponse()的参数,响应给客户端. 存在的 ...

  6. Flask - app的配置和实例化Flask的参数

    目录 Flask - app的配置和实例化Flask的参数 app的配置 app的配置 Flask - app的配置和实例化Flask的参数 app的配置 基本用法: from flask impor ...

  7. android app links,Android APP Links 配置

    一. 简介 在Instant App开发中,需要app支持Instant App Links. 本文中,主要介绍其作用,配置必需条件,配置的过程. 二. 作用 App Links 本质上是 Deep ...

  8. ArchSummit分享 | 高德地图App架构演化与实践

    讲师介绍 郝仁杰,高德地图无线开发专家.在7月13日落幕的2019年ArchSummit峰会上就高德地图近几年的App架构演化和实践进行了分享. 背景概述 高德是国内领先的数字地图内容.导航和位置服务 ...

  9. Appium+Python安卓自动化测试之启动APP和配置获取

    Appium+Python安卓自动化测试之启动APP和配置获取 本文章未讲述appium+python环境部署,环境部署会新开文章 一.手机连接电脑 1.USB连接电脑和手机,手机上点确认连接(最好用 ...

最新文章

  1. gentoo emerge安装软件
  2. PMcaff-培训 | 活动报名结束,押金和邮件须知的那些事儿
  3. 8-5 Navicat工具与pymysql模块
  4. 解决 iOS 12.4 Killed: 9 的问题
  5. Java多线程神器:join使用及原理
  6. 《学习opencv》笔记——基本数据结构,CvMat,矩阵訪问
  7. 在visual studio 2010+中调用ffmpeg编译时 报错error LNK xxxx: 模块对于 SAFESEH 映像是不安全的。...
  8. github.com/oschwald/maxminddb-golang 安装报错
  9. C++与tolua++的完整调用流程,超级详解解决交互疑难
  10. Shared library can't open object
  11. 视觉机器学习20讲-MATLAB源码示例(13)-稀疏表示算法
  12. 【Android工具】更新wifi分析仪,wifi信道信息查看工具,wifi分析仪3.10.6L
  13. 丁向荣单片机pdf_STC系列增强型8051单片机原理与应用
  14. nginx配置https后报错nginx: [emerg] https protocol requires SSL support in XXX.conf详细解决方法
  15. git切换远程分支并拉取最新代码
  16. 一款提升程序员生产力的黑科技神器
  17. 金融数据api接口记录(二)
  18. mixamo_Mixamo的动画商店插件现在支持Mecanim!
  19. c语言side输出空心正方形,请帮忙完成这个c#语言打印正方形的程序
  20. C语言字符串去空格(最简单版本)

热门文章

  1. 计算机系统资源分配最小单位,在操作系统中,什么是资源分配最小单位
  2. P6:可视化卷积神经网络
  3. 卷积神经网络 – CNN
  4. Ubuntu-20.04开机黒屏出现“dev/sda ... clean ... blocks”的信息
  5. Solr部署到tomcat
  6. c/c++教程 - 2.4.4 友元friend用法
  7. 使用阿里云搭建微信公众号管理系统
  8. myeclipse 打包Jar
  9. password textbox setup
  10. centos7 安装Gitlab