乐趣区

关于性能优化:有关性能优化的感悟

下半年换了个工作环境,而后有了些新的感悟。在元旦这天,总结一下这几个月为了进步程序性能,而做的那些事。

1. 异步线程

刚入行的时候,很烦面试的时候被考多线程,毕竟过后很少在工作中用到。但工作几年后发现,只有想进步程序的性能,就绕不开它。最常见的场景,就是利用多线程并发执行多个部分事件,缩短总体实现工夫。开发中,通常整个我的项目注册一个线程池的 Bean,各个办法都基于这个线程池来拿线程执行业务,容易针对线程池做参数调优。

有返回参数的异步,能够试试 CompletableFuture,也是 jdk8 提供的神器,比传统的 Feature 要好用,用法参考 CompletableFuture 教程。例如:当接口须要从多个内部零碎取数据时,都能够异步执行,而后对立收集返回值。甚至利用 CompletableFuture 中个性,主动执行回调办法。

但要留神,也不是什么时候都要用异步:

  • 机器 CPU 资源无限:单台机器 CPU 的外围数无限,当多线程并发数达到顶点时,再加线程,反倒事与愿违。此时能够思考负载平衡,将并发线程摊派到多台机器上。
  • 同步更快:有些程序本来执行就很快,加了异步后反而慢了,毕竟调配线程资源也是须要工夫的。例如总共只有十几条数据,流运算时不必 stream,而是 parallelStream

2. 缓存中间件

Redis

Redis 是最罕用的缓存中间件了,它反对的罕用数据结构挺多,要依据理论利用场景来抉择,我目前用的有 String、Hash、Set、List。

原始数据当然落在关系数据库中,但业务上罕用的,通常是通过转化的两头数据。例如:员工登录后所属部门、角色权限、积分等数据,来自于不同的微服务,不能每次要用都调各方服务的接口,这些都须要缓存起来。

用缓存很无脑,但刷新缓存才是难题。像刚刚的例子,不能把所有的缓存数据都落到员工的粒度上,要依据业务来分层。例如:机构级别的数据,就每个机构存一份,依照员工所属机构来查;部门级别的数据,就每个部门存一份,依照员工所属部门来查。等等。

Elastic Search

用 ES 做缓存?预计很多人是大大的问号,谁让 Redis 过后不反对 Json 呢。从关系型数据库抽离进去的数据有时比较复杂,例如:人员所属的部门、角色、岗位等,每一个属性往下,背地的数据都不少。有人说 Redis 缓存个部门 ID、角色 ID,剩下的依据 ID 查表。但这些可是根底数据,且不说会不会把数据库查出问题,如果想要依据部门属性、角色属性、岗位属性来查人员,这个 SQL 该咋写。

最好的形式就是将这些数据从关系数据库中抽出来,以 Json 文档的模式缓存下来,MongoDB、ES 都无能这事。但为了应答后续可能千奇百怪的查问场景,还是 ES 保险一些。

可 ES 毕竟不是业余的缓存中间件,我很看好最近新进去的 RedisJson。齐全满足日常工作需要,而且据说查问性能是 ES 的上百倍。但毕竟刚进去怕有坑,等稳固一段时间再动手吧。

3. 消息中间件

这里不说 MQ 的其余个性,就聊优化性能吧。后面说单台机器的 CPU 资源无限,能够思考将并发线程摊派到多台机器上,具体怎么做呢?

将须要解决工作通过音讯投递到 MQ 中,消费者监听到 MQ 的音讯后理论执行。假使有 1000 个工作,单台机器能解决工作的最大并发线程数是 100,那么 10 台机器就够了。

4. 缩小零碎交互

内存运算是最快的,要尽量减少和内部零碎的交互次数。

例如:在查问一批数据时,每条数据须要通过外键,查问匹配的其余零碎信息。如果其余零碎信息品种不多的话,是不是通过查一次 SQL 或调用一次接口,一次性全拿过去。而后写代码做数据拼接。而不是遍历出每条数据,都去内部零碎查一遍。

还有一些插入 MySQL、Redis 的一批数据,或给 MQ 发一批音讯的,如果能够的话,就在程序外部解决好,而后调用批量插入、发送的办法,性能相对能省不少。

5. Jvm 调优

这是陈词滥调啦!我之前文章有写过,网上材料更多,这就不说了。只说一点,尽量少狐疑 Jvm 调优能进步你的程序性能,多从方案设计和代码上反思。

新年快乐~

退出移动版