一、RESP协议概述
Redis客户端和Redis服务端使用RESP协议进行通信。
这个协议的特点:
- Simple to implement.实现简单
- Fast to parse.快速解析
- Human readable.可读性强
当我写一个socket程序,去拦截Jedis客户端发送的请求,程序如下:
public class JedisSocket {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(6379);
Socket socket = serverSocket.accept();
byte[] bytes = new byte[2048];
socket.getInputStream().read(bytes);
System.out.println(new String(bytes));
} catch (IOException e) {
e.printStackTrace();
}
}
}
得到如下结果:
*3
$3
SET
$4
name
$3
fon
$后面表示的是字符串长度。set的长度是3,name是4,fon是3,*号后面的数字,代表共有3组数据。这就是RESP的内容。
二、Jedis的使用
引入依赖
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.0.1</version>
</dependency>
一个简单的Jedis程序
public class JedisTest {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.set("name","coffejoy");
String str = jedis.get("name");
System.out.println(str);
//关闭连接
jedis.close();
}
}
使用Jedis连接池
interface CallWithJedis {
void call(Jedis jedis);
}
class RedisPool {
private JedisPool pool;
public RedisPool() {
this.pool = new JedisPool("bei1", 6379);
}
public void execute(CallWithJedis caller) {
Jedis jedis = pool.getResource();
try {
caller.call(jedis);
} catch (JedisConnectionException e) {
caller.call(jedis); // 重试一次
} finally {
jedis.close();
}
}
}
class Holder<T> {
private T value;
public Holder() {
}
public Holder(T value) {
this.value = value;
}
public void value(T value) {
this.value = value;
}
public T value() {
return value;
}
}
public class JedisPoolTest {
public static void main(String[] args) {
RedisPool redis = new RedisPool();
Holder<Long> countHolder = new Holder<>();
redis.execute(jedis -> {
String name = jedis.get("name");
System.out.println(name);
});
System.out.println(countHolder.value());
}
}
三、实现一个Jedis客户端程序
public class FonJedis {
//客户端set方法
private static String set(Socket socket, String key, String value) throws IOException {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("*3").append("\r\n");
stringBuffer.append("$3").append("\r\n");
stringBuffer.append("set").append("\r\n");
stringBuffer.append("$").append(key.getBytes().length).append("\r\n");
stringBuffer.append(key).append("\r\n");
stringBuffer.append("$").append(value.getBytes().length).append("\r\n");
stringBuffer.append(value).append("\r\n");
socket.getOutputStream().write(stringBuffer.toString().getBytes());
byte[] response = new byte[2048];
socket.getInputStream().read(response);
return new String(response);
}
//客户端get方法
public static String get(Socket socket, String key) throws IOException {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("*2").append("\r\n");
stringBuffer.append("$3").append("\r\n");
stringBuffer.append("get").append("\r\n");
stringBuffer.append("$").append(key.getBytes().length).append("\r\n");
stringBuffer.append(key).append("\r\n");
socket.getOutputStream().write(stringBuffer.toString().getBytes());
byte[] response = new byte[2048];
socket.getInputStream().read(response);
return new String(response);
}
public static void main(String[] args) {
try {
Socket socket = new Socket("bei1", 6379);
FonJedis.set(socket, "name", "coffejoy");
String value = FonJedis.get(socket, "name");
System.out.println(value);
} catch (IOException e) {
e.printStackTrace();
}
}
}