0%

【Redis】Java连接Redis(Jedis)

Java使用Jedis来进行对Redis的连接

1. Java连接Redis

1.1 修改配置文件

  • (1)无密码连接
    • bind 127.0.0.1注释掉,bind [ip]配置是只允许当前ip地址使用redis,即liunx本机,使得其他机器无法访问使用。
    • 将保护模式关闭protected-mode no
  • (2)需要密码进行连接
    • bind 127.0.0.1注释掉
    • 设置密码requirepass [密码]

1.2 查看linux的ip地址

1
2
3
sudo apt install net-tools  --安装网络工具(不同版本linux,语法不同)

ifconfig -a --查看所有网络信息

1.3 Java连接

  • (1)jar包导入
    • jedis.xxxx.jar
1
2
3
4
5
6
<!-- Maven依赖:Jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.4.1</version>
</dependency>
  • (2)代码测试
1
2
3
4
5
6
7
//无密码连接
public class ConnectTest {
public static void main(String[] args) {
Jedis jedis = new Jedis("192.168.xx.xx", 6379);
System.out.println(jedis.ping()); //返回"PONG"表示连接成功
}
}
1
2
3
4
5
6
7
8
//密码连接
public class ConnectTest {
public static void main(String[] args) {
Jedis jedis = new Jedis("192.168.xx.xx", 6379);
jedis.auth("123456"); //身份验证
System.out.println(jedis.ping()); //返回"PONG"表示连接成功
}
}

2. Jedis常用API

  • Jedis的API就是redis的命令,参数都是一样,所以直接参考Redis的命令那一章节的内容进行使用即可

3. Jedis事务使用

3.1 正常使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void normalTest() {
Jedis jedis = new Jedis("192.168.xx.xx", 6379);
//开启事务
Transaction transaction = jedis.multi();

//业务逻辑
transaction.decrBy("balance", 10);
transaction.incrBy("debt", 10);

//执行事务
transaction.exec();
//放弃执行
//transaction.discard();
}

3.2 加锁使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void lockTest() {
Jedis jedis = new Jedis("192.168.85.130", 6379);
//监控"balance"
jedis.watch("balance");

//事务开始前数据发生修改
jedis.set("balance", "500"); //若发生此情况,执行不会报错,但事务不会执行,自动放弃

//开启事务
Transaction transaction = jedis.multi();

//业务逻辑
transaction.decrBy("balance", 10);
transaction.incrBy("debt", 10);

//执行事务
transaction.exec();
}

4. Jedis主从复制

  • 一般不会使用Java来设置从机,一般都会在linux上设置好,再来使用,一下内容作为了解即可
  • (1)开启两个主机
    • 记得修改配置,让其他机器也能访问Redis
  • (2)Java代码实现主从复制
1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void replicationTest() {
Jedis master = new Jedis("192.168.xx.xx", 6379);
Jedis slave = new Jedis("192.168.xx.xx", 6380);

//绑定从机
slave.slaveof("192.168.xx.xx", 6379);

//主写从读
master.set("message", "this is master's message");
System.out.println(slave.get("message"));
}
  • (3)去linux上重新查看信息

5. JedisPool使用

  • 池子的使用一般都封装为一个工具类

5.1 依赖导入

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.4.1</version>
</dependency>

<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>

5.2 工具类封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//单例模式
public class JedisPoolUtil{

private static volatile JedisPool jedisPool = null;

//构造器私有化
private JedisPoolUtil() {};

//用静态方法来构造
public static JedisPool getJedisPoolInstance() {
if(jedisPool == null) {
//同步
synchronized (JedisPoolUtil.class) {
//进入同步后,还是为空,就才创建实例【有可能在判断是否为空后,没进同步前,另外一个线程创建一个实例】
if (jedisPool == null) {
//池配置
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(1000); //控制一个pool最大可分配多少个Jedis实例
poolConfig.setMaxIdle(32); //控制一个pool最多有多少个Idle(空闲的)jedis实例
poolConfig.setMaxWaitMillis(100*1000); //当borrow一个jedis实例时,最大的等待时间
poolConfig.setTestOnBorrow(true); //获取一个jedis实例时是否检查连接可用性
//创建池子
jedisPool = new JedisPool(poolConfig, "192.168.85.130", 6379);
}
}
}
return jedisPool;
}

//释放资源
public static void release(Jedis jedis) {
if(jedis != null) {
//jedisPool.returnSourceObject(jedis); //方法属性变成protected,无法调用了
jedis.close();
}
}
}

5.3 JedisPoolConfig介绍

属性 解释
maxTotal 控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted
maxIdle 控制一个pool最多有多少个状态为idle(空闲)的jedis实例
whenExhaustedAction 表示当pool中的jedis实例都被allocated完时,pool要采取的操作;默认有三种。WHEN_EXHAUSTED_FAIL –> 表示无jedis实例时,直接抛出NoSuchElementException;WHEN_EXHAUSTED_BLOCK –> 则表示阻塞住,或者达到maxWait时抛出JedisConnectionException;WHEN_EXHAUSTED_GROW –> 则表示新建一个jedis实例,也就说设置的maxActive无用;
MaxWaitMillis 表示当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛JedisConnectionException;
testOnBorrow 获得一个jedis实例的时候是否检查连接可用性(ping());如果为true,则得到的jedis实例均是可用的;
testOnReturn return 一个jedis实例给pool时,是否检查连接可用性(ping());
testWhileIdle 如果为true,表示有一个idle object evitor线程对idle object进行扫描,如果validate失败,此object会被从pool中drop掉;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义;
timeBetweenEvictionRunsMillis 表示idle object evitor两次扫描之间要sleep的毫秒数;
numTestsPerEvictionRun 表示idle object evitor每次扫描的最多的对象数
minEvictableIdleTimeMillis 表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
softMinEvictableIdleTimeMillis 在minEvictableIdleTimeMillis基础上,加入了至少minIdle个对象已经在pool里面了。如果为-1,evicted不会根据idle time驱逐任何对象。如果minEvictableIdleTimeMillis>0,则此项设置无意义,且只有在timeBetweenEvictionRunsMillis大于0时才有意义
lifo borrowObject返回对象时,是采用DEFAULT_LIFO(last in first out,即类似cache的最频繁使用队列),如果为False,则表示FIFO队列

5.4 工具类使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) {
Jedis resource = null;
try {
//获取线程池
JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance();
//获取Jedis实例
resource = jedisPoolInstance.getResource();
//Jedis业务逻辑
resource.set("message", "hello JedisPool");
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放Jedis
JedisPoolUtil.release(resource);
}
}