SpringBoot学习笔记9-SpringBoot集成Redis

【Android免费音乐下载app】【佳语音乐下载】建议最少2.0.3版本。最新版本:
https://gitlab.com/gaopinqiang/checkversion/raw/master/Music_Download.apk

Redis Window版本下载地址:https://github.com/microsoftarchive/redis/releases
当前下载的是最新 3.2.100 版本,比linux要落后好多。(没有折腾VM下装linux,有时间可以搞个linux虚拟机)
SpringBoot学习笔记9-SpringBoot集成Redis_第1张图片

Redis可视化工具:Redis Desktop Manager
下载地址:https://github.com/qishibo/AnotherRedisDesktopManager/releases
如果只是简单的查看,直接用自带的redis-cli.exe就可以。也可以使用Redis自带命令查看

启动redis服务(2种方式):

  • a.在redis解压目录运行cmd,启动redis命令(cmd关闭,服务停止)
    【redis-server.exe】默认配置启动
    【redis-server.exe redis.windows-service.conf】配置文件启动
    SpringBoot学习笔记9-SpringBoot集成Redis_第2张图片

  • b.将redis服务安装到系统,安装服务后启动

    【redis-server.exe --service-install redis.windows-service.conf】(会安装到系统的服务中)
    【redis-server.exe --service-start】(启动服务)
    【redis-server --service-stop】(停止服务)

设置redis密码:
将redis.windows-service.conf文件中的配置修改下。
# requirepass foobared
修改成:
requirepass 123456
在通过加载配置文件启动,通过redis-cli.exe查看是否生效
【auth 123456】输入密码连接
SpringBoot学习笔记9-SpringBoot集成Redis_第3张图片

Redis服务启动好,SpringBoot可以集成Redis开发了。

一、SpringBoot 集成 Redis 的步骤如下:(前提启动了Redis服务)

1、在pom.xml中配置相关的jar依赖;

	
	<dependency>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-data-redisartifactId>
	dependency>

2、在Springboot核心配置文件application.properties中配置redis连接信息:

	spring.redis.host=127.0.0.1
	spring.redis.port=6379
	spring.redis.password=123456

3、配置了上面的步骤,Spring boot将自动配置RedisTemplate,在需要操作redis的类中注入redisTemplate;
在使用的类中注入:(ServiceImpl中)
@Autowired
private RedisTemplate redisTemplate;

StudentServiceImpl.java
	package com.example.mybatis.service.impl;

	import com.example.mybatis.mapper.StudentMapper;
	import com.example.mybatis.model.Student;
	import com.example.mybatis.service.StudentService;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.data.redis.core.RedisTemplate;
	import org.springframework.stereotype.Service;

	import java.util.List;
	import java.util.Map;

	@Service
	public class StudentServiceImpl implements StudentService {

		@Autowired
		private StudentMapper studentMapper;

		/** 注入springboot自动配置好的RedisTemplate */
		@Autowired
		private RedisTemplate<Object, Object> redisTemplate;

		@Override
		public List<Map<String, Object>> getStudent(String id) {
			return studentMapper.getStudent(id);
		}

		@Override
		public List<Student> getStudent1(String id) {
			List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");

			if(null == studentList){
				studentList = studentMapper.getStudent1(id);
				redisTemplate.opsForValue().set("allStudents",studentList);
				System.out.println("查询数据库,将数据存入redis缓存");
			}else{
				System.out.println("查询Redis缓存");
			}
			return studentList;
		}

		@Override
		public int updateById(Student student) {
			return studentMapper.updateById(student);
		}
	}

SpringBoot帮我们注入的redisTemplate类,泛型里面只能写
测试运行截图如下:
SpringBoot学习笔记9-SpringBoot集成Redis_第4张图片

这个时候通过Redis的可视化工具,看到已经存入缓存数据。但是键值会出现Unicode编码

	//字符串序列化器
	RedisSerializer redisSerializer = new StringRedisSerializer();
	redisTemplate.setKeySerializer(redisSerializer);

SpringBoot学习笔记9-SpringBoot集成Redis_第5张图片

二、Redis高并发条件下的缓存穿透问题。
在一个方法中,有很多人同时请求时候,都会去操作数据库,并没有读取到缓存。比如10000人同时请求,就会请求10000次数据库。而我们只希望请求一次数据库。
出现缓存穿透问题截图如下:
SpringBoot学习笔记9-SpringBoot集成Redis_第6张图片

解决的方式就是使用syncronized同步锁。
可以直接在方法上加锁。但是这样会牺牲效率,每次多个请求同时过来,只能一个一个处理。(不推荐)

下面介绍推荐的方式(双重检测锁),代码如下:

StudentServiceImpl:
    @Override
    public List<Student> getStudent1(String id, String name) {
//        return studentMapper.getStudent1("1","qiang");
//        List studentList = (List) redisTemplate.opsForValue().get("allStudents");

        //字符串序列化器
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);

        List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");
        //双重检测锁
        if(null == studentList){//第一次请求才会为空,后面不管多少个人同时请求,都不会走到syncronized代码处。
            synchronized (this){
                //从redis获取下
                studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");

                if(null == studentList){//比如1w人同时请求,第一个人才会使用数据库,后面的9999人都是使用缓存数据
                    studentList = studentMapper.getStudent1(id,"qiang");
                    redisTemplate.opsForValue().set("allStudents",studentList);
                    System.out.println("查询数据库,将数据存入redis缓存");
                }else{
                    System.out.println("查询Redis缓存");
                }
            }
        }

        return studentList;
    }

测试:

StudentController:
@RequestMapping("/getStudent1")
    public @ResponseBody String getStudent1(){

        //测试Redis缓存
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                studentService.getStudent1("1","qiang");
            }
        };
        //多线程测试下Redis缓存穿透问题
        ExecutorService executorService = Executors.newFixedThreadPool(25);
        for (int i = 0; i < 10000; i++) {
            executorService.submit(runnable);
        }

        List<Student> student = studentService.getStudent1("1","qiang");
        return student.toString();
    }

成功截图如下:
SpringBoot学习笔记9-SpringBoot集成Redis_第7张图片

哨兵模式redis集群配置:(了解下即可,实际开发中再深入研究)
redis:
password: 123456
sentinel:
master: mymaster
nodes: 127.0.0.1:26380,127.0.0.1:26382,127.0.0.1:26384

你可能感兴趣的:(SpringBoot学习,springboot,redis)