工程目录
<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,会根据操作系统不同,环境的不同,在一定时间内执行一次持久化。
原创作者:黎昏
评论