Java 连接 Redis


在这里插入图片描述

  工程目录。
在这里插入图片描述


// pom.xml

<dependencies>
        <!--    1、 Jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <!--    2、 Junit测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--    3、 Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>

        <!-- 4. 导入spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.10.RELEASE</version>
        </dependency>

        <!--mvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.10.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>



// User.java

@Data
@AllArgsConstructor
@NoArgsConstructor

public class User implements Serializable {

    private String username;

    private String password;

}

  基本用法。


	@Test
    public void t1() {

        Jedis jedis = new Jedis("10.36.144.110", 6379);

        String set = jedis.set("name","zs");
        // "ok"
        System.out.println(set);

        Long lpush = jedis.lpush("list", "a", "b", "c");
        // 1
        System.out.println(lpush);

        // 设置值的同时指定生存时间
        String setex = jedis.setex("sex", 100, "女");
        // "ok"
        System.out.println(setex);

        jedis.close();
    }

    @Test
    public void t2() {

        Jedis jedis = new Jedis("10.36.144.110", 6379);

        String result = jedis.get("name");
        // zs
        System.out.println(result);

        List<String> list = jedis.lrange("list", 0, -1);

        for (String s : list) {
            // c b a
            System.out.println(s);
        }

        // 23
        System.out.println(jedis.ttl("sex"));

        jedis.close();
    }

  连接池的使用。


 	@Test
    public void t3() {

        // 数据库连接池配置
        JedisPoolConfig config = new JedisPoolConfig();
        // 空闲数
        config.setMaxIdle(10);
        config.setMinIdle(5);
        // 最大连接数
        config.setMaxTotal(20);
        // 超时时间
        config.setMaxWaitMillis(3000);

        // 数据库连接池
        JedisPool jedisPool = new JedisPool(config,"10.36.144.110", 6379);
        Jedis jedis = jedisPool.getResource();
        String age = jedis.set("age", "13");
        // "ok"
        System.out.println(age);

        // 关闭的数据库会进入回收池
        jedis.close();
    }

  抽取公共类。封装set、get方法,并且序列化对象。


// RedisUtil.java

public class RedisUtil {

    private static JedisPool pool;

    static {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(10);
        config.setMinIdle(5);
        config.setMaxTotal(20);
        config.setMaxWaitMillis(3000);
        pool = new JedisPool(config,"10.36.144.110", 6379);
    }

    public static Jedis getJedis() {
        return pool.getResource();
    }

    public static void close(Jedis jedis) {
        jedis.close();
    }

    public static String set(String key, String value) {
        Jedis jedis = getJedis();
        String result = jedis.set(key, value);
        close(jedis);
        return result;
    }

    public static String get(String key) {
        Jedis jedis = getJedis();
        String result = jedis.get(key);
        close(jedis);
        return result;
    }

    // 存对象
    public static String set(String key, Object value) {
        Jedis jedis = getJedis();

        // 对象转 string
        String s = JSON.toJSONString(value);
        String result = jedis.set(key, s);
        close(jedis);
        return result;
    }

    // 取对象值并转为对象
    public static <T> T get(String key, Class<T> tClass) {
        Jedis jedis = getJedis();
        String result = jedis.get(key);
        close(jedis);
        T t = JSON.parseObject(result, tClass);
        return t;
    }

}

  公共类的使用。


 	@Test
    public void t4() {
        String res1 = RedisUtil.set("width", "100");
        System.out.println(res1);

        User user = new User("zs", "123");
        String res2 = RedisUtil.set("user", user);
        System.out.println(res2);
    }

    @Test
    public void t5() {
        String result = RedisUtil.get("width");
        System.out.println(result);

        User user = RedisUtil.get("user",User.class);
        System.out.println(user);
    }

  以 byte[] 形式获取对象。


	@Test
    public void t6() {
        Jedis jedis = RedisUtil.getJedis();
        jedis.auth("123");

        User user = new User("ls", "234");
        // 序列化
        byte[] serialize = SerializationUtils.serialize(user);
        String res = jedis.set("user2".getBytes(), serialize);
        System.out.println(res);

        jedis.close();
    }

    @Test
    public void t7() {
        Jedis jedis = RedisUtil.getJedis();
        jedis.auth("123");

        byte[] bytes = jedis.get("user2".getBytes());

        // 反序列化
        User user = (User) SerializationUtils.deserialize(bytes);
        System.out.println(user);

        jedis.close();
    }

  Redis 的管道操作。
  主要解决频繁请求服务器造成的延迟问题。通过Redis的管道,先将命令放到客户端的一个 Pipeline 中,之后一次性将全部命令都发送到 Redis 服务,Redis 服务一次性的将全部的返回结果响应给客户端。


 	@Test
    public void t8() {
        Jedis jedis = RedisUtil.getJedis();

//        long start = System.currentTimeMillis();
//
//        for (int i = 0; i < 10000; i ++) {
//            jedis.incr("zan");
//        }
//
//        long end = System.currentTimeMillis();
//
//        // 12865
//        System.out.println(end - start);

        Pipeline pipelined = jedis.pipelined();
        long start = System.currentTimeMillis();

        for (int i = 0; i < 10000; i ++) {
            pipelined.incr("zan");
        }
        pipelined.syncAndReturnAll();

        long end = System.currentTimeMillis();

        // 324
        System.out.println(end - start);

    }

  Redis 应用。模拟 nginx 连接多台 tomcat 服务器,当一台服务器上登录时,其他服务器通过 cookie 识别其是否已登陆。


