SpringBoot之redis数据缓存管理,整合机关缓存

项目中整合redis

前期安装好了redis,我们就可以准备整合啦

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId></dependency>

package com.daiwei.config;import java.lang.reflect.Method;import org.springframework.beans.factory.annotation.Value;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.cache.annotation.CachingConfigurerSupport;import org.springframework.cache.annotation.EnableCaching;import org.springframework.cache.interceptor.KeyGenerator;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;@Configuration@EnableCachingpublic class RedisConfig extends CachingConfigurerSupport{ @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private int timeout; //自定义缓存key生成策略 @Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); String[] value = new String[1]; // sb.append(target.getClass().getName; // sb.append(":" + method.getName; Cacheable cacheable = method.getAnnotation(Cacheable.class); if (cacheable != null) { value = cacheable.value(); } CachePut cachePut = method.getAnnotation(CachePut.class); if (cachePut != null) { value = cachePut.value(); } CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class); if (cacheEvict != null) { value = cacheEvict.value(); } sb.append; for (Object obj : params) { sb.append(":" + obj.toString; } return sb.toString(); } }; } //缓存管理器 @Bean public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); //设置缓存过期时间 cacheManager.setDefaultExpiration; return cacheManager; } @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory){ StringRedisTemplate template = new StringRedisTemplate; setSerializer;//设置序列化工具 template.afterPropertiesSet(); return template; } //序列化不限制long private void setSerializer(StringRedisTemplate template){ @SuppressWarnings({ "rawtypes", "unchecked" }) Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper; template.setValueSerializer(jackson2JsonRedisSerializer); }}

package com.daiwei;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.builder.SpringApplicationBuilder;import org.springframework.boot.context.web.SpringBootServletInitializer;import org.springframework.cache.annotation.EnableCaching;@SpringBootApplication@EnableCachingpublic class StartApplication extends SpringBootServletInitializer{ @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(StartApplication.class); } public static void main(String[] args) { SpringApplication.run(StartApplication.class, args); }}

 @Cacheable(value="testallCache") @RequestMapping("/getUser/{id}") public Map<String,Object> getUser(@PathVariable long id) { Map<String,Object> user=BeanKit.describe(userService.findById, "roles"); System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功"); return user; }

输入地址访问

图片 111.png图片 212.png

看后台的日志可以看出 第一次访问的时候 是调用hibernate
去访问数据库的,然后再刷一遍,是不是发现秒开,而且控制台也没有日志记录,说明这次的请求访问的是缓存,而不是去访问数据库了,小小的测试成功了,同时你可以根据可视化工具去看下redis里面的储存情况:

图片 313.png具体的实际操作请看下一章。

【SpringBoot2.0文章汇总目录,java多线程教程文章汇总
长期更新系列】请多多支持

参考地址:http://www.cnblogs.com/EmptyFS/p/6595968.html
多数文字来源:http://www.cnblogs.com/EmptyFS/p/6595968.html
准备工作:

【SpringBoot2.0系列01】初识SpringBoot【SpringBoot2.0系列02】SpringBoot之使用Thymeleaf视图模板【SpringBoot2.0系列03】SpringBoot之使用freemark视图模板【SpringBoot2.0系列04】SpringBoot之使用JPA完成简单的rest
api【SpringBoot2.0系列05】SpringBoot之整合Mybatis【SpringBoot2.0系列06】SpringBoot之多数据源动态切换数据源【SpringBoot2.0系列07】SpringBoot之redis使用(Lettuce版本)【SpringBoot2.0系列08】SpringBoot之redis数据缓存管理

图片 4

虚拟机IP图示

实现数据缓存,如果缓存中没有数据,则从数据库查询,并且写入redis缓存,如果redis缓存中有数据,则直接从redis中读取,同事删除更新等操作也需要维护缓存。本文基于前面两篇文章而来,部分重复就不贴。

首先升级或安装一下pip(新安装的系统还没有pip需要安装或升级,默认一般是是使用pip2进行)

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- redis依赖commons-pool 这个依赖一定要添加 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> </dependencies>
前提:
curl https://bootstrap.pypa.io/get-pip.py | python 
yum intsall wget

yml配置如下:

第1步:定位对应下载安装包目录
mkdir -p /data/bak
cd /data/bak/
server: port: 8989spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8 username: root password: root redis: host: 127.0.0.1 port: 6379 lettuce: pool: max-idle: 8 min-idle: 0 max-active: 8mybatis: config-location: classpath:/mybatis/config/mybatis-config.xml mapper-locations: classpath:/mybatis/mapper/*.xmllogging: level: com: yukong: chapter7: repository: debug
第2步:下载安装包

登录http://download.redis.io/releases/
选择需要安装的版本并下载

wget http://download.redis.io/releases/redis-3.2.8.tar.gz

这里就是配置了一下mybati跟redis
但是比之前多了一点就是配置了我们com.yukong.chapter.repository包的日志级别为debug这样sql就会打印出来。然后之前一样的配置一下RedisConfig.java

第3步:编译安装

创建redis安装文件夹:

mkdir /usr/local/redis

解压缩安装包:

tar -zxvf redis-3.2.8.tar.gz

进入安装包文件夹:

cd redis-3.2.8

执行安装命令:

make PREFIX=/usr/local/redis/ install

(1)提示make[1]: Entering directory `/root/redis-2.8.17/src‘
CC adlist.o,

图片 5

image.png

原因是:
未安装gcc,使用命令安装gcc:
yum install gcc

(2)提示make

图片 6

image.png

解决:
将make改为make MALLOC=libc,推测是因为编译库的问题。
命令:make MALLOC=libc PREFIX=/usr/local/redis/ install

PS:上面安装命令执行完成,/usr/local/redis/目录下就有个bin目录,里面放的是redis服务相关的可执行命令

复制redis配置文件到指定目录:

cp redis.conf /usr/local/redis

其他补充:

cd /usr/local/src
wget http://download.redis.io/releases/redis-3.0.5.tar.gz
tar xf redis-3.0.5.tar.gz
cd redis-3.0.5
make
make install
#(可用make PREFIX=/usr/local/redis install 安装到指定的路径下面 )  
cp utils/redis_init_script /etc/init.d/redis
chmod a+x /etc/init.d/redis
mkdir /etc/redis
cp redis.conf /etc/redis/
 /** * @author xiongping22369 * @date 2018/8/20 15:33 * @description redis配置 配置序列化方式以及缓存管理器 @EnableCaching 开启缓存 */@EnableCaching@Configuration@AutoConfigureAfter(RedisAutoConfiguration.class)public class RedisConfig { /** * 配置自定义redisTemplate * * @param connectionFactory * @return */ @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); template.setValueSerializer(jackson2JsonRedisSerializer; //使用StringRedisSerializer来序列化和反序列化redis的key值 template.setKeySerializer(new StringRedisSerializer; template.setHashKeySerializer(new StringRedisSerializer; template.setHashValueSerializer(jackson2JsonRedisSerializer; template.afterPropertiesSet(); return template; } /** * json序列化 * @return */ @Bean public RedisSerializer<Object> jackson2JsonRedisSerializer() { //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); serializer.setObjectMapper; return serializer; } /** * 配置缓存管理器 * @param redisConnectionFactory * @return */ @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { // 生成一个默认配置,通过config对象即可对缓存进行自定义配置 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); // 设置缓存的默认过期时间,也是使用Duration设置 config = config.entryTtl(Duration.ofMinutes // 设置 key为string序列化 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer // 设置value为json序列化 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer // 不缓存空值 .disableCachingNullValues(); // 设置一个初始化的缓存空间set集合 Set<String> cacheNames = new HashSet<>(); cacheNames.add("timeGroup"); cacheNames.add; // 对每个缓存空间应用不同的配置 Map<String, RedisCacheConfiguration> configMap = new HashMap<>(); configMap.put("timeGroup", config); configMap.put("user", config.entryTtl(Duration.ofSeconds; // 使用自定义的缓存配置初始化一个cacheManager RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory) // 一定要先调用该方法设置初始化的缓存名,再初始化相关的配置 .initialCacheNames(cacheNames) .withInitialCacheConfigurations(configMap) .build(); return cacheManager; }}
第4步:配置远程访问

修改配置文件:/usr/local/redis/redis.conf

bind 127.0.0.1 ---->bind 0.0.0.0 

图片 7

image.png

注:redis服务访问限制设置。使用127.0.0.1表示只能本机访问;如果用的是服务器在局域网里的ip:192.168.1.128,即表示局域网内的ip都可以访问;如果使用0.0.0.0由表示所有地址都可以访问。需要绑定多个时,可以添加多个bind
xxx.xxx.xxx.xxx

daemonize no ----->daemonize yes 

图片 8

image.png

注:PS:daemonize no 这个修改为daemonize yes 开启守护进程

 logfile ''----->logfile /data/log/redis.log

注:logfile ”’ .修改日志保存路径

dir ./  ----->dir /usr/local/redis/data #配置持久化文件存放位置

图片 9

image.png

注:dir ./ 这里需要修改为dir /usr/local/redis/data
不然redis数据会存储到root文件夹下面

requirepass xxxxx  ----->requirepass 你设置的远程连接的密码信息

图片 10

image.png

图片 11

image.png

注:随便找个位置增加requirepass
xxxxx,可以增加访问redis访问密码,如果你的redis对外网开放,这个密码一样要足够长足够复制,不然以redis的访问速度,比较容易被人破解

maxmemory 1024M

注:可以增加maxmemory 1024M来限制redis占用内容大小,也可以不限制

第4步:修改完成后,创建redis数据存储文件夹

mkdir /usr/local/redis/data

相比上节,我们多配置了一个缓存管理器,在springboot2中配置缓存管理是新的api也就是builder模式构建。然后通过@EnableCaching
开启缓存注解。然后需要注意的是
你在redistemplate中的配置的key,value序列化方法并不会生效,需要在RedisCacheConfiguration中单独配置。

第5步:启动redis服务端(启动时指定配置文件)
/usr/local/redis/bin/redis-server /usr/local/redis/redis.conf
ps -ef |grep redis # 查看启动情况

图片 12

image.png

一般缓存在service层中使用。代码如下

第6步:处理防火墙或开启端口6379

PS:生产环境上一般不建议直接的关闭防火墙

systemctl stop firewalld #关闭防火墙
systemctl enable firewalld #开机启用防火墙
systemctl start firewalld #开启防火墙
firewall-cmd --add-service=redis --permanent   #开放redis 服务
firewall-cmd --zone=public --add-port=6379/tcp --permanent #或者可以直接添加端口
firewall-cmd --reload # 重载防火墙
firewall-cmd --list-ports #查看占用端口
/** * @author yukong * @date 2018/8/20 14:35 * @description user业务层实现 */@Servicepublic class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User saveUser(User user) { userMapper.save; // 返回用户信息,带id return user; } /** * @CacheEvict 应用到删除数据的方法上,调用方法时会从缓存中删除对应key的数据 * condition 与unless相反,只有表达式为真才会执行。 * @param id 主键id * @return */ @CacheEvict(value = "user", key = "#root.args[0]", condition = "#result eq true") @Override public Boolean removeUser { // 如果删除记录不为1 则是失败 return userMapper.deleteById == 1; } /** * @Cacheable 应用到读取数据的方法上,先从缓存中读取,如果没有再从DB获取数据,然后把数据添加到缓存中 * key 缓存在redis中的key * unless 表示条件表达式成立的话不放入缓存 * @param id 主键id * @return */ @Cacheable(value = "user", key = "#root.args[0]", unless = "#result eq null ") @Override public User getById { return userMapper.selectById; } /** * @CachePut 应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存 * @param user 用户信息 * @return */ @CachePut(value = "user", key = "#root.args[0]", unless = "#user eq null ") @Override public User updateUser(User user) { userMapper.update; return user; }}
第7步:使用客户端进行远程连接

图片 13

image.png

其中每个注解的作用都写在注释中了。

注意事项:

线上环境一般不会开启redis的远程,不然容易被别人拿来挖矿!
详情可查看:

然后我们编写一下对应的rest接口来测试

========================================================
/** * @author yukong * @date 2018/8/20 15:27 * @description user控制器 */@RequestMapping@RestControllerpublic class UserController { @Autowired private UserService userService; @PostMapping public User save(@RequestBody User user) { return userService.saveUser; } @PutMapping public User update(@RequestBody User user) { return userService.updateUser; } @DeleteMapping(value = "/id/{id}") public Boolean delete(@PathVariable Long id) { return userService.removeUser; } @GetMapping(value = "/id/{id}") public User findById (@PathVariable Long id) { return userService.getById; }}
补充:

生成软连接:

ln -s /usr/local/redis/bin/redis-server /usr/bin/redis-server
ln -s /usr/local/redis/bin/redis-cli /usr/bin/redis-cli

启动服务

redis-server /usr/bin/redis-server

关闭服务

redis-cli shutdown

客户端启动

redis-cli

启动程序。首先访问http://localhost:8989/user/id/2成功请求数据
并且控制台打印sql

========================================================

图片 14image.png查看redis是否成功缓存数据。图片 15image.png

其他配置修改:

成功缓存数据,并且key为主键id。再次刷新访问。

Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
daemonize yes 

PS:如果Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定

pidfile /var/run/redis.pid

图片 16image.png并没有打印sql,说明缓存生效,数据是从缓存中去的,而没有去访问数据库。至于修改跟删除两个注解就交给大家测试。关于本文,其中mybatis相关的代码并没有贴出,全部代码放在github上,地址如下。最后配套教程的代码全部在这里github

开启aof持久化
appendonly yes 
appendfsync everysec

最后大家关注一下我的个人公众号把。

绑定的主机地址或开启远程访问
bind 0.0.0.0 

图片 17公众号

把redis安装为服务,设置开机启动
vim /lib/systemd/system/redis.service
加入以下内容:
[Unit]
Description=redis service
Wants=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
[Install]
WantedBy=multi-user.target
重新载入
systemctl daemon-relaod
设置开机启动
systemctl enable redis
启动redis
systemctl start redis
开启防火墙的3306端口
firewall-cmd --add-port=3306/tcp --permanent
firewall-cmd --reload
当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
timeout 300
指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
loglevel verbose

修改数据库的数量,reidis默认数据库为0,可以使用SELECT
<dbid>连接上指定数据库id

databases 16
指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
save

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website