江湖上说,天下武功,无坚不摧,唯快不破,这句话简直是为我量身定制。
我是一个Redis服务,最引以为傲的就是我的速度,我的 QPS 能达到10万级别。
在我的手下有数不清的小弟,他们会时不时到我这来存放或者取走一些数据,我管他们叫做客户端,还给他们起了英文名叫 Redis-client。
有时候一个小弟会来的非常频繁,有时候一堆小弟会同时过来,但是,即使再多的小弟我也能管理的井井有条。
有一天,小弟们问我。
想当年,为了不让小弟们拖垮我傲人的速度,在设计和他们的通信协议时,我绞尽脑汁,制定了下面的三条原则:
为什么这么设计呢?先来看看一条指令发出的过程,首先在客户端需要对指令操作进行封装,使用网络进行传输,最后在服务端进行相应的解析、执行。
这一过程如果设计成一种非常复杂的协议,那么封装、解析、传输的过程都将非常耗时,无疑会降低我的速度。什么,你问我为什么要遵循最后一条规则?算是对于程序员们的馈赠吧,我真是太善良了。
我把创造出来的这种协议称为 RESP (REdis Serialization Protocol
)协议,它工作在 TCP 协议的上层,作为我和客户端之间进行通讯的标准形式。
说到这,我已经有点迫不及待想让你们看看我设计出来的杰作了,但我好歹也是个大哥,得摆点架子,不能我主动拿来给你们看。
所以我建议你直接使用客户端发出一条向服务器的命令,然后取出这条命令对应的报文来直观的看一下。话虽如此,不过我已经被封装的很严实了,正常情况下你是看不到我内部进行通讯的具体报文的,所以,你可以伪装成一个Redis的服务端,来截获小弟们发给我的消息。
实现起来也很简单,我和小弟之间是基于 Socket 进行通讯,所以在本地先启动一个ServerSocket
,用来监听Redis服务的6379端口:
public static void server() throws IOException {
ServerSocket serverSocket = new ServerSocket(6379);
Socket socket = serverSocket.accept();
byte[] bytes = new byte[1024];
InputStream input = socket.getInputStream();
while(input.read(bytes)!=0){
System.out.println(new String(bytes));
}
}
然后启动redis-cli
客户端,发送一条命令:
set key1 value1
这时,伪装的服务端就会收到报文了,在控制台打印了:
*3
$3
set
$4
key1
$6
value1
看到这里,隐隐约约看到了刚才输入的几个关键字,但是还有一些其他的字符,要怎么解释呢,是时候让我对协议报文中的格式进行一下揭秘了。
我对小弟们说了,对大哥说话的时候得按规矩来,这样吧,你们在请求的时候要遵循下面的规则:
*<参数数量> CRLF
$<参数1的字节长度> CRLF
<参数1的数据> CRLF
$<参数2的字节长度> CRLF
<参数2的数据> CRLF
...
$<参数N的字节长度> CRLF
<参数N的数据> CRLF
首先解释一下每行末尾的CRLF
,转换成程序语言就是\r\n
,也就是回车加换行。看到这里,你也就能够明白为什么控制台打印出的指令是竖向排列了吧。
在命令的解析过程中,set
、key1
、value1
会被认为是3个参数,因此参数数量为3,对应第一行的*3
。
第一个参数set
,长度为3对应$3
;第二个参数key1
,长度为4对应$4
;第三个参数value1
,长度为6对应$6
。在每个参数长度的下一行对应真正的参数数据。
看到这,一条指令被转换为协议报文的过程是不是就很好理解了?
当小弟对我发送完请求后,作为大哥,我就要对小弟的请求进行指令回复了,而且我得根据回复内容进行一下分类,要不然小弟该搞不清我的指示了。
简单字符串回复只有一行回复,回复的内容以+
作为开头,不允许换行,并以\r\n
结束。有很多指令在执行成功后只会回复一个OK
,使用的就是这种格式,能够有效的将传输、解析的开销降到最低。
在RESP协议中,错误回复可以当做简单字符串回复的变种形式,它们之间的格式也非常类似,区别只有第一个字符是以-
作为开头,错误回复的内容通常是错误类型及对错误描述的字符串。
错误回复出现在一些异常的场景,例如当发送了错误的指令、操作数的数量不对时,都会进行错误回复。在客户端收到错误回复后,会将它与简单字符串回复进行区分,视为异常。
整数回复的应用也非常广泛,它以:
作为开头,以\r\n
结束,用于返回一个整数。例如当执行incr
后返回自增后的值,执行llen
返回数组的长度,或者使用exists
命令返回的0或1作为判断一个key
是否存在的依据,这些都使用了整数回复。
批量回复,就是多行字符串的回复。它以$
作为开头,后面是发送的字节长度,然后是\r\n
,然后发送实际的数据,最终以\r\n
结束。如果要回复的数据不存在,那么回复长度为-1。
当服务端要返回多个值时,例如返回一些元素的集合时,就会使用多条批量回复。它以*
作为开头,后面是返回元素的个数,之后再跟随多个上面讲到过的批量回复。
到这里,基本上我和小弟之间的通讯协议就介绍完了。刚才你尝试了伪装成一个服务端,这会再来试一试直接写一个客户端来直接和我进行交互吧。
private static void client() throws IOException {
String CRLF="\r\n";
Socket socket=new Socket("localhost", 6379);
try (OutputStream out = socket.getOutputStream()) {
StringBuffer sb=new StringBuffer();
sb.append("*3").append(CRLF)
.append("$3").append(CRLF).append("set").append(CRLF)
.append("$4").append(CRLF).append("key1").append(CRLF)
.append("$6").append(CRLF).append("value1").append(CRLF);
out.write(sb.toString().getBytes());
out.flush();
try (InputStream inputStream = socket.getInputStream()) {
byte[] buff = new byte[1024];
int len = inputStream.read(buff);
if (len > 0) {
String ret = new String(buff, 0, len);
System.out.println("Recv:" + ret);
}
}
}
}
运行上面的代码,控制台输出:
Recv:+OK
上面模仿了客户端发出set
命令的过程,并收到了回复。依此类推,你也可以自己封装其他的命令,来实现一个自己的Redis客户端,作为小弟,来和我进行通信。
不过记住,要叫我大哥。
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/HTbdBa15sZU1tJEFgiKHxA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。