Jedis直接使用Redis原生命令操作Redis,解决某些命令没有封装

时间:2025-03-21 08:45:34

背景:做项目中需要通过客户端ID关闭客户端连接(对应命令client kill id 12345),但是使用jedis封装的clientKill方法,尝试了很多次,都没有效果。所以就尝试使用反射方式,直接执行Redis命令来解决该问题。

使用Jedis的Connection类直接执行Redis命令

import .*;
import ;
import ;

public class Test {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        try (Connection connection = new Connection("127.0.0.1") /*1.使用Connection连接Redis*/) {
            // 2. 通过反射获取Connection中的sendCommand方法(protected Connection sendCommand(Command cmd, String... args))。
            Method method = ("sendCommand", , String[].class);
            (true); // 设置可以访问private和protected方法
            // 3. 调用connection的sendCommand方法,第二个参数为执行的命令(比如set,get,client等),第三个参数为命令的参数。
            // 3.1 该命令最终对应redis中为: set test-key test-value
            (connection, , new String[]{"test-key", "test-value"});
			// 4.获取Redis的命令执行结果
            (());
        }

    }

}

到Redis中查看

127.0.0.1:6379> get test-key
"test-value"

其中需要注意的点

  1. 为一个枚举,redis的命令从这里面找,比如set,get,client等

  2. () 可以获取到执行结果。获取的结果和使用redis-cli效果一样
    除了这个之外, 还有其他的,如果()。 具体使用哪一个,需要根据命令来决定。
    如果使用的不对,则会抛出类型转换异常。

封装成工具方法

    public static List<String> execRedisCommand(Jedis jedis, String command, String... args) throws InvocationTargetException, IllegalAccessException {
         cmd = (());
        Client client = ();
        Method  method = (, "sendCommand", , String[].class);
        (true);
        (client, cmd, args);
        try {
            List<String> respList = new ArrayList<>();
            Object response = ();
            if (response instanceof List) {
                for (Object itemResp : ((List) response)) {
                    (new String((byte[]) itemResp));
                }
                return respList;
            } else {
                return (new String((byte[]) response));
            }

        } catch (JedisException e) {
            return (());
        }
    }

调用样例

Jedis jedis = new Jedis("127.0.0.1", 6379);
("mypass");
(execRedisCommand(jedis, "set23", "hello", "123").get(0));

maven

<!--MethodUtils来源-->
<dependency>
	<groupId></groupId>
	<artifactId>commons-lang3</artifactId>
	<version>3.9</version>
</dependency>

JedisCluster解决方案

getClusterNodes() 可以获取到所有的Redis节点和其对应的Jedis对象。然后对你想要执行的节点进行上面的操作即可。

若不太明白上面这句话,请先来熟悉Redis集群的工作原理,然后再看就懂了