性能优化,实践浅谈

当经历了无数的日日夜夜,朝九晚九,攻克了无数难关,终于将系统预定功能开发完成,通过测试,部署上线后。你是否会感觉志得意满,到达了人生巅峰,高唱无敌是多么寂寞。

现实情况是,如果你这个系统,业务没有做起来,没啥人用,huan则罢liao。如果有越来越多的人,持续使用。随着用户增多,业务数据增多,那系统一定会暴露一些性能问题。而对这些问题的优化解决,以及监测,往往需要比开发具体功能,更高更全面的技术素质及能力。

一、性能问题监控

锅叔云:性能问题是具有隐蔽性,服务器硬件性能良好不等于系统服务性能良好。这么说可能经验欠缺的同学难于理解。不就是系统慢么,用户会告诉我们啊? 我们有服务器监控啊,如果cpu,或者内存满了,会有监控报警啊?

首先,系统慢用户未必会告诉你,如果比你的竞品慢太多,用户会用脚投票。然后,如果你开发的系统在把硬件跑到瓶颈之前都快如闪电,请收下锅叔的膝盖-_-|| 。

常见的性能问题,往往是欠缺性能考虑引起的,响应巨慢的同时,硬件利用率可能5%不到,这类问题也是此次锅叔主要讨论的。

经验上来说,对于性能问题的监控预警是难于解决具体的性能问题的。实践中我们需要一些日常机制来筛查系统性能问题,避免病入膏肓。

数据库慢查询日志——是一个重要的监控途径,其中记录了耗时较长的数据库操作记录。可以通过手动或自动分析慢查询日志,筛查可能存在的性能问题,主流数据库都支持慢查询日志生成,具体的配置方式此处不做赘述。非统计类的数据操作通常应该在100ms以下。

接口性能监控——后台系统通常是通过服务接口向外提供服务的,前端页面或者移动设备是通过调用服务端接口来完成对应操作的。接口的粒度是大于数据库操作的,一个接口调用可能包含很多个数据库调用。接口性能更接近于用户体验,因为多数时候用户的一个操作动作会对应一个服务接口(如保存,确认)。在不存在慢查询的时候,接口性能可能也会不满足要求,可能的原因如,一个接口循环调用了1000次数据库操作,或者调用了一些第三方接口等。对接口的性能监测原理上就是用调用结束的时间减去进入的时间点计算总耗时,并把这个耗时记录下来,以便时候筛查。Spring的切片能力可以方便的实现该需求。非报表,导出类接口,锅叔认为应当在1秒内完成为佳。

消息队列——如果你的系统中使用到了类似消息队列的机制,对队列中排队的消息数,同样应当进行监测,消息如果发生了堆积,说明在这个阶段内,系统的整体消费能力已经不能满足输入要求了。

以上三个监控维度是互不重叠的,应该同时进行。

二、性能问题的定位

除了数据库慢查询日志可以明确提示具体SQL缓慢外,上面另外两种情况所能直接提示定位到的粒度都比较大,对应一个接口或者一段处理过程代码。

定位更细问题的具体方法也很容易想到,即 分段输出各阶段的耗时。如对于一个100行的方法,可以在第30,60,100,分别计算并日志输出这3段执行耗费的时间。重复进行,就最终可以定位到将问题所在。

性能问题的定位需要有一些性能常识,所谓性能常识即,通常做一件事情需要完成的时间,不用很准确,但量级要清楚。比如一次数据库操作,一般在数十毫秒,与内存的交互在纳秒或者微秒间,与第三方系统的接口可能在数百毫秒到几秒之间。有了这些经验我们才能够对耗时是否合理有个基本判断。比如对于一个50毫秒的数据库操作,循环100次就是5秒,已经很慢了,可以考虑是不是可以合并成一次批量操作。

三、应用性能优化方法

合并远程调用——根据经验,实践中因为循环进行数据库操作,或对第三方系统接口进行循环调用,是引起性能问题的非常非常常见的原因。对于此类问题的优化方式通常就是优化调用的方式,使用批量操作。例如,如果需要去数据库中查询锅叔近一年的打卡记录,可以用准确日期,查询365次,也可以用时间范围一次查询出365条,后面的方法肯定比前面的快很多。如果方法比较复杂,冗长,可以从中抽取所需的公共数据,进行统一的批量查询取出,放入内存备用,会比哪里用到哪里查要快很多。同样写入,修改操作,也尽量批量进行。

使用缓存——对于访问频率较高的数据,可以在内存中存储,利用内存存取要快于硬盘很多的特性,来进行访问加速。常见的场景如各种计数——锅叔的文章有多少次浏览之类。

多线程并行——通过多线程把串行修改为并行。例如与设备通信查询状态,逐个查询和并行同时向设备查询,后者要快得多。现实中多数的操作耗时是在IO上,因此多线程方式可以有效提高性能,避免”空”等。多线程并行需要注意做好线程同步。

四、数据库性能优化

数据库是一个现代系统都会依赖的组件,对他的性能问题解决也是开发人员需要掌握的。

增加索引——加索引,是数据库优化的首选方案。原理是利用空间换时间。现在存储的成本下降非常快,基本上可以做到常规业务数据查询都可以走索引。对于复杂的sql 有时需要分析下怎么加索引,可以通过执行计划来分析。

