多级缓存就是充分利用请求处理的每个环节,分别添加缓存,减轻tomcat压力,提升服务性能
JVM进程缓存
缓存分为两类:
- 分布式缓存(例如redis)
- 优点:存储容量更大,可靠性更好,可以在集群间共享
- 缺点:访问缓存有网络开销
- 场景:缓存数据量较大,可靠性要求较高,需要在集群间共享
- 进程本地缓存(HashMap、GuavaCache)
- 优点:读取本地内存,没有网络开销,速度更快
- 缺点:存储容量有限,可靠性较低,无法共享
- 场景:性能要求较高,存储数据量较小
进程本地缓存:使用Caffeine实现(最流行)
基础用法:
java
@Test
public void testCaffine(){
Cache<Object, Object> cache = Caffeine.newBuilder().build();
cache.put("zsy",666);
Object zsy = cache.get("zsy", key -> {
return "666";
});
System.out.println(zsy);
}
三种缓存驱逐策略:
- 基于容量:设置缓存的数量上限
- 基于时间:设置缓存的有效时间
- 基于引用:设置缓存为软引用或弱引用,利用GC来回收缓存数据,性能差
默认情况下,缓存过期不会立即清理驱逐,而是再一次读写操作后,或者空闲时间
lua基础
基本数据类型、变量、循环、函数、条件控制、
看帮助文档
OpenResty
使用
- 在nginx.conf的http下面,添加对openresty的lua模块的加载
- 在nginx.conf的server下面,添加对需要路径的监听
- 编写lua脚本
获取不同类型的请求参数:
| 参数格式 | 参数示例 | 参数解析代码示例 |
|---|---|---|
| 路径占位符 | /item/1001 | location ~ /item/(\d+){content_by_lua_file lua/item.lua } |
| 请求头 | id:1001 | local headers=ngx.req.get_headers() |
| get请求参数 | ?id=1001 | local getParams=ngx.req.get_url_args |
| post表单参数 | id=1001 | ngx.req.read_body() local postParam=ngx.req.get_post_args() |
| json参数 | {"id":1001} | ngx.req.read_body() local jsonBody=ngx.req.get_body_data() |
Nginx location 匹配规则
| 匹配符 | 匹配类型 | 示例 | 是否匹配 /item/1001 | 优先级 |
|---|---|---|---|---|
| = | 精确匹配 | location = /item | 不匹配 (必须完全一致) | 1 (最高) |
| ^~ | 最佳前缀匹配 | location ^~ /item | 匹配 (匹配后停止搜索正则) | 2 |
| ~ | 正则匹配(区分大小写) | location ~ /item/\d+ | 匹配 | 3 |
| ~* | 正则匹配(不区分大小写) | location ~* /ITEM | 匹配 | 3 |
| (无) | 普通前缀匹配 | location /item | 匹配 | 4 (最低) |
冷启动:服务刚刚启动时,redis中并没有缓存,如果所有商品数据都在第一次查询时添加缓存,可能会给数据库带来较大压力
缓存预热:我们可以利用大数据统计用户访问的热点数据,在项目启动时将这些数据提前查询并保存到redis中
缓存同步
缓存常见三种方式:
设置有效期、同步双写、异步通知
canal
将自己伪装成mysql的一个slave节点,从而监听二进制日志变化。再把得到的变化信息通知给canal的客户端,进而完成对其他数据库的同步