1:JVM预热,JVM预热工具(JMH)
类加载过程完毕后,所有需要的类会进入 JVM cache (native code) ,这样就可以被快速的实时访问。当然,还有许多其它与JVM启动无关的类此时并未被加载。
当应用的第一个请求到来,会触发逻辑相关类的第一次加载,此过程会有一定的耗时,会影响第一次调用的实时响应。这主要是因为JVM的懒加载及JIT机制(内存映射技术)。
因此对于低延迟应用,必须采用特定的策略来处理第一次的预加载逻辑,以保障第一次的请求的快速响应。此过程,我们称之为 JVM 的预热。
为什么需要JMH:if 快还是 switch 快?HashMap 的初始化 size 要不要指定,指定之后性能可以提高多少?各种序列化方法哪个耗时更短?无论出自何种原因需要进行性能评估,量化指标总是必要的。
JMH: 是用于代码微基准测试的工具套件,主要是基于方法层面的基准测试,精度可以达到纳秒级。该工具是由 Oracle 内部实现 JIT 的大牛们编写的,他们应该比任何人都了解 JIT 以及 JVM 对于基准测试的影响。
JMH 比较典型的应用场景如下:
1.1: 想准确地知道某个方法需要执行多长时间,以及执行时间和输入之间的相关性
1.2: 对比接口不同实现在给定条件下的吞吐量
1.3: 查看多少百分比的请求在多长时间内完成
@Benchmark :注解的方法,JMH才会对其执行基准测试,不然就是一个普通方法。
@Warmup :在基准测试代码正式度量之前,先对其进行预热,使得代码的执行是经历过了类的早期优化、JVM运行期编译、JIT优化之后的最终状态,从而能够获得代码真实的性能数据
@Measurement :度量。在每一轮的度量中,所有的度量数据会被纳入统计之中(预热数据不会纳入统计之中)
@BenchmarkMode :注解来声明使用哪一种模式来运行,一共有五种,All表示所有基准模式。 这主要用于内部 JMH 测试。
@OutputTimeUnit :提供了统计结果输出时的默认单位时间,比如,调用一次该方法将会耗费多少个单位时间
@State :State 对象自然地封装了基准测试所处理的状态。 State 对象的范围定义了它在工作线程之间共享的程度。
@Param :提供可配置的参数值
JMH的测试套件(Fixture) :@Setup 会在每一个基准测试方法执行前被调用,通常用于资源的初始化,@TearDown 则会在基准测试方法被执行之后被调用,通常可用于资源的回收清理工作
@CompilerControl
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.19</version>
</dependency>
2:缓存预热
2.1:缓存预热就是系统启动前,提前将相关的缓存数据通过查询数据库直接加载到缓存系统。
避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
3:DB预热
为什么要DB预热:MysqlInnoDB存储引擎,重启完毕后,一开始十几分钟的性能是非常差的,原因是因为InnoDB有innodb buffer;
和innodb buffer pool相关的参数innodb_buffer_pool_size,size越大,可以放到内存,的数据越多,而大多数的项目都会有热点数据的存在,
当热点数据经过LRU算法进入到buffer pool之后,读磁盘的次数减少,读的都是内存,速度是最快的。
问题来了:数据库一重启,热点数据都被清空,bf里面都是空的.等待app的sql请求过来让bf填满数据是一个方法,但30分钟内很难把热点数据都装载进来,这个时候就需要人工预热。
3.1:sql语句进行DB预热 :SELECT table_schema, table_name FROM information_schema.tables // 查询所有的表名和schema
3.2:mysql增加配置进行DB预热:my.cnf 加入init-file=/mysql/init.sql; init.sql就是mysql预热的语句