锁等待——数据库是有锁概念的,一个事务占有X锁未提交前,其他事务是不能够对该记录进行操作的,只能等待。未使用唯一索引的数据库写操作,可能会对全表加写锁,在提交前,全表记录无法操作。因此对数据库锁,应当有所认识,尽量晚上锁,尽快解锁,尽量小范围上锁。推论可得,实践中,如果是长事务,尽量把更新操作后移,把耗时的非事务性操作(如无依赖的第三方接口等),设法从事务中移除。

事务隔离级别——选择合适的事务隔离级别,事务隔离级别与数据库锁有关,如最严格的串行隔离级别,所有的事务将串行进行。广泛使用的数据库MYSQL,其默认隔离级别为 “可重复读”,但带来了间隙锁的限制,增加了锁抢占的概率。如无特别,可以根据实际情况调整为 “读提交”

中间结果——本质可以理解为数据库层次的缓存,如果一些结果从全量记录中计算数据量巨大,耗时必然很长。可以分批计算,存储中间结果。以加速数据取得。如计算锅叔家近一年的总支出,可以通过每笔记录加起来,也可以每个月算一次,这样只需要查询近12个月的支出加起来就可以啦。

Original: https://www.cnblogs.com/uncleguo/p/16106699.html
Author: 锅叔
Title: 性能优化,实践浅谈

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/617222/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • C9800配置Session timeout和Idle timeout

    对客户端会话时间的修改通常发生在客户端会话超时时。一般客户会话超时,在logging中可以看到类似如下的log YYYY/DD/MM HH:MM:SS.xxx {wncd_x_R0…

    Java 2023年5月30日
    0115
  • Activiti7 多实例子流程

    顾名思义,子流程是一个包含其他活动、网关、事件等的活动,这些活动本身形成了一个流程,该流程是更大流程的一部分。 使用子流程确实有一些限制: 一个子流程只能有一个none类型的启动事…

    Java 2023年6月7日
    0103
  • mysql毫秒数引发的问题

    起因:最近同事在做定时打卡的东西,遇到一个诡异的问题,端只是传了一个开始时间跟打卡周期,剩下的打卡时间都是由服务端…

    Java 2023年6月5日
    079
  • Java 微服务框架选型(Dubbo 和 Spring Cloud?)

    微服务(Microservices)是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件…

    Java 2023年5月29日
    095
  • JAVA实现AES加密、解密

    一、什么是AES? 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且…

    Java 2023年6月5日
    075
  • 2018-2021我的开源项目总结

    本人18年6月份毕业在武汉找了第一份 java开发工作4500(面试时被hr压了500,武汉当时行情第一年5000), 做的oa、库存管理相关系统,公司内系统架构主要是ssh,页面…

    Java 2023年6月13日
    082
  • VSCode个性化的配置(QIUQIU&LL)

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月7日
    093
  • java学习之socket编程

    Socks实际上是什么:实际上是提供了精彩通信的端口,在通信之前双方都必须要创造一个端点才能通信,其实感觉socket跟计算机的三次握手有些相似,分为三个步骤:(1)服务器监听:服…

    Java 2023年6月13日
    074
  • 基于Javaweb,Mysql图书管理系统

    一、项目简介 人工管理图书的手续繁索、效率低下给具有强烈时间观念的管理人员带来了诸多不便,学校图书馆缺少一套完善的图书管理软件,为了对图书的管理方便,因此必须开发图书管理系统。 二…

    Java 2023年6月8日
    096
  • 《认知觉醒》读书笔记

    《认知觉醒》这本书分为两个部分,第一部分是 内观自己,摆脱焦虑,第二部分是 外观世界,借力前行。前者从大脑、潜意识、元认知三个方面帮助我们认识自己,审视自己内心焦虑不安的原因。后者…

    Java 2023年6月5日
    0121
  • ReadWriteLock 接口详解

    ReadWriteLock 接口详解 这是本人阅读ReadWriteLock接口源码的注释后,写出的一篇知识分享博客 读写锁的成分是什么? 读锁 Lock readLock(); …

    Java 2023年6月5日
    093
  • iOS https请求 NSURLSessionDataTask

    // YKSHttpsRequest.m // YKShareSdkDemo // Created by qingyun on 22/05/2017. // Copyright ©…

    Java 2023年5月30日
    0123
  • 【设计模式系列】结构型之桥接模式(常用)

    前言 不知道大家对于设计模式是个什么样的看法,是认为没必要啊,还是觉得是那种深入到骨子里的优雅。随着工作年限的增加,对设计模式愈发熟悉的前提下,真心觉得,设计模式是真他 * 的优雅…

    Java 2023年6月7日
    0116
  • Java中的命名规则

    在查找java命名规则时,未在国内相关网站查找到较为完整的文章,这是一篇国外程序开发人员写的java命名规则的文章,原文是英文写的,为了便于阅读,遂翻译为汉语,以便帮助国内开发者有…

    Java 2023年6月15日
    084
  • U校园自动答题和雨课堂刷视频脚本使用教程

    本篇主要参考两个github开源项目: 本篇举例的两个项目,第一个是利用 TamperMonkey 插件,第二个是直接用的.py项目 关于 TamperMonkey 可取Chrom…

    Java 2023年6月7日
    0140
  • JavaWeb中过滤器Filter的使用示例

    https://github.com/YouXianMing/Java-Web-Study/tree/master/Servlet-Filter 过滤器示例基于以下流程 测试效果如…

    Java 2023年5月29日
    088
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球