Loading

性能优化有感

性能优化有感

性能优化是个枯燥,却又有趣的过程
性能优化我大致分为几个方面

  • 代码优化
  • 线程优化、异步
  • JVM优化
  • 数据库优化
  • 缓存优化
  • 架构优化

下面来展开谈谈感悟,也可以参考美团技术团队常见性能优化

代码优化

代码是跟我们接触最多的东西,代码优化主要有

  1. 代码结构优化,可以方便日后扩展和代码标准化
    • 是否可以进行抽象避免冗余代码
    • 是否可以利用设计模式
    • 代码是否遵循阿里巴巴Java开发手册

这里可以采用阿里巴巴Java开发规范插件

  1. 代码是否有多重循环,无效的查询等
    • 多重循环可以根据数据量采用HashMap进行查询,属于利用空间换取时间
    • 无效的查询等可以进行删除
      这里推荐Findbugs

线程优化

线程优化是一个复杂的过程,多线程如何运用,如何避免死锁、饥饿、活锁等问题

  1. 线程使用的地方

    • 在查询中可以运用到多线程,把串行化操作变化为并行化操作
    • I/O阻塞的操作,最经典的莫过于BIO
    • 计算量大的操作,使用多线程可以更好的运用CPU的运算能力
  2. 线程池
    需要了解线程池的状态,线程池的参数,以及内部原理,并选择合适的线程池
    这里推荐一篇文章Java线程池实现原理及其在美团业务中的实践 再次感谢美团技术团队

    • 线程池分为
      • newCachedThreadPool
      • newFixedThreadPool
      • newSingleThreadExecutor
      • newScheduleThreadPool
      • forkjoinPool
        注意:这里不建议使用Executors来创建线程池,方式OOM等问题,参考阿里巴巴开发规范,建议使用new ThreadPoolExecutor()
  3. 异步
    异步建议采用MQ,使用范围例如insert、update操作,可以丢到MQ,这里要注意MQ消息丢失问题,同时MQ也可以实现延迟队列,例如30分钟关闭订单,采用Job的方式并不是一个好的解决方案,可以采用MQ延时队列实现,这里推荐rocketmq(阿里巴巴牛逼)

  4. 并发容器的选择
    concurrenthashmap和synchronizedmap性能差距很大,建议选择合适的并发容器

JVM优化

JVM优化这里本人也不是特别的熟练,只是讲一些自己所知道的

  1. 无日志不优化
    在没有日志的情况下,该怎么优化,如何优化,哪些方面需要优化,这里都是未知的,所以需要日志才能进行优化
  2. 工具
    优化要有趁手的工具,好在JDK本身就为我们提供了不少,在JDK的bin目录下有一堆自带的工具,这里介绍几个我熟悉且用过的
    • jps:查看当前机器上的java程序
    • jcmd:跟jps差不多但是能看到启动命令
    • jstat:查看JVM信息,例如GC信息
    • jinfo:查看JVM参数
    • jmap:JVM在内存中的情况,可以导出Dump
    • jstack:栈信息,可以用来查看死锁等
    • jconsole:一个可视化工具
    • jvisualvm:也是一个可视化工具比jconsole功能强一些,但是都有局限性,在服务器上无法使用
    • eclipse memory analyer:分析dump文件
  3. 参数优化
    使用上面的工具对服务器进行监控,可以根据信息适当的调整堆大小,GC收集器等。建议开启-XX:+HeapDumpOnOutOfMemoryError

数据库优化

数据库是优化中重要的一环,具体优化方法如下

  1. SQL优化:是否可以去掉不必要的查询,使用explain对sql进行分析,避免回表等
  2. 分库分表:一台数据库可能存在性能瓶颈,可以采用分库分表的方式,拆分主要采用冷热数据分离、日期分割、HASH取模等。
  3. 读写分离:对数据的修改可以操作主库,对数据的查询可以操作从库,进行读写分离
    分库分表以及读写分离后可能会出现分布式事务、读写分离操作的复杂性等问题这里需要引入中间件例如:MyCat sharding jdbc

缓存优化

缓存是个优化的好办法但是也有弊端

  1. 缓存分类
    • JVM缓存:concurrenthashmap、guava缓存
    • Redis等NoSQL数据库
  2. 缓存拆分
    可以在代码中对接口进行拆分,可以缓存的和不可以缓存的写成多个方法,对可以缓存的进行缓存
  3. 缓存带来的弊端
    缓存并不是越多越好,缓存给系统带来了复杂性,例如:何时添加缓存、何时删除缓存、缓存雪崩、缓存击穿、缓存穿透、缓存预热、Redis集群如何实现、Redis哨兵、Redis脑裂等问题

架构优化

架构优化其实就程序员来说能做的并不是很多

  1. 限流:GateWay进行限流,限流方法有滑动窗口、漏桶、令牌桶算法,这里建议采用合适的方法进行限流防止应用崩溃
  2. 熔断:可以采用hystrix防止服务雪崩
  3. CDN优化:对静态资源采用CDN可以提交响应速率
  4. DNS优化:这个暂时不熟可以交给运维处理
  5. 服务扩容:可以采用K8S和Docker的技术对服务进行动态扩容,这里也是运维实现

测试

优化了这么多,体现当然是压力测试,这里因为不熟悉性能指标,单机TPS部分接口可以达到800+ RT在300ms以内,希望大家提供一个单机性能标准,以上采用的是LoadRuner测试的结果

洋洋洒洒写了这么多,主要的还是平时的积累以及思考,也希望您对内容进行补充。

posted @ 2020-04-25 23:29  ingxx  阅读(653)  评论(0编辑  收藏  举报