try redis(四) -java 客户端jedis 使用

时间:2021-11-16 17:30:11

不同的计算机语言针对redis,都有自己的客户端。

官网上也列出了客户端的 http://www.redis.io/clients

java客户端如下:

try redis(四) -java 客户端jedis 使用

感觉客户端无非也就是做些连接和拼接命令的事情。所以不费心思比较哪个好了,就选第一个吧。一般第一个应该都是不错的。

选择jedis ,发现他的代码是 GitHub 托管的,开源的。地址为 https://github.com/xetorthio/jedis

找到 maven dependency 

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

将上面这段 xml,拷入 pom.xml 中(maven 依赖)

try redis(四) -java 客户端jedis 使用

try redis(四) -java 客户端jedis 使用发现添加了 jedis-2.6.0.jar 和 commons-pool2-2.0.jar 这两个包。一个应该是核心包,一个appache的pool包,我猜是客户端连接池用到了。具体的还得往下走。

到目前为止,准备工作都ok.跑一个简单的例子如下:

Jedis jedis = new Jedis("10.13.145.75",6379); //默认端口6379
jedis.set("key", "HelloWorld");
String result = jedis.get("HelloWorld");
System.out.println(result);

注意,我这里报连接超时。

try redis(四) -java 客户端jedis 使用

查了下,发现是redis服务器端防火墙造成的 。

service iptables stop
把防火墙关了,再执行下代码。ok.完成了。


代码很简单,直接看下 jedis 的源代码是怎么实现的吧。

当调用 jedis.set("key", "HelloWorld"); 的时候


Jedis.class 中,调用了String set(final String key, String value)

其中client  是客户端对象

/**
* Set the string value as value of the key. The string can't be longer than
* 1073741824 bytes (1 GB).
* <p>
* Time complexity: O(1)
*
* @param key
* @param value
* @return Status code reply
*/
public String set(final String key, String value) {
checkIsInMulti();
client.set(key, value);
return client.getStatusCodeReply();
}

Client.class

    public void set(final String key, final String value) {
set(SafeEncoder.encode(key), SafeEncoder.encode(value));
}
其中 SafeEncoder.encode(String)是把字符串,安装utf-8字符集,转成 byte[]数组。 

然后相当于调用了父类

BinaryClient.class的  public void set(final byte[] key, final byte[] value)  


public void set(final byte[] key, final byte[] value) {
sendCommand(Command.SET, key, value);
}

Connection.class 中 sendCommand 是所有发送命令的入口。command 是个枚举对象

 protected Connection sendCommand(final Command cmd, final byte[]... args) {
try {
connect();
Protocol.sendCommand(outputStream, cmd, args);
pipelinedCommands++;
return this;
} catch (JedisConnectionException ex) {
// Any other exceptions related to connection?
broken = true;
throw ex;
}
}
 connect()方法就是传统的socket连接服务器的代码


Protocol.class 

public static void sendCommand(final RedisOutputStream os,
final Command command, final byte[]... args) {
sendCommand(os, command.raw, args);
}
sendCommand 是所有发送命令的出口.直接给 redis-server 发送命令。说白了就是把 set key HelloWorld 的byte[] 字节发给redis-server了

为了证实自己的猜测,特意抓了个包。

try redis(四) -java 客户端jedis 使用

发现确实如自己猜测的那样。


至于get命令,也是类似。只是最后调用了。

client.sendCommand(Protocol.Command.GET, key);

抓包也看了下。向server请求时,请求了 GET key

抓取的报文如下:

try redis(四) -java 客户端jedis 使用


redis-server 返回的 是Hello World .


抓取的报文如下:

try redis(四) -java 客户端jedis 使用



最后贴一下 jedis 的 类图,大概画的。

try redis(四) -java 客户端jedis 使用

try redis(四) -java 客户端jedis 使用