工程目录
<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();
}
@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();
}
复制代码
连接池的使用
@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);
}
@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[] 形式获取对象
@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();
}
@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 服务一次性的将全部的返回结果响应给客户端。
@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,会根据操作系统不同,环境的不同,在一定时间内执行一次持久化。
原创作者:黎昏
评论