SpringBoot集成redis

Redis Window版本下载地址:https://github.com/microsoftarchive/redis/releases
当前下载的是最新 3.2.100 版本,比linux要落后好多。(没有折腾VM下装linux,有时间可以搞个linux虚拟机)
在这里插入图片描述

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】配置文件启动
在这里插入图片描述

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】输入密码连接
在这里插入图片描述

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

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

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

	<!-- 加载spring boot redis包 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-redis</artifactId>
	</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<Object, Object> 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类,泛型里面只能写 <String, String>、<Object, Object>
测试运行截图如下:
在这里插入图片描述

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

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

在这里插入图片描述

二、Redis高并发条件下的缓存穿透问题。
在一个方法中,有很多人同时请求时候,都会去操作数据库,并没有读取到缓存。比如10000人同时请求,就会请求10000次数据库。而我们只希望请求一次数据库。
出现缓存穿透问题截图如下:
在这里插入图片描述

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

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

StudentServiceImpl@Override
    public List<Student> getStudent1(String id, String name) {
//        return studentMapper.getStudent1("1","qiang");
//        List<Student> studentList = (List<Student>) 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();
    }

成功截图如下:
在这里插入图片描述

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值