(本篇为翻译稿,转载请注明出处,谢谢)原文链接:nats protocol
NATS协议
In a network, a wire protocol is the mechanism for transmitting data from point a to point b. The term is a bit confusing, because it sounds like layer 1 of the network, which physically places the bits "onto the wire." In some cases, it may refer to layer 1; however, it generally refers to higher layers, including Ethernet and ATM (layer 2) and even higher layer distributed object protocols such as SOAP, CORBA or RMI. See OSI model, communications protocol, data link protocol and distributed objects.
NATS传输协议 ( wire protocol ) 是一个简单的基于文本的发布/订阅类型的协议。客户端通过常规的TCP/IP套接口与gnatsd(NATS服务器)连接和通信,并使用少量协议控制字符,以换行为结尾。
区别于二进制消息格式的传统消息系统,基于文本的NATS协议不需要使用特定API解析消息,因此可以通过各种编程语言和脚本语言来实现客户端。
NATS服务器无需额外分配内存用于解析消息,实现了零分配字节解析器(zero allocation byte parser),快速且高效。
NATS协议术语约定
话题名称Subject Names: 包括reply subject(INBOX)names,是一个包含字母和数字的字符串,对大小写不敏感,字符串中间不允许有空格,可以用英文字符.来分隔。例如:
FOO, BAR, foo.bar, foo.BAR, FOO.BAR
通配符Wildcards: NATS支持subject的通配符
- *表示匹配subject的任意层级的所有字符
- >表示匹配subject的任意长度的尾部,只能用于最后,这也被称为"完全通配符"。例如,foo.*.quux和foo.>通配订阅都能匹配foo.bar.quux,但是只有后者匹配foo.bar.baz。完全通配符可以表示订阅NATS中的每一个话题 topic:sub > 1.
字段分隔符Field Delimiters: NATS协议消息的字段使用空格(space)或者\t(tab)来分隔。多个空格字符会被当做一个字段分隔符。
换行Newlines: 与其它基于文本的协议一样,NATS使用CR和LF(CR+LF,\r\n,0x0D0A)来终止协议消息。换行符也用来标识PUB或者MSG协议消息的真正消息体的开始。
NATS协议消息概览
下表简要描述了NATS协议消息。
名称 | 发送方 | 描述 |
---|---|---|
INFO | Server | TCP/IP连接初始化后发送给client |
CONNECT | Client | 发送给server,描述连接信息 |
PUB | Client | 发布消息到一个subject,可选携带reply subject |
SUB | Client | 订阅某个subject或者subject通配的消息 |
UNSUB | Client | 取消订阅某个subject(或者自动取消订阅) |
MSG | Server | 发送消息给某个订阅者 |
PING | Both | PING keep-alive消息 |
PONG | Both | PONG keep-alive消息 |
+OK | Server | 在verbose模式下,确认封装协议消息 |
-ERR | Server | 指示协议错误,会导致客户端连接断开 |
NATS协议消息详细
INFO
语法
INFO {["option_name":option_value],...}
选项
server_id: NATS server 的唯一标识
version: NATS server 的版本
go: 编译NATS server 所用的 golang 版本
host: NATS server 主机的 IP 地址
port: NATS server 的监听端口
auth_required: 如果设置了,client 需要在连接上增加认证信息
ssl_required: 如果设置了,client 必须使用 SSL 认证
max_payload: server可以接收的来自 client 的最大消息体长度//消息长度 or 消息体长度?
描述
一旦server接收到来自client的连接,server就会向client发送服务器信息和配置以及安全要求,这些是client连接server进行安全认证和交换消息所需要用到的信息。
样例
下面是telnet demo.nats.io(107.170.221.32)站点的NATS服务返回的一个INFO样例
Xshell:\> telnet 107.170.221.32 4222
Connecting to 107.170.221.32:4222...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
INFO
{"server_id":"ad29ea9cbb16f2865c177bbd4db446ca","version":"0.6.8","go":"go1.5.1","host":"0.0.0.0","port":4222,"auth_required":false,"ssl_required":false,"max_payload":1048576}
CONNECT
语法
CONNECT {["option_name":option_value],...}
选项
verbose: 打开+OK消息确认选项
pedantic: 打开格式校验选项,如校验 subjects 是否正确封装
ssl_required: 标识 client 是否需要 SSL 连接
auth_token: client 的认证令牌
user: 连接用户名 (如果设置了 auth_required)
pass: 连接密码 (如果设置了 auth_required)
name: 可选的 client 名称
lang: 实现 client 所用的编程语言
version: client 版本
描述
CONNECT消息类似于INFO消息。一旦 client 与NATS server 确立了TCP/IP套接口连接,收到来自 server 的INFO消息,client 可能发送CONNECT消息到NATS server ,来提供当前连接的更多消息,包括安全信息。
样例
下面是一个Go Client的默认字符串样例
CONNECT {"verbose":false,"pedantic":false,"ssl_required":false,"name":"","lang":"go","version":"1.1.0"}\r\n
大多数 client 会将verbose默认设置为 false 。这表示 server 在收到消息后,将不再向client 发送+OK确认消息。
PUB
语法
PUB [reply-to] <#bytes>\r\n[payload]\r\n
其中,
subject: 发布消息的目标subject
reply-to: 回复收件箱subject(reply inbox subject),订阅者可以用来向发布者或者请求者发送response
#bytes: 消息体长度(单位:byte)
payload: 消息体
描述
发布者使用PUB消息向给定subject发布消息,可选提供reply subject信息。如果提供了reply subject,该消息将发送给正确的订阅者。注意,payload是可选的。如果想发送空消息,将payload的长度设置为0
样例
向subject FOO发布字符串消息“hello NATS!”
PUB FOO 11\r\nHello NATS!\r\n
向subject FONT.DOOR发布请求消息"Knock Knock",带有reply subject选项,INBOX.22
PUB FRONT.DOOR INBOX.22 11\r\nKnock Knock\r\n
向subject NOTIFY发布空消息
PUB NOTIFY 0\r\n\r\n
SUB
语法
SUB [queue group] \r\n
其中,
subject: 要订阅的subject名称
queue group: 如果指定了该字段,订阅者将加入这个queue group
sid: 订阅者唯一ID,可以包含字母和数字
描述
SUB消息初始化subject的一个订阅者,可选加入一个队列分组(queue group)
样例
使用sid 1订阅subject FOO
SUB FOO 1\r\n
订阅 subject BAR ,注明使用sid 44作为队列分组 (distribution queue group) G1的一部分
SUB BAR G1 44\r\n
UNSUB
语法
UNSUB [max_msgs]
其中,
sid: 取消订阅的subject的ID
max_msgs: 自动取消订阅之前需要等待的消息条数
描述
UNSUB取消指定subject的订阅,或者在接收到指定数量的消息后自动取消订阅
样例
下面的例子涉及subject FOO,已经被指定sid为1. 如果要取消订阅FOO
UNSUB 1\r\n
接收到5条信息后自动取消订阅
UNSUB 1 5\r\n
MSG
语法
MSG [reply-to] <#bytes>\r\n[payload]\r\n
其中,
subject: subject名称
sid: subject ID
reply-to: 收件箱subject,发布者监听回复的subject
#bytes: 消息体长度(单位:byte)
payload: 消息体
描述
MSG协议消息向client发送消息
样例
来自subject FOO.BAR的消息
MSG FOO.BAR 9 11\r\nHello World\r\n
相同的消息,只是增加了一个reply inbox
MSG FOO.BAR 9 INBOX.34 11\r\nHello World\r\n
PING/PONG
描述
PING和PONG实现了client和server之间的简单keep-alive机制。一旦client连接上NATS server,server就会按照配置的时间间隔持续向client发送PING消息。当client在指定响应时间间隔内没有响应PONG消息,server将断开与client的链接。如果链接空闲时间太长,它会断开。
如果server发送ping请求,你可以响应pong消息表示你仍在线。你也可以向server发送ping消息,然后收到来自server的pong消息。ping/pong间隔是可以配置的。
+OK/ERR
语法
+OK
-ERR
当verbose连接选项设置为true(默认值)时,server用+OK消息来确认来自client的每一个完整的消息。大多数client会通过CONNECT消息将verbose设置为false。
-ERR消息是server用来告诉client出现了协议、认证或者其它运行时连接错误。大多数的错误会导致server关闭该连接。
一般异步处理这些错误消息。
会造成连接断开的错误消息为:
-ERR 'Unknown Protocol Operation' -ERR 'Authorization Violation' -ERR 'Authorization Timeout' -ERR 'Parser Error' -ERR 'Stale Connection' PING/PONG消息超时 -ERR 'Slow Consumer' -ERR 'Maximum Payload Exceeded'
不会造成连接断开的错误消息为:
-ERR 'Invalid Subject'