title: 动态部署排查经验 date: 2014-12-22 12:39:04

概述

经常有同学在答疑群上提出疑问为什么动态部署不生效?,然后就是一通排查。由于是远程交流,代价实在是太高。这篇文章主要是和大家分享一下动态部署排查的一些经验,希望能够帮助大家快速定位、解决问题。

另外,根据历史经验,大部分都是使用不规范造成的,为了避免这些奇奇怪怪的问题,大家最好按照Atlas工程结构指南以及容器接入 这两篇文章提到的规范,来组织工程结构。

快速排查三连

从demo中一个例子开始,假设我们发了1.0.0的Ap,之后修改了splashscreen和firstbundle两个地方的代码,并且修改了对应的版本号

基线版本 新版本
整包(apk) 1.0.0 1.0.1
splashscreen(maindex) 1.0.0 1.0.1
firstbundle(bundle) 1.0.1 1.0.2

1. 打包产物检查

首先检查打包的产物,按照历史经验,90%的问题都是因为打包产物不对造成的。

第一点,依赖变动

打开产物中的dependencyDiff.json的文件,这个文件记录了本次改动相对AP的依赖变化信息

  1. {
  2. "awbDiffs":["com.atlas.demo:firstbundle"],
  3. "mainDexDiffs":["com.atlas.demo:splashscreen(1.0.0@aar=>1.0.1@aar)"],
  4. "modifyLines":[
  5. "com.atlas.demo:firstbundle(1.0.1=>1.0.2)"
  6. ],
  7. "newAwbs":[]
  8. }

可以看到,firstbundle 和 splashscreen 的版本变化和改动一致,没有问题。

如果对不上,说明打包产物错误,下面是两个常见的原因,需要同学们自己做一下排查。

根本原因 可能的错误操作
修改引入了其它隐含的改动 在发布lib/bundle版本时,带动了其它lib/bundle的版本变化
AP不对,mvn仓库中的AP,和预期的不是同一个 1.重新publish了AP,老AP被覆盖了
2.gradle在本地仓库做了一份cache,是否和远程仓库中的一致

第二点,验证配置文件

打开update-1.0.0.json

  1. {
  2. //基线版本
  3. "baseVersion":"1.0.0",
  4. "updateBundles":[
  5. {
  6. "dependency":[
  7. "com.taobao.publicBundle"
  8. ],
  9. "isMainDex":false,
  10. "name":"com.taobao.firstbundle",
  11. //基线依赖1.0.0中的唯一tag
  12. "srcUnitTag":"1lxlheevwoeeg",
  13. //动态部署版本1.0.1的tag
  14. "unitTag":"1x6r8iuzs90ff",
  15. "version":"1.0.0@1.0.2"
  16. },
  17. {
  18. "isMainDex":true,
  19. "name":"com.taobao.maindex",
  20. "srcUnitTag":"1nf3phs9djbuj",
  21. "unitTag":"31jv86qvt1gc",
  22. "version":"1.0.0@1.0.1"
  23. }
  24. ],
  25. //动态部署更新版本
  26. "updateVersion":"1.0.1"
  27. }
  1. 涉及改动确认,配置中的diff信息和我们的改动一致(两个部分,firstbundle和maindex)

  2. 涉及版本确认,baseVersion(1.0.0), updateVersion(1.0.1),分别对应打包命令的apVersionversionName,表明是1.0.0->1.0.1的diff信息。

  3. srcUnitTag 和 unittag确认。(如果同学们没有按照规范来,这个地方很容易出错,导致动态部署失败)

关于第三个,我们以firstbundle为例,详细说明。首先,看下在配置文件update-1.0.0.json中的值:

key val
srcUnitTag 1lxlheevwoeeg
unitTag 1x6r8iuzs90ff

ok,我们再解压1.0.0的ap文件,打开atlasFrameworkProperties.json文件,关键字搜索com.taobao.firstbundle

  1. {
  2. "bundleInfo":[
  3. {
  4. "pkgName":"com.taobao.firstbundle",
  5. "unique_tag":"1lxlheevwoeeg",
  6. "version":"1.0.0@1.0.1"
  7. },
  8. //...
  9. ]
  10. }

各位,有没有灵光一闪?是的,unittag和srcunittag是有联系的,客户端用来验证patch的合法性,看图:

动态部署失败排查指南 - 图1

以上是正确的使用姿势,下面是常见的一些常见的错误

错误 原因
update-xxx.json中bundle的srcUnittag和AP中的unitttag不一样 AP不对,比对的AP和预想的不是同一个
在update-xxx.json文件中,某个bundle的srcUnittag和unittag一样 通常来说都是改了代码,但是没有变更依赖lib/bundle的版本号

第三点,diff代码验证

解压tpatch

  1. └── patch-1.0.1@1.0.0
  2. ├── libcom_taobao_firstbundle
  3. └── classes.dex
  4. └── libcom_taobao_maindex.so

反编译Dex,查看patch出来的代码和修改的是否一致。

比如修改了firstbundle 中的first.java和splashscreen中的maindex.java,diff出来的产物就一定如上图所示:

  • libcom_taobao_firstbundle,反编译classes.dex,有且只有first.class这个diff
  • libcom_taobao_maindex.so,解压反编译classes.dex,有且只有maindex.class这个diff
  • 改了几个类这里就会对应diff出几个,不会多也不会少

如果有异常,和第上面一样

  • 还是AP有问题
  • 或者本次修改隐含带入了其它改动。

2. 客户端检查

通常来说,如果打包产物如果没有问题,动态部署一般都是可以正常生效的。

首先,确保手机存储卡容量足够(至少100m吧),然后在进行下面的排查步骤。

按照文档,触发patch更新操作,观察本地上两个地方

  1. /data/data/\${pkg}/files/bundleBaseline/updateinfo
  2. /data/data/pkg/files/storage/\${bundle\_pkg\_name}/bundle.zip

pkg为app的包名

如果同时存在updateinfoupdateinfo_new两个文件,以updateinfo_new为准

bundle_pkg_name为bundle的包名,maindex的包名为com.taobao.maindex

重启前

在动态部署提示重启前,执行 cat updateInfo 命令

  1. 1.0.1Ecom.taobao.maindex@31jv86qvt1gc;com.taobao.firstbundle@1x6r8iuzs90ff;

格式很简单

动态部署版本 maindex tag firstbudnle tag
1.0.1 31jv86qvt1gc 1x6r8iuzs90ff

对应前面打包产物update-1.0.0.json中的记录的unittag,数据没有问题。

查看merge的产物是否存在,以firstbundle为例,maindex同理。

cd到和/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle

  1. bullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle # ls
  2. 1x6r8iuzs90ff lock

目录名为记录的tag1x6r8iuzs90ff,cd 进去

  1. bullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle/1x6r8iuzs90ff # ls
  2. bundle.dex bundle.zip lock meta

可以看到产物merge成功了,反编译budnle.zip(apk),可以验证改动

重启后

还是查看这两个文件,updateinfo的内容有没有变,或者storage下merge后bundle的产物是否存在

  1. /data/data/\${pkg}/files/bundleBaseline/updateinfo
  2. /data/data/pkg/files/storage/\${bundle\_pkg\_name}/bundle.zip

没有异常,说明本次动态部署生效。

如果有异常,返回检查第一步的产物。