Administrator
发布于 2023-04-14 / 9 阅读
0
0

随笔-4

idea实时模板

IntelliJ IDEA 附带了一个名为 Live Templates(实时模板) 的便捷功能。这是个啥玩意?即使您还不知道它是什么, 但是你也一定经常使用到它。比如输入常用代码段的快捷方式 sout,IDEA 会插入代码段 System.out.println()。又比如,输入 psvm, IDEA 会快速帮您生成 main 方法等。

File(文件) -> Setting(设置) -> Editor(编辑器) -> Live Templates(实时模板)新建模板

数据库连接池

池化技术大家应该都不会陌生,那么数据库连接池的相关配置你了解吗,真的是越大越好吗?答案肯定是NO!为什么呢,因为线程存在上下文切换,频繁切换线程肯定会降低系统的性能。

那么应该设置成多少呢,连接池的大小的设置还是要结合实际的业务场景来决定。当你的线程处理的是cpu密集型业务时,线程池连接数可以尽量接近cpu的个数,如果设置过小,无法发挥多核cpu的性能,设置过大,则会产生切换线程的消耗。当你的线程处理的是 I/O 密集型业务时,便可以让线程/连接数设置的比 CPU核心大一些,这样就能够在阻塞等待期间,切换线程执行任务,使同样的时间内,能完成更多的工作,提升吞吐量。

一般建议连接池中的连接数量大小应该设置成:数据库能够有效同时进行的查询任务数(通常情况下来说不会高于 2*CPU核心数)。

Mybatis缓存

一级缓存

在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能。

每个SqlSession中持有了Executor,每个Executor中有一个LocalCache。当用户发起查询时,MyBatis根据当前执行的语句生成 MappedStatement,在Local Cache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入 LocalCache,最后返回结果给用户。

一级缓存配置:

<!--共有两个选项, SESSION或者 STATEMENT,默认是 SESSION级别-->
<setting name="localCacheScope" value="SESSION"/>

执行添加、修改、删除等更新操作后,一级缓存失效。在session级别下,开启多个sqlSession更新数据后可能出现脏读等情况,因为一级缓存只在数据库会话内部共享。另外,STATEMENT级别的一级缓存无法共享 localCache,因为它内部判断STATEMENT后会清空缓存。session级别的更新操作也会清空缓存。

总结:

  1. MyBatis一级缓存的生命周期和SqlSession一致。

  2. MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。

  3. MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。

二级缓存

在上文中提到的一级缓存中,其最大的共享范围就是一个SqlSession内部,如果多个SqlSession之间需要共享缓存,则需要使用到二级缓存。二级缓存开启后,同一个namespace下的所有操作语句,都影响着同一个Cache,即二级缓存被多个SqlSession共享,是一个全局的变量。

当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

二级缓存配置:

  1. 在MyBatis的配置文件中开启二级缓存。

    <setting name="cacheEnabled" value="true"/>

     

  2. 在MyBatis的映射XML中配置cache或者 cache-ref 。

    <!--cache标签用于声明这个namespace使用二级缓存,并且可以自定义配置。-->
    <cache/>

     

    <!--cache-ref代表引用别的命名空间的Cache配置,两个命名空间的操作使用的是同一个Cache。-->
    <cache-ref namespace="mapper.StudentMapper"/>

     

  3. cache属性

  • type:cache使用的类型,默认是 PerpetualCache,这在一级缓存中提到过。

  • eviction: 定义回收的策略,常见的有FIFO,LRU。

  • flushInterval: 配置一定时间自动刷新缓存,单位是毫秒。

  • size: 最多缓存对象的个数。

  • readOnly: 是否只读,若配置可读写,则需要对应的实体类能够序列化。

  • blocking: 若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。

总结:

  1. MyBatis的二级缓存相对于一级缓存来说,实现了 SqlSession之间缓存数据的共享,同时粒度更加的细,能够到 namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。

  2. MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。

  3. 在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis、Memcached等分布式缓存可能成本更低,安全性也更高。

服务器cpu过载

  1. top命令找出cpu占比比较高的进程pid
  2. pwdx pid找到业务进程路径,可以看到具体是什么服务
  3. 一般java web服务的话,可以使用脚本工具show-busy-java-threads.sh快速定位问题。


评论