从零开始仿写一个抖音App——日志和埋点以及后端初步架构
[*]1.很多人在写一些重复性的日志的时候就会想到 aop,这种技能可以在注解的方法前后注入必要的模板代码。我在上一篇文章中讲到了这个技能,有爱好的同学可以去看看,这里我就简单说一下。
[*]2.首先我们得先界说一个注解类,其可以用于注解类大概方法。注解类中可以被填入一些信息,比如是否必要打印方法的初入参等等。
[*]3.在注解类使用了之后,我们必要用到 gradle transform。这种技能可以让我们在编译期间扫描所有的类,从而找被注解类所注解的方法和类。
[*]4.最后我们可以用上javassist来给找到的方法前后注入我们必要的代码。留意这里的日志可以是本地的 debug日志,也可以是本地文件日志,还可以是埋点日志。可以说 aop 日志只是一种对别的几种日志的自动化封装。
3、网络请求日志
https://i-blog.csdnimg.cn/blog_migrate/c05b5c0916a08c3a907aa7440a06f64b.png
[*]1.我们在调试网络请求的时候,除了抓包还会打印出网络请求。这个时候就如果有一种统一的形式来打印日志的话就会方便许多。
[*]2.现在绝大部分的厂商使用的网络请求库都是 okhttp ,所以我就直接在其上面进行日志的定制就行了。因为项目的 http 模块还没有进行开发,所以还没有实当代码,这里就讲一讲大致方案。之后在开发 http 模块的时候会顺便解说具体实现。
[*]3.在解说方案之前我们必要知道,okhttp 的工作方式。如图3中所示,在一个 okhttp 请求的过程中会经过一个个拦截器,从本地向网络请求的时候会经过一次,网络请求回来的时候又会经过一次。
[*]4.所以我们就可以添加一个日志拦截器在两次经过拦截器的时候打印请求的 head 和按需打印 请求的 body。留意,这里打印可以是向 debug 日志、本地文件日志、埋点日志这三个地方打印。分别用于本地 debug、线上 debug和网络性能监控。
4、本地文件日志
https://i-blog.csdnimg.cn/blog_migrate/761ecbc4c9e0ca8292df1d66805d18c5.png
[*]1.当我们在线上遇见 bug 的时候咋办呢?有些 crash 的日志可以通过 bugly 这种平台来进行回捞。但是有些奇葩的 bug 只在某些机型乃至某些用户的手机上发生。这个时候本地文件日志就派上用场了。
[*]2.我们可以在开发的时候在一些关键的功能上手动添加上本地文件日志。当某个用户报了 bug 之后我们就可以让其通过一个入口将文件日志发送到后台,最后由开发职员进行日志分析找到题目。
[*]3.接下来我就来通过代码团结上面的图4来解说本地文件日志的实现方式。
[*]4.我们先来看看图4:
[*]1.LocalFileLogger负责提供本模块对外的 api,主要功能有两个:
[*]1.初始化和绑定LocalFileLoggerService(这是一个 service,可以通过 binder 来与外部交互)
[*]2.通过 binder 将外部的添加日志的请求交给LocalFileLoggerService
[*]2.LocalFileLoggerService中会初始化一个 HandlerThread,本 Service 会通过 Handler 向其不断的抛入经过高性能拼接的日志的添加请求。
[*]3.FileLogger是负责将日志写入本地的类,其也初始化了一个 HandlerThread,而且自界说了一个 LoggerHandler。这个 Handler 会将 LocalFileLoggerService 抛过来的一条条日志进行累积,当积累到了肯定量的时候。发出写入日志的请求交给 HandlerThread执行。
https://i-blog.csdnimg.cn/blog_migrate/9fc43de5f112d1c38ae5437ff37a15b9.png
https://i-blog.csdnimg.cn/blog_migrate/e79c1b764e2a0389df7fa13ddcc52aa6.png
https://i-blog.csdnimg.cn/blog_migrate/c07ff50058872bc093a5fd4a1d75e291.png
https://i-blog.csdnimg.cn/blog_migrate/ca0754bb7b9a1342f7441944bbe897a4.png
[*]5.再来看看代码,我们跟着代码走一遍流程:
[*]1.首先在图5中我们可以瞥见在 addLog 中经过一系列的调用,终极交给了 sLogInterface.log 这个对象是一个 Binder 对象,用于利用 LocalFileLoggerService 。
[*]2.进入到图6,可以瞥见 Service 初始化了一个 HandlerThread 然后界说了一个 Handler 用于向此中抛送请求。然后在看 mBinder 的实现就是通过 Handler 向 HandlerThread 中抛送 FileLogger.addLog 的执行请求。
[*]3.进入到图7,可以瞥见在 FileLogger 初始化的时候也初始化了一个 HandlerThread ,然后界说了一个 LoggerHandler 来向此中抛日志写入请求。FileLogger.addLog 方法中是直接发送一个请求。
[*]4.再看图8,LoggerHandler.add 中并不会立即向本地写入日志,而是会有一 LOG_CACHE_COUNT 阈值,只有超过了这个阈值才会向文件系统中写入日志。
5、埋点日志
https://i-blog.csdnimg.cn/blog_migrate/ad2cd32661e4520a9307795a81f476d6.png
[*]1.埋点日志其实和文件日志类似,我这里就团结图9简单说一下,具体的代码大家可以去翻看项目
[*]2.首先还是有一个 UploadLogManager 用于给外部提供 api 以及初始化 LocalFileLoggerService。这里比文件系统复杂的地方就在于多了一个 UploadLogConfiguration 用于装配一些设置。
[*]3.有了 LocalFileLoggerService 之后这里分两个不同的埋点日志添加方式。
[*]1.实时埋点日志添加:外部必要立即将当前的埋点日志上报,此时就直接将请求发送给 UploadLogHandler 然后交给 HandlerThread 执行,终极 通过 LogSender执行网络上报。
[*]2.非实时埋点日志添加:这种方式是每隔肯定的时间,LocalFileLoggerService 会从 UploadLogStorage 中取出肯定量的日志,合并之后再像1中一样上报埋点。
[*]4.目前因为 Http 模块和 数据库模块都没有开始写,所以 UploadLogStorage 和 LogSender 都还只是接口,但是并不影响代码逻辑。
三、后端架构的初步设想
虽然本项目的着重点是仿抖音 android 端 app 的开发,但是后台方面也会有所涉及。接下来笔者会介绍一下本项目在后端方面的目标和预期达到的结果。
1、RPC
可能会有客户端的同学对 RPC(远程过程调用) 这个词不怎么了解,我这里就先简单介绍一下。
拿 Java 来说:比如我们有两个服务 A、B 在两个服务器上,此时我们要在 A 上调用 B 的服务获取其上的数据 Foo。那么在 A 中可以写成 Foo f = b.XXXService();。在这里 Foo 是 A、B 两个服务所界说的数据传输结构,b 是 B 服务所抽象出来的对象,其内部实现可以是各种网络数据交互协议,比如说 http 协议。简单来说:RPC就是要像调用本地的函数一样去调远程函数。
现存的 RPC 框架有很多,各个大厂也都开源了自己框架,我这里就介绍和比较一下几个框架,最后团结本项目的需求选择适合的框架。
[*]1.Dubbo:这个是阿里开源的一个框架,厥后阿里因为种种原因把他废弃了,最后被当当网维护扩展出了一个 Dubbox。这里就讲一讲他的优劣势吧:
[*]1.优势:
[*]1.Dubbo 是用 java 写的,对于 android 客户端的开发者来说比较友好。
[*]2.Dubbo 的生态目前来说还是比较好的,笔者去年在有赞实习 java 开发的时候,用过半年的 Dubbo,感觉各种坑都有人踩过,各种库也都比较完善。
[*]3.对于服务治理支持的比较到位。
[*]2.劣势:
[*]1.跨平台本领差,原生的 Dubbo 基本上没有跨平台本领,后面的话集成了 thrift 作为扩展的话就有了,不外我总感觉集成之后用起来不方便。
[*]2.以 java 作为主开发语言的话,不能快速迭代。我们项目的时间主要是要向 android 客户端倾斜,所以必要一个能快速迭代的语言。
[*]3.序列化和反序列化的速度与其他 RPC 框架相比都不是很拔尖。
[*]4.性能较其他几个框架差。
[*]2.Thrift:这个是 FaceBook 开源的一个框架,2007年由facebook贡献到apache基金,是apache下的顶级项目。
[*]1.优势:
[*]1.跨平台本领强,支持几乎所有的主流语言。
[*]2.性能比较好
[*]2.劣势:
[*]1.跨平台的语言协议写起来比较麻烦。
[*]2.不支持服务治理
[*]3.Grpc:由 Google 开源的框架,我司目前后端也在使用这个框架
[*]1.优势:
[*]1.跨平台本领强、支持大部分主流开发语言
[*]2.跨平台语言协议用的是 ProtoBuf,与我们客户端的技能栈一致。
[*]3.性能比较好
[*]4.有我司的技能支持,固然不是官方的,不外我可以了解我司在这方面的技能,最后反哺到我们的项目中。
[*]2.劣势:
[*]1.不支持服务治理
看了上面的比较我想大家内心已经有了答案,没错我决定使用 grpc 做为本项目后端的 rpc 框架。然后开发的语言是 python 为主,java 为辅助,后面如果偶然间的话可能会用 go 实现一个小的服务也说不定。使用这些语言的原因有下面几点:
[*]1.首先 python 目前后台的生态也比较成熟,用起来也比较方便快速。
[*]2.其次我们到了后面会使用 tensorflow 来训练各种深度学习的模型,如许的话熟练使用 python 是必须的。
[*]3.有人会问你为什么要用几种不同的语言来实现后端的服务呢?这不是多此一举吗。简直,从正常开发的角度来讲是挺多余的,但是多语言的情况在大一些的厂来讲是再正常不外的事情,我的一部分目的也是为了模拟这种场景。除此之外,这种多语言的情况在我看来还是比较有意思的,想试试玩玩看。
2.微服务与服务治理
其实本来在这里我有很多东西想说的,但是发现自己现在的本领并不能完全说好这两个东西,怕最后会误导大家,所以我这里就列一下最后本项目必要完成的与这两个目标相关的东西。
[*]1.在未来笔者预期的是会有10台服务呆板,两台为一组提供一类服务,一共会有五个大类的服务。
[*]2.所以第一个要实现的功能就是:服务发现注册功能。这个功能主要是和注册中央进行交互。
[*]1.服务提供者启动,向注册中央注册自己提供的服务
[*]2.消耗者启动,向注册中央订阅自己必要的服务
[*]3.注册中央返回服务提供者的列表给消耗者
[*]4.消耗者从服务提供者列表中,按照软负载平衡算法,选择一台发起请求
[*]3.为了了解和监控各个服务的情况,第二个要实现的功能就是:服务监控,即累计计算随着时间推移各个服务被调用的次数。
[*]4.为了区分内外网,以及统一鉴权。必要实现的第三个功能就是:服务网关,所有外部请求都会经过这个网关,网关会将请求分发给内部的呆板,内部呆板调用完成之后会将结果通过网关返回给外部。
四、ubuntu情况初始化
不知道在我的读者中有多少个人用的是 mac。因为我本人就是 mac 和 win 的双系统用户所以我深知。mac 在开发方面的利益。这一节就轻松一点,我演示一下如何将本地 mac 下令行情况初始化到云上的 ubuntu 中。
1、oh my zsh
https://i-blog.csdnimg.cn/blog_migrate/e071428d217e1821ab017563bc4ca715.png
[*]1.首先必要在XX云中买一个呆板。我买的是阿里云,最开始的系统模板选择 ubuntu16,然后什么都不要装。然后在本地用 ssh 登录云主机。
[*]2.在本地电脑上 clone 一下我的这个库,接下来要用到里面的两个脚本文件。ubuntu初始化
[*]3.用 scp 下令将2中的两个文件上传到服务器上分别是:ubuntu_init.sh 和 ubuntu_init_oh-my-zsh.sh。例如:scp a.jpg root@47.106.145.211:/root/a.jpg,将本地本目次的 a.jpg 文件上传为云服务器上的/root/a.jpg文件。
[*]4.运行ubuntu_init.sh,中间会让你输入密码,最后会重启服务器。
[*]5.等4中重启服务器之后,登录服务器然后运行ubuntu_init_oh-my-zsh.sh。如此就大功告成了。终极结果如图10,这个终端比 ubuntu 原生的好用多了,而且还支持各种定制的插件。
[*]6.忘了说了这个下令行是一个开源项目:oh my zsh,英语比较好的同学可以看原项目,来拓展自己的配置。
2、vim 配置
https://i-blog.csdnimg.cn/blog_migrate/7cbad4c48b3bc86c90b759b7685b0666.png
[*]1.接下来就是 vim 的配置,其实我到现在也没完全乐成的把配置完全乐成的把配置完成乐成的转移到 ubuntu 上面,所以大家看看就好。
[*]2.ubuntu初始化,这个仓库里 .vimrc 是 vim 的配置文件。vim 插件管理,这个仓库里是 vim 插件库。
[*]3.这里其实就是为了 show 一下我的成果,对于初学者来说能学习的方面不多,对于老鸟来说也看不上我的配置。
3、docker配置
这两周我也抽空学习了一下 docker,我的理解上 docker 就是一个方便打包重用超轻量虚拟机。所以我们后端也会用上这个技能以方便运维。我也是刚学这东西,所以我就贴几个我学习的网址吧!
[*]1.docker初始学习
[*]2.docker python 学习
五、尾巴
总结
可以看出,笔者的工作学习模式便是由以下 「六个要点」 构成:
❝ 多层次的工作/学习计划 + 番茄工作法 + 定额工作法 + 批处理惩罚 + 多任务并行 + 图层工作法❞
盼望大家能将这些要点融入自己的工作学习当中,我信赖肯定会工作与学习地更富有成效。
下面是我学习用到的一些册本学习导图,以及系统的学习资料。每一个知识点,都有对应的导图,学习的资料,视频,面试标题。
**如:我必要学习 **Flutter的知识。(大家可以参考我的学习方法)
[*]Flutter 的头脑导图(无论学习什么,有学习蹊径都会事半功倍)
https://i-blog.csdnimg.cn/blog_migrate/4767ea86a6ef8c812a04e80c7c42263d.png
[*]Flutter进阶学习全套手册
https://i-blog.csdnimg.cn/blog_migrate/81ec3743fc74f5ec5ed44ccdfcbf73f7.png
[*]Flutter进阶学习全套视频
https://i-blog.csdnimg.cn/blog_migrate/aba8b2814fe4034af266472e95279747.png
大概就上面这几个步调,如许学习不但高效,而且能系统的学习新的知识。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
中…(img-Sos4IU3N-1715181501620)]
大概就上面这几个步调,如许学习不但高效,而且能系统的学习新的知识。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]