实习公司&小组
(大佬们可能看不起的)酷家乐 - 工具后端 - 输出引擎
实习参与项目
参与的项目不多,总体有:
- 户型图输出服务端
- 户型图输出渲染端
- Micro-task微服务框架
- Kool-VR输出服务端
- 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
(对比Callable
和Runnable
)
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对我的关照。