为什么别人家的APP,上报日志就这么省流量?
为了统计 APP 内用户行为,或者需要收集某些产品数据,APP 往往需要进行日志上报,日志上报往往又非常费流量,大家的 APP 是怎么上报日志的呢?
画外音:用户流量的大头,是日志上报?
APP 可不可以不上报日志,只从服务器日志统计用户的行为和产品数据?
不行,有些用户行为不会与服务器进行交互,例如 “卡片切换”,服务器日志无法完成所有统计。
APP 一般如何上报日志?
常用方法有这么几种。
(1)使用类似于 Google Analytics 的第三方工具;
优点:无需开发
缺点:不能做个性化统计
(2)自己制订私有协议进行上报;
优点:节省流量
缺点:开发成本高
画外音:例如,TCP 二进制协议,可定制化,又省流量。
(3)使用 HTTP 协议,通过 GET 参数传递需要上报的数据。
如何通过 HTTP 协议进行上报?
可以在 Web-Server 下放置一个文件,APP 发起 HTTP 请求访问这个文件,通过 GET 参数传递数据,并通过分析 access 日志来得到想要的数据。
如何通过 GET 参数传递数据?
一般又有两种方式:
(1)约定格式法;
(2)KV 法。
什么是 “约定格式法”?
约定格式法:约定分隔符,约定占位符,约定每个字段的含义,例如:
约定如下:
(1)被访问文件是 up;
(2)分隔符是 [];
(3)第一个字段 [bj] 代表城市,第二个字段代表日期,第三个字段代表时间,第四个字段代表用户 id,第五个字段代表行为。
该方法 缺点是:扩展性较差,有时候某些字段没有值,也必须在相应的位置保留占位符,因为每个字段的含义都是事先约定好的,要想新增统计项,只能在 GET 后面新增 []。
什么是 “KV 法”?
KV 法:通过 GET 参数自解释的 KV 方式来上报数据。
上面的例子用 KV 法来上报,则上报形式为:
该方法的 优点是:扩展性好。
缺点是:上报数据量比较大,非常消耗流量。
为什么会这么消耗流量呢?
之所以消耗流量,主要有这样一些原因:
(1)无效流量多,HTTP 报文有很多无效数据;
(2)URL 冗余,每次都要上报 URL;
(3)KEY 冗余,每次都要上报 KEY;
(4)上报频度高,用户每次操作都要日志上报的话,上报量很大。
有没有节省流量的方法呢?
针对上述 1-4 点,常见的优化方案有这样一些。
痛点 1:HTTP 请求内无效数据多。
解决方案:手动构造 HTTP 请求,尽可能多的去除 HTTP 中的无效数据。
画外音:
如果使用第三方库构造 HTTP 请求,可能会带上你并不需要的 UA 数据。
自己构造,则可以只保留 GET /up HTTP/1.1 和 GET 传递的必须数据;
痛点 2:URL 冗余。
解决方案:使用尽可能短的域名来接收上报的日志。
画外音:例如,s.daojia.cn/a
痛点 3:KEY 冗余。
解决方案:使用尽可能短的 KEY 来标识数据,日志收集方一定要统一规范好 KEY。
画外音:例如,city=bj 可以优化为 c=bj
一个 BAD CASE,由于没有规范,曾经某个部门上报用户 ID,不同项目中重复埋点,上报了 4 次:
name=shenjian&user_id=123&uid=123&user_name=shenjian
而上述 name、user_id、uid、user_name 都属于重复上报。
痛点 4:上报频率高。
解决方案:先将数据保存到 APP 本地存储,再定时上报,这类优化对于 PV 类,SUM 类,AVG 类统计尤为有效。
例如,要统计登录按钮的点击次数,三次点击,传统统计可能需要上报三次:
daojia.com/up?date=201…
daojia.com/up?date=201…
daojia.com/up?date=201…
优化后,增加了一个参数,只需要上报一次:
非实时上报,应该在什么时机进行日志上报呢?
如果进行合并上报,或者批量上报,数据的时效性会有一定的影响。
画外音:如果策略合理,数据误差会非常小。
为了优化,会在这样的一些时间点进行上报:
(1)特殊时间点上报:例如,APP 打开,关闭,后台转入活跃时;
(2)按时间批量上报:例如,每隔 10 分钟才上报一次;
(3)按数据量批量上报:例如,每收集 10 条记录才上报一次;
还有其他什么优化方案?
批量上报,数据压缩。
希望,文章的逻辑是清晰的。
架构师之路 - 分享通俗易懂的技术文章
调研:
贵司有埋点规范么?
不同项目出现过重复埋点么?