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级别的更新操作也会清空缓存。
总结:
-
MyBatis一级缓存的生命周期和SqlSession一致。
-
MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
-
MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。
二级缓存
在上文中提到的一级缓存中,其最大的共享范围就是一个SqlSession内部,如果多个SqlSession之间需要共享缓存,则需要使用到二级缓存。二级缓存开启后,同一个namespace下的所有操作语句,都影响着同一个Cache,即二级缓存被多个SqlSession共享,是一个全局的变量。
当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。
二级缓存配置:
-
在MyBatis的配置文件中开启二级缓存。
<setting name="cacheEnabled" value="true"/>
-
在MyBatis的映射XML中配置cache或者 cache-ref 。
<!--cache标签用于声明这个namespace使用二级缓存,并且可以自定义配置。--> <cache/>
<!--cache-ref代表引用别的命名空间的Cache配置,两个命名空间的操作使用的是同一个Cache。--> <cache-ref namespace="mapper.StudentMapper"/>
-
cache属性
-
type
:cache使用的类型,默认是PerpetualCache
,这在一级缓存中提到过。 -
eviction
: 定义回收的策略,常见的有FIFO,LRU。 -
flushInterval
: 配置一定时间自动刷新缓存,单位是毫秒。 -
size
: 最多缓存对象的个数。 -
readOnly
: 是否只读,若配置可读写,则需要对应的实体类能够序列化。 -
blocking
: 若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。
总结:
-
MyBatis的二级缓存相对于一级缓存来说,实现了
SqlSession
之间缓存数据的共享,同时粒度更加的细,能够到namespace
级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。 -
MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。
-
在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis、Memcached等分布式缓存可能成本更低,安全性也更高。
服务器cpu过载
- top命令找出cpu占比比较高的进程pid
- pwdx pid找到业务进程路径,可以看到具体是什么服务
- 一般java web服务的话,可以使用脚本工具show-busy-java-threads.sh快速定位问题。