实习小结

Posted by keys961 on June 12, 2018

实习公司&小组

(大佬们可能看不起的)酷家乐 - 工具后端 - 输出引擎

实习参与项目

参与的项目不多,总体有:

  1. 户型图输出服务端
  2. 户型图输出渲染端
  3. Micro-task微服务框架
  4. Kool-VR输出服务端
  5. Kool-VR输入渲染端

其中前2个实习中期以后新需求,以及遗留代码的坑都由我接手,第3个参与度在后期增加,第4第5个较少。

实习个人感觉自己比较水,业务上时间花的有点多,回来也没力气(都是借口,都是自己太懒)研究新东西。

学习到的东西

1. Spring [Boot]

现在到2.0+版本了,不过我们还是用比较稳定的1.5,不过对于输出引擎来说够用了。实习期间也是更加熟练使用了这个工具,不用Boot去配麻烦太多了。

其IoC,AOP的确方便的使用,解除耦合性,不过还是有很多屎坑的(有些遗留代码里,Micro-task就有人写了这个bug,被我找到)。

另外还有Spring Cache吧,其实也是AOP应用,我们组也有自己的扩展Spring Cache的小项目,不过我没很深入研究过源码。

而Spring源码,的确,我也没认真仔细看过很多,也是比较欠缺的地方。

2. JVM

实习前,肯定很少遇到Full GC这种问题,也很少会配置GC(肯定无脑G1)。实习的时候,由于有段时间经常Full GC,所以我也经常去分析Dump文件,然后给出优化方案(比如上次图片缓存的,还是稍微加大了点老年代内存空间,未来也可能用G1替换CMS)。

此外一些监控工具,比如top,jmap,jstack等还是对分析很有用的。

3. 缓存调优

有2周我专门对FGS的缓存进行优化,原先是全部用内存缓存(Caffine),速度很慢,超时严重;

之后替换了多级缓存,二级缓存使用Redis,速度变快了,不过这时报Full GC;

Dump后,减少一级缓存用量,Full GC变少了,但还是有;

最后直接去掉了内存缓存,使用磁盘缓存,并进行优化,现在平稳运行。

(其实也以前代码留的坑,乱用缓存)

4. Micro-task

其实就是个异步任务队列,原理其实非常简单。

队列用Redis作载体,然后提供消费者和生产者。

生产者把请求信息推入Redis队列,消费者把请求信息取出Redis队列。

任务执行者叫Worker,内包含任务主逻辑TaskCallable/TaskRunnable(对比CallableRunnable

Worker其实是有3个线程(现在有所改变,会有更多的任务逻辑线程),主线程接受并处理WorkerManager发送的请求,如关闭/打开Worker或获取Worker信息,一个Schedule线程用于跟踪监控任务逻辑的线程,另外一个线程就是任务逻辑线程。这些都可以用多个线程池管理。

Worker的状态有如FETCHING,STARTING,RUNNING,SAVING,TIMEOUT,FAILURE,SUCCEED等等,可参考FutureTask源码(面试还被问过),十分类似。

(现在的问题是Java不能强制杀死一个子线程,特别是任务超时的情况下,线程还是存在在那里的,但是Worker会去获取新任务,但是却无法将新任务加入到线程池中[线程池固定大小1]导致阻塞,现在是一超时就重启Worker,这只能是个折衷的办法,这也是需要思考的问题)

然后其配置也是遵循Spring Boot经典的配置形式(写在application[-stage].yml,参考Micro-task源码能非常快地写出。

我主要编写了其使用文档以及关键组件的原理文档,并且修复了若干bug(比如对Worker的指令只对一台机器有效等等)。

5. 开发规范

熟悉了敏捷开发的一些流程:

  • 比如以JIRA上的任务为导向,完成一个又一个这个Sprint的任务
  • 小组开组会讨论开发状态
  • 新需求必须些设计文档,不需要和传统设计文档那么复杂
  • 代码必须进行Review才能Merge到主分支上
  • Git分支的规范(需要先Rebase到最新的结点然后再MR,需要Release的版本要添加新功能需要Cherry-pick等等)
  • 跨组联调一定要有,即使你认为你的接口一定正确(感觉公司还是这方面比较混乱,各搞各的)

测试方面,我这边的话尽量保证自己冒烟测和单测能过,说实话,公司里,各个测试组其实流程也是有些混乱(也可以说是在尝试),我这里花了很多时间来调整配置以适应测试组的要求。

6. 画图业务能力

也是很吃惊,我的业务主要是出图。所以也稍微锻炼了我的计算能力,虽然本身也比较垃圾。

不过阅读源码的能力也有所提高。这些代码大多数是我的工具后端组老大写的,估计保守有2年的吧。不得不说,代码里有屎坑,错误的东西居然还能跑那么旧,比如一些计算错误。此外,其出图的效率也不高,有的图在某些区域多余绘制了好几遍,导致效率下降(本来用Java出图效率就不太好了),不过提的MR也没merge进去,mentor说怕出错(他估计也没怎么看过更底层的东西)。

出图逻辑的架构可能会随需求增加而重构。现在出图的主逻辑在1个类实现,所有的绘制代码(不包含工具方法以及底层的工具方法)都在这个类实现。未来可能会被重构,我个人的想法是,图像里的每类元素都有自己的绘制方法实现,然后用一个模板去套。

7. 其它工具和知识的使用和学习

其实有些工具都是非常常用的,比如Maven, MyBatis, Mongo, Redis之类的,实习前只是。由于业务原因,也是学习怎么使用,其实去理解它们的使用是非常简单的,就是一些学过的基础的东西,基础好了就能很快上手,稍微看看文档就行了。不过细致的源码分析(以前课上有人看过Redis源码,不过我没看),还是需要研究研究的。

此外我们业务之间SOA调用比较常用,这虽然会有性能上的损失,不过也有利于解耦。

另外跨域的问题也有一定的学习(CORS)。

总之感觉自己还是比较水&垃圾的。不过也感谢mentor对我的关照。