// Const.java

public interface Const {
    //30分钟
    int LIVETIME = 60*30;
    //登陆状态标识
    String ISLOGIN="islogin";
}

// RedisUtil.java

// 用于保存用户的登陆状态==>有时间限制
public static String setex(String key,int time,Object value){
        Jedis jedis = getResoucres();
        //把对象序列化为JSON字符串
        String string = JSON.toJSONString(value);
        //操作
        String result = jedis.setex(key, time,string );
        close(jedis);
        return result;
    }

    // 重新设置值生存时间
    public static Long expire(String key ,int time){
        Jedis jedis = getResoucres();
        //操作 重新设置值生存时间
        Long result = jedis.expire(key, time);
        close(jedis);
        return result;
    }


// UserController.java 

@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/login")
    public String login(String username, String password, HttpServletResponse response){
        if (username.equals("admin")&&password.equals("admin")) {
            User u = new User("admin", "admin");

            String uuid = UUID.randomUUID().toString();
            //保存数据到redis 作为登陆的状态
            //使用uuid作为redis保存的key值,为了防止key重复导致覆盖
            RedisUtil.setex(uuid, Const.LIVETIME,u);
            //把uuid的值保存到cookie当中,让其他服务器可以获取uuid来验证登陆状态
            //创建cookie对象
            Cookie cookie=new Cookie(Const.ISLOGIN, uuid);
            //设置cookie的存活时间
            cookie.setMaxAge(Const.LIVETIME);
            //设置作用范围
            cookie.setPath("/");
            //使用response写出cookie给客户端
            response.addCookie(cookie);
            return "ok";
        }
        return "no";
    }
    @RequestMapping("/check")
    public String checkLogin(@CookieValue(Const.ISLOGIN) String uuid){
        /*Cookie[] cookies = request.getCookies();
        String uuid= null;
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(Const.ISLOGIN)) {
                uuid= cookie.getValue();
            }
        }*/
        //cookie有没有uuid存在
        if (uuid!=null){
            User user = RedisUtil.get(uuid, User.class);
            if (user != null) {
                System.out.println(user);
                return "is login";
            }
        }
        return "is not login";
    }
}

  Redis 其他配置。
  docker-compose.yml 映射 Redis 配置文件。


version: '3.1'
services:
  nginx:
    restart: always
    image: daocloud.io/library/nginx:latest
    container_name: nginx
    ports:
      - 80:80
  redis:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 6379:6379
    volumes:
      - /opt/docker_nginx/conf.d/:/etc/nginx/conf.d
      - /opt/docker_nginx/img/:/data/img
      - /opt/docker_nginx/html/:/data/html
      - /opt/docker_nginx/conf/redis.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]


// 关闭 docker
docker-compose down

// 创建文件夹
mkdir conf

// 要自己建立 redis.conf 文件,否则开启 docker 自动创建成文件夹
vi conf/redis.conf

// 开启 docker
docker-compose up -d


# 认证
requirepass admin

# rdb
dbfilename redis.rdb
save 900 1
sava 300 10
save 60 10000

# aof
appendonly yes
appendfilename "redis.aof"
appendfsync everysec

  认证连接。
  redis-cli,命令 auth admin。
  图形化界面,连接时添加上密码。
  java,代码 jedis.auth(admin);

  Redis 数据持久化机制。
  RDB 是 Redis 默认的持久化机制。RDB无法保证数据的绝对安全。
  save 900 1,在900秒内,有1个key改变了,就执行RDB持久化。
  save 300 10,在300秒内,有10个key改变了,就执行RDB持久化。
  save 60 10000,在60秒内,有10000个key改变了,就执行RDB持久化。

  AOF 持久化机制默认是关闭的,Redis 官方推荐同时开启 RDB 和 AOF 持久化,更安全,避免数据丢失。
  AOF 持久化的速度,相对 RDB 较慢的,存储的是一个文本文件,并且会记录每次数据库的操作命令,到了后期文件会比较大,传输困难。
  appendfsync always,每执行一个写操作,立即持久化到AOF文件中,性能比较低。
  appendfsync everysec,每秒执行一次持久化。
  appendfsync no,会根据操作系统不同,环境的不同,在一定时间内执行一次持久化。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值