springboot整合redis + redisson

        基于上一篇文章整合数据库连接池和mybatis-plus之后继续开撸,接着整合redis和redisson

springboot整合mybatis-plus+durid数据库连接池_极速小乌龟的博客-CSDN博客在idea中新建项目,选择springbootinitializr,点击next创建项目即可。【项目】创建时记得勾选lombok,springweb。项目能够正常启动并访问,说明第一步项目创建没有问题。在src下创建TestController进行测试。创建test数据库并创建user表。在启动类上添加mapper扫描.成功执行,并且配置插件生效。...https://blog.csdn.net/qq_35771266/article/details/125834909

        在我们开发中我们经常会用到分布式缓存和分布式锁。而这两个功能我们就可以使用redis和redisson来实现。

一、为什么采用分布式锁和分布式缓存

        我们就以分布式锁来讲,因为两者的原因是一样的。

        在之前系统没有采取集群部署,每个项目只有一个应用部署的话,那么我们采取jdk提供的锁也是可以的。因为只有一个应用。使用方式如下:

public static void main(String[] args) {
        ReentrantLock rLock = new ReentrantLock();
        rLock.lock();
        try{
            //业务代码
        }finally {
            rLock.unlock();
        }
    }

但是为什么在集群部署情况下这种锁就不行了呢?我们来画个图说明

 如上图,假设我们现在将应用A部署了两个,然后假设现在有两个用户同时调用了methodA方法,那么在原来但应用的基础上,两个用户进来会因为有一个用户拿不到锁进入等待。但是在集群部署情况下,如果两个用户分别进入了两个服务,一个用户在当前服务加了锁对另一个用户来说,这个锁是完全没有用的。因为完全不在同一个应用。

        基于上述原因,所以我们在集群环境下为了解决这个问题就将锁放到一个公共的地方,让所有的服务在同一个地方来获取锁。这样一来,就解决了在集群环境下锁失效的问题。因为主要是讲整合springboot,所以原理我就不仔细讲了。不明白的可以自己学习一下。

 二、springboot整合redis

1.引入pom

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

2.配置yml文件

扫描二维码关注公众号,回复: 14858191 查看本文章
spring:
  redis:
    host: 127.0.0.1
    port: 6379

如果有密码就加上password

3.编写测试方法

package com.example.sessiondemo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * @description: RedisTestController <br>
 * @date: 2022/7/21 21:55 <br>
 * @author: William <br>
 * @version: 1.0 <br>
 */
@RestController
@RequestMapping("/redis")
public class RedisTestController {

    @Autowired
    StringRedisTemplate redisTemplate;

    /**
     * description: testRedisSet 测试redis设置缓存<br>
     * @version: 1.0 <br>
     * @date: 2022/7/21 21:59 <br>
     * @author: William <br>
     * @return java.lang.String
     */
    @GetMapping("redisSet")
    public String testRedisSet(){
        redisTemplate.opsForValue().set("test:redis:userName","张三",120, TimeUnit.SECONDS);
        return "OK";
    }


    @GetMapping("redisGet")
    public String testRedisGet(){
        String name = redisTemplate.opsForValue().get("test:redis:userName");
        return name;
    }
}

4.启动多个应用

为了测试分布式缓存生效,我们模拟启动两个服务来测试。

在idea中复制应用,修改启动参数

 成功启动后,如下图所示

5.测试缓存是否生效

首先我们在8080应用设置缓存

 成功后我们在redis中查看,如下图所示,说明我们确实设置成功。

 然后我们在8081端口获取缓存数据,如下图所示,在不同的服务中我们也能获取到数据,说明我们基于redis的分布式缓存成功。

 三、springboot整合redisson

1.引入jar包

 <!--redisson-->
 <dependency>
     <groupId>org.redisson</groupId>
     <artifactId>redisson-spring-boot-starter</artifactId>
     <version>3.12.5</version>
 </dependency>

2.编写测试代码

 我是自己写了一个简单的读写锁,场景是这样的:

有两个方法一个方法是修改书本信息,一个方法是读取书本信息。我们为了保证读的数据一定是最新数据,所以使用了读写锁。对锁不太了解的可以自行学习一下读写锁的原理,我就不赘述了。接下来我们直接上代码测试。

package com.example.sessiondemo.controller;

import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @description: TestController <br>
 * @date: 2022/7/17 16:54 <br>
 * @author: William <br>
 * @version: 1.0 <br>
 */
@RestController
@RequestMapping("test/")
public class TestController {


    @Autowired
    RedissonClient redissonClient;

    private final String BOOK_KEY = "test:book:";



    @PutMapping("/updateBook")
    public String updateBook(Long bookId){
        if(bookId == null || bookId<=0){
            return "error";
        }
        String lockKey = BOOK_KEY + bookId;
        RReadWriteLock lock = redissonClient.getReadWriteLock(lockKey);
        RLock rLock = lock.writeLock();
        rLock.lock();
        try {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }finally {
            rLock.unlock();
        }
        return "OK";
    }



    @GetMapping("getBook")
    public String getBook(Long bookId){
        if(bookId == null || bookId<=0){
            return "error";
        }
        String lockKey = BOOK_KEY + bookId;
        RReadWriteLock lock = redissonClient.getReadWriteLock(lockKey);
        RLock rLock = lock.readLock();
        rLock.lock();
        try {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }finally {
            rLock.unlock();
        }
        return "OK";
    }

}

3.启动两个应用测试

 测试结果如下:我们同时访问8080和8081的两个接口,都能正常响应,没有相互阻塞。

但是当我们先访问了修改接口,再去访问读的接口,服务就会被阻塞。在修改结束后我们读取数据的服务才会得到响应。说明分布式锁整合成功。

 

 

 

 好了,以上就是整合过程。如果需要源码的同学可以加微信联系获取源码。

猜你喜欢

转载自blog.csdn.net/qq_35771266/article/details/125921432