![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
性能调优
文章平均质量分 93
学习、记录、分享、优化。
Q.E.D.
放弃亦是坚持,坚持亦是放弃。
展开
-
32 - MySQL调优之事务:高并发场景下的数据库事务调优
其实 MySQL 的并发事务调优和 Java 的多线程编程调优非常类似,都是可以通过减小锁粒度和减少锁的持有时间进行调优。在 MySQL 的并发事务调优中,我们尽量在可以使用低事务隔离级别的业务场景中,避免使用高事务隔离级别。在功能业务开发时,开发人员往往会为了追求开发速度,习惯使用默认的参数设置来实现业务功能。例如,在 service 方法中,你可能习惯默认使用 transaction,很少再手动变更事务隔离级别。原创 2023-11-28 07:30:00 · 2114 阅读 · 0 评论 -
31 - MySQL调优之SQL语句:如何写出高性能SQL语句?
在开发中,我们要尽量写出高性能的 SQL 语句,但也无法避免一些慢 SQL 语句的出现,或因为疏漏,或因为实际生产环境与开发环境有所区别,这些都是诱因。面对这种情况,我们可以打开慢 SQL 配置项,记录下都有哪些 SQL 超过了预期的最大执行时间。// 开启慢 SQL 日志// 记录日志地址// 最大执行时间除此之外,很多数据库连接池中间件也有分析慢 SQL 的功能。原创 2023-11-27 08:00:00 · 2635 阅读 · 1 评论 -
30 - 思考题集锦
漏桶算法是基于一个漏桶来实现的,我们的请求如果要进入到业务层,必须经过漏桶,漏桶出口的请求速率是均衡的,当入口的请求量比较大的时候,如果漏桶已经满了,请求将会溢出(被拒绝),这样我们就可以保证从漏桶出来的请求量永远是均衡的,不会因为入口的请求量突然增大,致使进入业务层的并发量过大而导致系统崩溃。例如,连接池和线程池中的连接就是使用单例模式实现的,数据库操作是非常频繁的,每次操作都需要创建和销毁连接,如果使用单例,可以节省不断新建和关闭数据库连接所引起的性能消耗。首先,这两种设计模式的实现方式是不同的。原创 2023-11-27 07:30:00 · 2037 阅读 · 0 评论 -
29 - 装饰器模式:如何优化电商系统中复杂的商品价格策略?
在这之前,我先简单介绍下什么是装饰器模式。装饰器模式包括了以下几个角色:接口、具体对象、装饰类、具体装饰类。接口定义了具体对象的一些实现方法;具体对象定义了一些初始化操作,比如开头设计装修功能的案例中,水电装修、天花板以及粉刷墙等都是初始化操作;装饰类则是一个抽象类,主要用来初始化具体对象的一个类;其它的具体装饰类都继承了该抽象类。/*** 定义一个基本装修接口*//*** 装修方法*//*** 装修基本类*//*** 基本实现方法*/原创 2023-11-26 07:30:00 · 2089 阅读 · 0 评论 -
28 - 生产者消费者模式:电商库存设计优化
使用生产者消费者模式来缓冲高并发数据库扣除库存压力,类似这样的例子其实还有很多。例如,我们平时使用消息队列来做高并发流量削峰,也是基于这个原理。抢购商品时,如果所有的抢购请求都直接进入判断是否有库存和冻结缓存库存等逻辑业务中,由于这些逻辑业务操作会增加资源消耗,就可能会压垮应用服务。此时,为了保证系统资源使用的合理性,我们可以通过一个消息队列来缓冲瞬时的高并发请求。生产者消费者模式除了可以做缓冲优化系统性能之外,它还可以应用在处理一些执行任务时间比较长的场景中。原创 2023-11-25 07:30:00 · 2422 阅读 · 0 评论 -
27 - 如何使用设计模式优化并发编程?
平时,如果需要传递或隔离一些线程变量时,我们可以考虑使用上下文设计模式。在数据库读写分离的业务场景中,则经常会用到 ThreadLocal 实现动态切换数据源操作。但在使用 ThreadLocal 时,我们需要注意内存泄漏问题,在之前的[第 25 讲]中,我们已经讨论过这个问题了。当主线程处理每次请求都非常耗时时,就可能出现阻塞问题,这时候我们可以考虑将主线程业务分工到新的业务线程中,从而提高系统的并行处理能力。原创 2023-11-24 07:30:00 · 2064 阅读 · 0 评论 -
26 - 原型模式与享元模式:提升系统性能的利器
通过以上讲解,相信你对原型模式和享元模式已经有了更清楚的了解了。两种模式无论是在开源框架,还是在实际开发中,应用都十分广泛。在不得已需要重复创建大量同一对象时,我们可以使用原型模式,通过 clone 方法复制对象,这种方式比用 new 和序列化创建对象的效率要高;在创建对象时,如果我们可以共用对象的内部数据,那么通过享元模式共享相同的内部数据的对象,就可以减少对象的创建,实现系统调优。原创 2023-11-23 07:30:00 · 2029 阅读 · 0 评论 -
25 - 单例模式:如何创建单一对象优化系统性能?
它的核心在于,单例模式可以保证一个类仅创建一个实例,并提供一个访问它的全局访问点。该模式有三个基本要点:一是这个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。// 饿汉模式// 自行创建实例private Singleton(){}// 构造函数public static Singleton getInstance(){// 通过该函数向整个系统提供实例。原创 2023-11-22 07:30:00 · 2082 阅读 · 0 评论 -
24 - 内存持续上升,我该如何排查问题?
在一些比较简单的业务场景下,排查系统性能问题相对来说简单,且容易找到具体原因。但在一些复杂的业务场景下,或是一些开源框架下的源码问题,相对来说就很难排查了,有时候通过工具只能猜测到可能是某些地方出现了问题,而实际排查则要结合源码做具体分析。可以说没有捷径,排查线上的性能问题本身就不是一件很简单的事情,除了将今天介绍的这些工具融会贯通,还需要我们不断地去累积经验,真正做到性能调优。原创 2023-11-21 07:30:00 · 2333 阅读 · 0 评论 -
22 - 如何优化垃圾回收机制?
今天的内容比较多,最后再强调几个重点。垃圾收集器的种类很多,我们可以将其分成两种类型,一种是响应速度快,一种是吞吐量高。通常情况下,CMS 和 G1 回收器的响应速度快,Parallel Scavenge 回收器的吞吐量高。在 JDK1.8 环境下,默认使用的是 Parallel Scavenge(年轻代)+Serial Old(老年代)垃圾收集器,你可以通过文中介绍的查询 JVM 的 GC 默认配置方法进行查看。原创 2023-11-19 07:30:00 · 2196 阅读 · 0 评论 -
21 - 深入JVM即时编译器JIT,优化Java编译
今天我们主要了解了 JKD1.8 以及之前的类的编译和加载过程,Java 源程序是通过 Javac 编译器编译成 .class 文件,其中文件中包含的代码格式我们称之为 Java 字节码(bytecode)。这种代码格式无法直接运行,但可以被不同平台 JVM 中的 Interpreter 解释执行。由于 Interpreter 的效率低下,JVM 中的 JIT 会在运行时有选择性地将运行次数较多的方法编译成二进制代码,直接运行在底层硬件上。原创 2023-11-17 07:30:00 · 2156 阅读 · 0 评论 -
20 - 欲知JVM调优先了解JVM内存模型
这讲我们主要深入学习了最基础的内存模型设计,了解其各个分区的作用及实现原理。如今,JVM 在很大程度上减轻了 Java 开发人员投入到对象生命周期的管理精力。在使用对象的时候,JVM 会自动分配内存给对象,在不使用的时候,垃圾回收器会自动回收对象,释放占用的内存。但在某些情况下,正常的生命周期不是最优的选择,有些对象按照 JVM 默认的方式,创建成本会很高。比如,我在[第 03 讲]讲到的 String 对象,在特定的场景使用 String.intern 可以很大程度地节约内存成本。原创 2023-11-16 07:30:00 · 2060 阅读 · 0 评论 -
19 - 如何用协程来优化多线程业务?
协程和线程密切相关,协程可以认为是运行在线程上的代码块,协程提供的挂起操作会使协程暂停执行,而不会导致线程阻塞。协程又是一种轻量级资源,即使创建了上千个协程,对于系统来说也不是很大的负担,但如果在程序中创建上千个线程,那系统可真就压力山大了。可以说,协程的设计方式极大地提高了线程的使用率。通过今天的学习,当其他人侃侃而谈 Go 语言在网络编程中的优势时,相信你不会一头雾水。学习 Java 的我们也不要觉得,协程离我们很遥远了。原创 2023-11-15 07:30:00 · 2051 阅读 · 0 评论 -
18 - 如何设置线程池大小?
今天我们主要学习了线程池的实现原理,Java 线程的创建和消耗会给系统带来性能开销,因此 Java 提供了线程池来复用线程,提高程序的并发效率。Java 通过用户线程与内核线程结合的 1:1 线程模型来实现,Java 将线程的调度和管理设置在了用户态,提供了一套 Executor 框架来帮助开发人员提高效率。Executor 框架不仅包括了线程池的管理,还提供了线程工厂、队列以及拒绝策略等,可以说 Executor 框架为并发编程提供了一个完善的架构体系。原创 2023-10-24 10:30:15 · 2371 阅读 · 0 评论 -
17 - 并发容器的使用:识别不同场景下最优容器
在并发编程中,我们经常会使用容器来存储数据或对象。Java 在 JDK1.1 到 JDK1.8 这个漫长的发展过程中,依据场景的变化实现了同类型的多种容器。我将今天的主要内容为你总结了一张表格,希望能对你有所帮助,也欢迎留言补充。原创 2023-10-17 08:00:00 · 2111 阅读 · 0 评论 -
16 - 多线程调优(下):如何优化多线程上下文切换?
上下文切换是多线程编程性能消耗的原因之一,而竞争锁、线程间的通信以及过多地创建线程等多线程编程操作,都会给系统带来上下文切换。除此之外,I/O 阻塞以及 JVM 的垃圾回收也会增加上下文切换。总的来说,过于频繁的上下文切换会影响系统的性能,所以我们应该避免它。另外,我们还可以将上下文切换也作为系统的性能参考指标,并将该指标纳入到服务性能监控,防患于未然。原创 2023-10-17 07:30:00 · 2285 阅读 · 0 评论 -
15 - 多线程调优(上):哪些操作导致了上下文切换?
上下文切换就是一个工作的线程被另外一个线程暂停,另外一个线程占用了处理器开始执行任务的过程。系统和 Java 程序自发性以及非自发性的调用操作,就会导致上下文切换,从而带来系统开销。线程越多,系统的运行速度不一定越快。那么我们平时在并发量比较大的情况下,什么时候用单线程,什么时候用多线程呢?一般在单个逻辑比较简单,而且速度相对来非常快的情况下,我们可以使用单线程。例如,我们前面讲到的 Redis,从内存中快速读取值,不用考虑 I/O 瓶颈带来的阻塞问题。原创 2023-09-11 07:30:00 · 2231 阅读 · 0 评论 -
14 - 多线程之锁优化(下):使用乐观锁优化并行操作
开始优化前,我们先来简单回顾下乐观锁的定义。乐观锁,顾名思义,就是说在操作共享资源时,它总是抱着乐观的态度进行,它认为自己可以成功地完成操作。但实际上,当多个线程同时操作一个共享资源时,只有一个线程会成功,那么失败的线程呢?它们不会像悲观锁一样在操作系统中挂起,而仅仅是返回,并且系统允许失败的线程重试,也允许自动放弃退出操作。所以,乐观锁相比悲观锁来说,不会带来死锁、饥饿等活性故障问题,线程间的相互影响也远远比悲观锁要小。更为重要的是,乐观锁没有因竞争造成的系统开销,所以在性能上也是更胜一筹。原创 2023-09-08 07:30:00 · 2226 阅读 · 0 评论 -
13 - 多线程之锁优化(中):深入了解Lock同步锁的优化方法
不管使用 Synchronized 同步锁还是 Lock 同步锁,只要存在锁竞争就会产生线程阻塞,从而导致线程之间的频繁切换,最终增加性能消耗。因此,如何降低锁竞争,就成为了优化锁的关键。在 Synchronized 同步锁中,我们了解了可以通过减小锁粒度、减少锁占用时间来降低锁的竞争。在这一讲中,我们知道可以利用 Lock 锁的灵活性,通过锁分离的方式来降低锁竞争。原创 2023-09-07 07:30:00 · 2113 阅读 · 0 评论 -
12 - 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
JVM 在 JDK1.6 中引入了分级锁机制来优化 Synchronized,当一个线程获取锁时,首先对象锁将成为一个偏向锁,这样做是为了优化同一线程重复获取导致的用户态与内核态的切换问题;其次如果有多个线程竞争锁资源,锁将会升级为轻量级锁,它适用于在短时间内持有锁,且分锁有交替切换的场景;偏向锁还使用了自旋锁来避免线程用户态与内核态的频繁切换,大大地提高了系统性能;但如果锁竞争太激烈了,那么同步锁将会升级为重量级锁。减少锁竞争,是优化 Synchronized 同步锁的关键。原创 2023-09-06 07:30:00 · 2214 阅读 · 0 评论 -
10 - 网络通信优化之通信协议:如何优化RPC网络通信?
一提到 RPC,你是否还想到 MVC、SOA 这些概念呢?如果你没有经历过这些架构的演变,这些概念就很容易混淆。你可以通过下面这张图来了解下这些架构的演变史。无论是微服务、SOA、还是 RPC 架构,它们都是分布式服务架构,都需要实现服务之间的互相通信,我们通常把这种通信统称为 RPC 通信。RPC(Remote Process Call),即远程服务调用,是通过网络请求远程计算机程序服务的通信技术。原创 2023-08-26 07:30:00 · 2242 阅读 · 0 评论 -
09 - 网络通信优化之序列化:避免使用Java序列化
无论是网路传输还是磁盘持久化数据,我们都需要将数据编码成字节码,而我们平时在程序中使用的数据都是基于内存的数据类型或者对象,我们需要通过编码将这些数据转化成二进制字节流;如果需要接收或者再使用时,又需要通过解码将二进制字节流转换成内存数据。我们通常将这两个过程称为序列化与反序列化。Java 默认的序列化是通过 Serializable 接口实现的,只要类实现了该接口,同时生成一个默认的版本号,我们无需手动设置,该类就会自动实现序列化与反序列化。原创 2023-08-18 13:30:57 · 2447 阅读 · 1 评论 -
08 - 网络通信优化之IO模型:如何解决高并发下IO瓶颈?
I/O 是机器获取和交换信息的主要渠道,而流是完成 I/O 操作的主要方式。在计算机中,流是一种信息的转换。流是有序的,因此相对于某一机器或者应用程序而言,我们通常把机器或者应用程序接收外界的信息称为输入流(InputStream),从机器或者应用程序向外输出的信息称为输出流(OutputStream),合称为输入 / 输出流(I/O Streams)。机器间或程序间在进行信息交换或者数据交换时,总是先将对象或数据转换为某种形式的流,再通过流的传输,到达指定机器或程序后,再将流转换为对象数据。原创 2023-08-17 07:30:00 · 2921 阅读 · 28 评论 -
07 - 深入浅出HashMap的设计与优化
HashMap 通过哈希表数据结构的形式来存储键值对,这种设计的好处就是查询键值对的效率高。我们在使用 HashMap 时,可以结合自己的场景来设置初始容量和加载因子两个参数。当查询操作较为频繁时,我们可以适当地减少加载因子;如果对内存利用率要求比较高,我可以适当的增加加载因子。我们还可以在预知存储数据量的情况下,提前设置初始容量(初始容量 = 预知数据量 / 加载因子)。这样做的好处是可以减少 resize() 操作,提高 HashMap 的效率。原创 2023-08-15 07:30:00 · 2920 阅读 · 32 评论 -
06 - Stream如何提高遍历集合效率?
现在很多大数据量系统中都存在分表分库的情况。例如,电商系统中的订单表,常常使用用户 ID 的 Hash 值来实现分表分库,这样是为了减少单个表的数据量,优化用户查询订单的速度。但在后台管理员审核订单时,他们需要将各个数据源的数据查询到应用层之后进行合并操作。例如,当我们需要查询出过滤条件下的所有订单,并按照订单的某个条件进行排序,单个数据源查询出来的数据是可以按照某个条件进行排序的,但多个数据源查询出来已经排序好的数据,并不代表合并后是正确的排序,所以我们需要在应用层对合并数据集合重新进行排序。原创 2023-08-10 07:30:00 · 3775 阅读 · 91 评论 -
05 - ArrayList还是LinkedList?使用不当性能差千倍
前面我们已经从源码的实现角度深入了解了 ArrayList 和 LinkedList 的实现原理以及各自的特点。如果你能充分理解这些内容,很多实际应用中的相关性能问题也就迎刃而解了。就像如果现在还有人跟你说,“ArrayList 和 LinkedList 在新增、删除元素时,LinkedList 的效率要高于 ArrayList,而在遍历的时候,ArrayList 的效率要高于 LinkedList”,你还会表示赞同吗?现在我们不妨通过几组测试来验证一下。原创 2023-08-05 07:30:00 · 3160 阅读 · 45 评论 -
04 - 慎重使用正则表达式
很基础,这里带你简单回顾一下。正则表达式是计算机科学的一个概念,很多语言都实现了它。正则表达式使用一些特定的元字符来检索、匹配以及替换符合规则的字符串。构造正则表达式语法的元字符,由普通字符、标准字符、限定字符(量词)、定位字符(边界字符)组成。正则表达式虽然小,却有着强大的匹配功能。我们经常用到它,比如,注册页面手机号或邮箱的校验。但很多时候,我们又会因为它小而忽略它的使用规则,测试用例中又没有覆盖到一些特殊用例,不乏上线就中招的情况发生。原创 2023-07-26 07:30:00 · 3788 阅读 · 17 评论 -
03 - 字符串性能优化不容小觑,百M内存轻松存储几十G数据
这一讲中,我们认识到做好 String 字符串性能优化,可以提高系统的整体性能。在这个理论基础上,Java 版本在迭代中通过不断地更改成员变量,节约内存空间,对 String 对象进行优化。我们还特别提到了 String 对象的不可变性,正是这个特性实现了字符串常量池,通过减少同一个值的字符串对象的重复创建,进一步节约内存。但也是因为这个特性,我们在做长字符串拼接时,需要显示使用 StringBuilder,以提高字符串的拼接性能。原创 2023-07-20 07:30:00 · 4016 阅读 · 0 评论 -
02 - 如何制定性能调优策略?
学完这讲,你应该对性能测试以及性能调优有所认识了。我们再通过一张图来回顾下今天的内容。我们将性能测试分为微基准性能测试和宏基准性能测试,前者可以精准地调优小单元的业务功能,后者可以结合内外因素,综合模拟线上环境来测试系统性能。两种方法结合,可以更立体地测试系统性能。测试结果可以帮助我们制定性能调优策略,调优方法很多,这里就不一一赘述了。但有一个共同点就是,调优策略千变万化,但思路和核心都是一样的,都是从业务调优到编程调优,再到系统调优。原创 2023-07-19 07:30:00 · 3989 阅读 · 0 评论 -
01 - 如何制定性能调优标准?
通过今天的学习,我们知道性能调优可以使系统稳定,用户体验更佳,甚至在比较大的系统中,还能帮公司节约资源。但是在项目的开始阶段,我们没有必要过早地介入性能优化,只需在编码的时候保证其优秀、高效,以及良好的程序设计。在完成项目后,我们就可以进行系统测试了,我们可以将以下性能指标,作为性能调优的标准,响应时间、吞吐量、计算机资源分配使用率、负载承受能力。回顾我自己的项目经验,有电商系统、支付系统以及游戏充值计费系统,用户级都是千万级别,且要承受各种大型抢购活动,所以我对系统的性能要求非常苛刻。原创 2023-07-18 07:30:00 · 4042 阅读 · 0 评论