Redis(二)——SpringDataRedis、SpringCache + Redis(使用缓存、key的生成器、更新 / 删除缓存、公共配置)、Session共享、nginx(前后端分离部署)
SpringBoot 操作 Redis有两种方案:
1、Spring Data Redis
2、Spring Cache
当然可以直接用 jedis 、lettuce 操作,这个上篇文章讲了,就不说了。
一、Spring Data Redis
1、前期准备
依赖导入:
然后文件配置:
2、使用 Spring Data Redis
a、序列化和反序列化
运行后看结果:
此时看下 redis 里面:
可以看到一个显示的 name,另外一个跟这个显示的不同。因为 ls 用的是 redisTemplate ,这里把对象存到 redis中,。以后取出来也要恢复成对象,那么这里要做的一件事是序列化和反序列化。
点进去查看部分源码:
可以发现序列化的方案有好几种。各自有各自对应的序列化方案。
b、手动序列化字符串(不使用 redis 默认的序列化方案)
且源码中写着,如果我们没有自己配序列化方案,会默认使用 redis 提供的:
所以我们可以自己实现和配置序列化:
然后测试一下:
结果:
这里之所以是 zs,是因为存进去的不是 name,而是序列化之后的:
序列化之后的就是这个玩意,所以 redis 直接把这个拿去 get 了,所以获取的是 zs。所以这里需要先清空一下缓存。
代码:
结果:
所以这时才是 lisi。
如果要序列化对象则不能使用这种类型,会报类型错误异常。
c、序列化对象
这里新建一个实体类,测试对象,如果不序列化,这里也会报错,显示没有序列化,所以这里要序列化:
序列化其实就是把对象变成字符串,反序列化就是把字符串转化对象。
然后测试代码:
然后结果:
一旦这个 book 类里面有任何变化,就无法反序列化回来。
二、Spring cache + Redis
1、前期准备
配置文件配置:
接着实体类:
2、使用缓存
a、使用缓存
首先是启动类开启缓存:
然后是 service 层(这里为了省事没有设立 mapper 层):
这里就是缓存策略 +::+ 方法参数组成的字符串
上面的 c1 是缓存的名字,缓存的名字在 properties 配置文件里面设置:
这里调用两次同一个方法,测试一下:
很明显,输出的结果跟代码不一致,因为第一次执行这个方法的时候,该方法的返回值已经缓存起来,第二次在调用的时候,会直接去缓存里面拿,所以两次的结果都一致。这一次的运行只执行了一次方法,如果再执行一次,方法会一次都不执行。
需要每次执行参数不同才不会调用缓存里面已经有的数据。
比如这样:
b、指定某些参数作为缓存的 key
这时再运行看结果:
很明显,这时只是用 id 作为缓存的 key。
除了这个还有其他的也可以作为缓存的 key:
3、key 的生成器——keyGenerator
还可以自定义 redis 缓存的 key 的格式:
然后使用:
结果去 redis 中看看:
4、更新缓存——@CachePut
按照上面的写法,如果查询完之后,调用更新方法更新数据,再一次查询,此时查询出来的数据还是以前的数据,而不是更新后的数据。
所以这时就不应该去查缓存,而是去数据库里面查询数据。那么同样的有办法把更新的数据放到缓存中:
测试代码:
5、清空缓存,删除数据库数据——@CacheEvict
6、公共配置——@CacheConfig
三、Redis 做 Session 共享
1、引言和介绍
像是大型网站,肯定是部署了很多服务器的。一般哪些服务器压力小就会分配访问的用户去哪台服务器。如果用户访问网站进了 A 服务器,做了登录校验,此时 A 服务器上有了用户的 session 信息。下次用户再访问,进了其他服务器,那么这时其他的服务器就没有用户的信息,用户需要再一次的进行校验。这明显是不合理的。那么解决这种问题的方法有很多。
目前主流的办法是 session 共享。主要是再设置一个服务器,这个服务器专门做 session 操作,只要涉及到 session 的操作都来这个服务器:
session 中很多需要的操作或者特性和 redis很像,或者说 redis 可以满足,所以用 redis 代替 session 是非常适合的,而且性能也很好。
2、前期准备
依赖导入:
这个 Spring Session 是基于 Spring 的 AOP 思想,封装了 session 操作,可以做到对 session 操作的透明化,加了这个依赖,以后操作把 session 存入到 redis 时,不需要去管,会自动的帮我们把 session 存入到 redis 中,以前怎么操作 session ,现在就怎么操作,因为内部帮我们处理了。
到目前为止就可以了,其他的也不需要配置了。
3、测试
那么就写两个接口来测试一下:
然后网页测试:
然后查看 redis 中:
然后访问另外一个接口:
可以自行手动测试打包后在 linux 中开两个服务,两个端口,运行项目,一个端口访问一个接口,另一个端口访问另一个接口。博主测试是可以成功共享 session 的。
四、nginx
1、介绍
可以做动静分离,前后端分离部署。
负载均衡是内部有个转发策略,可以分发流量到不同的服务器中去:
2、安装和启动 nginx
3、配置 nginx
这里配置上游服务器 aaa.bbb 是名字,名字随便起。
上图中配置红色框框处即可。
4、前后端分离部署
SpringBoot打包(注意链接数据库的 url 和端口)。
打包前 Security 配置文件里面加这么一段:
然后前段 vue打包,在 vue 项目文件夹下按住 shift 点击空白处右键,运行 PowerShell,执行命令:npm run build
打包成功后会多一个叫 dist 的文件夹。
把上面两个打包成功的玩意拉到 linux 中,
如果是前后端不分离部署的话,dist 文件夹扔到 SpringBoot 中的 static 文件夹下即可。
如果是前后端分离部署(其实也就是动静分离),就把打包好的前端项目 dist 放到 nginx 中的一个地方去:如果是请求的是静态资源,就直接从里面拿出来返回;如果请求的是接口,就转发到 upstream 里面去。
因为这里都是向 nginx 请求,所以也不存在跨域问题。
这里建议静态资源放到 nginx 中的 /usr/local/nginx/html 文件夹中去,因为这个 html 文件夹是一定有操作权限的。
然后在 /usr/local/nginx/conf 文件夹中的 nginx.conf 需要改下配置:
拦截完所有请求后,还需要给静态资源放行:
要的自取:
location ~ .*\.(js|css|ico|png|jpg|jpeg|eot|svg|ttf|woff|html|txt|pdf|) {
root /usr/local/nginx/html/;#所有静态文件直接读取硬盘
expires 30d; #缓存30天
}
这么一来就可以了。
到这就搞完了,重启 nginx:
然后启动 SpringBoot 项目即可。到此,前后端分离部署就算完成了。