之因此把代码放到第一位,是由于这一点最容易引发技术人员的忽视。实际上,第一步就应该是分析相关的代码,找出相应的瓶颈,再来考虑具体的优化策略。有一些性能问题,彻底是因为代码写的不合理,经过直接修改一下代码就能解决问题的,好比for循环次数过多、做了不少无谓的条件判断、相同逻辑重复屡次等。 html
1.尽可能指定类、方法的final修饰符(方法内联优化,去除方法调用的成本(如创建栈帧等)、为其余优化创建了良好的基础)数据库
2.尽可能重用对象(如StringBuilder/StringBuffer,单例模式)后端
3.尽量使用局部变量数组
4.及时关闭流缓存
5.尽可能采用懒加载的策略,即在须要的时候才建立(如懒汉式单例模式)性能优化
6.慎用异常,异常只能用于错误处理,不该该用来控制程序流程。服务器
7.若是能估计到待添加的内容长度,为底层以数组方式实现的集合、工具类指定初始长度架构
8.尽可能避免随意使用静态变量(常驻内存)app
9.使用同步代码块替代同步方法
10.使用数据库链接池和线程池(避免频繁地打开和关闭链接;避免频繁地建立和销毁线程)
11.不捕获Java类库中定义的继承自RuntimeException的运行时异常类
........
优秀的代码来自每一点点小小的优化,关注每个细节,不只仅能提高程序运行效率,一样能够规避许多未知的问题。
数据库是最容易产生性能瓶颈的服务组件。
主从同步、读写分离、分库分表及Sharding Sphere
(1)首先考虑读写分离,主数据库处理事务性增删改操做,从数据库专门负责处理查询操做,后台进行主从同步。扩展了数据读的能力,对于写能力依然无法扩展。
(2)水平分区数据拆分,即将同一张表的数据拆分到不一样的数据库中,如经过UserID%8操做划分。重要的原则是被拆分的数据尽量的平均拆分到后端的数据库中。
(3)尽可能减小事务边界(事务边界,单个sql语句在后端数据库上同时执行的数量)
若是每一条SQL语句都能带有分库分表键,经过分布式服务层在对于SQL的解析后都能精确地将这条SQL语句推送到该数据所在的数据库上执行;可是若是数据库访问不带有分库分表键,则会出现全表扫描,致使事务边界的数量增大。会出现的问题:系统中锁冲突的几率增长,系统难以扩展(整个平台的数据库链接能力是取决于后端单个数据库的链接能力),总体性能下降(大数据量的聚合、排序、分组计算,会占用较大的内存和CPU计算资源)。
买家在查看本身订单的过程当中出现全表扫描,有违“尽可能减小事务边界”这一原则
如何解决这类问题?异构索引表,拿空间换时间。
采用异步机制将原表内的每一次建立或者更新,都换另外一个维度保存一份完整的数据表或者索引表,经过两次带分库分表键的访问代替了全表扫描。
这个时候就须要结合当前使用链接池的原理、具体的链接池监控数据和当前的业务量做一个综合的判断,经过反复的几回调试获得最终的调优参数。
针对某些客户端的请求,在服务端可能须要针对这些请求作一些附属的事情,这些事情其实用户并不关心或者用户不须要当即拿到这些事情的处理结果,这种状况就比较适合用异步的方式处理这些事情。
一种作法,是额外开辟线程,这里能够采用额外开辟一个线程或者使用线程池的作法,在IO线程(处理请求响应)以外的线程来处理相应的任务,在IO线程中让response先返回。
若是异步线程处理的任务设计的数据量很是巨大,那么能够引入阻塞队列BlockingQueue做进一步的优化。具体作法是让一批异步线程不断地往阻塞队列里扔数据,而后额外起一个处理线程,循环批量从队列里拿预设大小的一批数据,来进行批处理(好比发一个批量的远程服务请求),这样进一步提升了性能。
另外一种作法,是使用消息队列(MQ)中间件服务,MQ天生就是异步的。一些额外的任务,可能不须要我这个系统来处理,可是须要其余系统来处理。这个时候能够先把它封装成一个消息,扔到消息队列里面,经过消息中间件的可靠性保证把消息投递到关心它的系统,而后让这个系统来作相应的处理。
好比C端在完成一个提单动做之后,可能须要其它端作一系列的事情,可是这些事情的结果不会马上对C端用户产生影响,那么就能够先把C端下单的请求响应先返回给用户,返回以前往MQ中发一个消息便可。并且这些事情理应不是C端的负责范围,因此这个时候用MQ的方式,来解决这个问题最合适。
看成DB用(非缓存场景)。
须要结合具体的业务场景,看这块业务涉及的数据是否适合用NoSQL来存储,对数据的操做方式是否适合用NoSQL的方式来操做,或者是否须要用到NoSQL的一些额外特性(好比原子加减等)。
若是业务数据不须要和其余数据做关联,不须要事务或者外键之类的支持,并且有可能写入会异常频繁,这个时候就比较适合用NoSQL(好比HBase)。
好比,公司内部有一个对exception作的监控系统,若是在应用系统发生严重故障的时候,可能会短期产生大量exception数据,这个时候若是选用MySQL,会形成MySQL的瞬间写压力飙升,容易致使MySQL服务器的性能急剧恶化以及主从同步延迟之类的问题,这种场景就比较适合用Hbase相似的NoSQL来存储。
经过监控系统(如没有现成的系统,本身作一个简单的上报监控的系统也很容易)上对一些机器关键指标(gc time、gc count、各个分代的内存大小变化、机器的Load值与CPU使用率、JVM的线程数等)的监控报警,也能够看gc log和jstat等命令的输出,再结合线上JVM进程服务的一些关键接口的性能数据和请求体验,基本上就能定位出当前的JVM是否有问题,以及是否须要调优。