写点什么

Java 开发之如何连接 Redis

  • 2021 年 12 月 02 日
  • 本文字数:4756 字

    阅读完需:约 16 分钟

​工程目录



    <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;
复制代码


}

基本用法


@Testpublic 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();}

@Testpublic 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();}
复制代码


连接池的使用


@Testpublic 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;}
复制代码


}


公共类的使用


@Testpublic 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);}

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

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


以 byte[] 形式获取对象


@Testpublic 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();}

@Testpublic 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 服务一次性的将全部的返回结果响应给客户端。

@Testpublic 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.rdbsave 900 1sava 300 10save 60 10000

aof

appendonly yesappendfilename "redis.aof"appendfsync everysec


认证连接


redis-cli,命令 auth admin。


图形化界面,连接时添加上密码。


java,代码 jedis.auth(admin);


Redis 数据持久化机制。


RDB 是 Redis 默认的持久化机制。java培训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,会根据操作系统不同,环境的不同,在一定时间内执行一次持久化。


原创作者:黎昏


用户头像

关注尚硅谷,轻松学IT 2021.11.23 加入

还未添加个人简介

评论

发布
暂无评论
Java开发之如何连接Redis