刚接手的系统就出了问题

2021-05-14 14:17:24 浏览数 (1)

前段时间出差去成都,交接了搜索系统,还专门发了个朋友圈,吐槽在成都不吃辣的人的痛苦,赚了不少评论。

谁成想,节后上班还没坐稳,系统就出了问题。

搜索系统的索引会在每天凌晨全量更新,白天会接收各系统的MQ增量更新,以满足数据准确、一致和实时的目的,问题就出在了白天的增量MQ上。

过几天要大促,市场和运营的同志们拼了命的创建活动,导致MQ大面积积压,短信都要把手机震烂了。。。也让项目代码还没看完的我连轴转了。。。

虽然现在问题还在等待解决,也想抽空记录,顺便和大家分享下:

1. 接收MQ的目的是实时更新索引,但是,写ES的索引时,最好不要实时刷新,一般搜索的场景应该也不需要这么实时,只要运用ES本身的定时刷新,实现准实时,就完全可以了,写ES并实时刷新是非常耗时且占资源的。

2.对于线程池的使用。因为我们用的是自己的MQ本来就是异步线程处理的,个人认为对接收多个MQ来说,完全可以直接创建多个class类来单独处理每一个MQ,而原来的代码却又把这多个MQ任务 放进了一个线程池,启动线程处理,导致某一个MQ卡住时,其他MQ也全部不能正常消费。虽然代码结构看起来各种继承,各种抽象,然而并么有啥好效果。所以,线程池的运用要适当,讲究场景,不可滥用。

3.系统之间的调用。对于一些固定不变的数据,比如字典、黑白名单,不需要实时调接口的,我们应该尽量不去调,因为接口调用涉及到的系统间交互和网络开销还是很大的,再加上我们调的后端系统的缓存设计有些不合理,以至于我们扩容以后直接击穿了他们的数据库,这个等待结果返回的耗时就更加不可估量了,基本上就是你设多长时间超时,那就得等多长时间。所以调用方和接口方的处理方式都要合理、严谨才能避免事故的发生。

关于缓存。我所涉及到的缓存大致有三个层次,

【本机缓存 --> 快速存储 --> 数据库】。

快速存储 有大家熟悉的redis memrecache等 ,数据库有MySQL 等。

往往让大家忽略的是本地缓存。其实,现在已经有很多优秀的缓存框架开源出来,在尽量不影响GC的前提下,有效利用机器内存的同时,提高程序处理的效率,我最常用的是Google 的cahce 框架 guava ,当然还有ehcache等等优秀的缓存框架。

因为 现在的机器硬件都非常优秀,即使是docker ,也是多核大内存,而JVM 能有效运用的内存大小其实是有限的。在一般情况下,我的机器都会空闲出很可观的一部分内存空间,我们可以叫它堆外内存,代码就不在这贴了,

github上写了个guava的demo,大家看有什么意见可以一起交流学习下O(∩_∩)O

https://github.com/jinhuicheng/heap-outside-cache.git

0 人点赞