起因:
研究zabbix的API设计风格。查看zabbix官网API文档,可以看到使用的是json-rpc:2.0
随后搜索到知乎上的一个问题讨论:https://www.zhihu.com/question/28570307 即标题中的问题。
仔细研究,问题不断发散再发散,整理一下,以下内容是看了很多篇相关知识后的个人理解:
1、RPC是什么?
参考:https://www.zhihu.com/question/25536695/answer/221638079
RPC是指远程过程调用。服务器A要调用服务器B上的某个方法,由于内存空间不同,无法直接调用,需要通过网络来表达调用的语义和传达调用的数据。需解决以下问题:
通信问题:在服务器A与B之间建立起TCP连接(有答案说UDP也可以);TCP、UDP是属于传输层的协议
参数的序列化和反序列化:参数通过网络传输,需把服务器A内存里的内容序列化后进行传输。
方法映射:参数中包含着要调用的方法,服务器B必须建立起参数与所要调用方法的映射关系
服务器B执行完方法后返回,同样经历上述过程。
2、json-RPC是什么
json-rpc 2.0规范:http://wiki.geekdream.com/Specification/json-rpc_2.0.html
JSON-RPC是一个无状态且轻量级的远程过程调用(RPC)协议。 本规范主要定义了一些数据结构及其相关的处理规则。它允许运行在基于socket,http等诸多不同消息传输环境的同一进程中。
简单来说,就是定义了各个RPC各参数规范。如method表示方法,param表示参数。服务器B拿到这个东西就是知道了服务器A要调用什么方法,参数是什么。
它是运行在socket、http、websocket等协议之上的。注意http、websocket已经是属于应用层了。
3、什么是websocket?它和socket有什么区别?
介绍websocket: https://blog.csdn.net/wwd0501/article/details/54582912
websocket首先是一个应用层协议,这点与http相同。
与http不同的是,它可以建立服务器A与服务器B之间的一个长连接(类似于TCP中的长连接),之后可以发送多个请求。而http每一个请求都是独立的。据介绍,websocket建立长连接时,使用http,之后的请求与返回,则不需要http协议了。
socket是传输层与应用层之间的一个抽象层,为应用层屏蔽了传输层复杂的协议。
4、什么是RESTful?
restful是一种API设计风格。这里可以发现,其实restful和json-rpc其实是没有可比性的。其对比的应该是RPC.
restful必须依赖于http,因为它需要http请求的类型(post、get、put、delete)来标榜对该资源进行如何的处理。
restful设计难点:需要将所有的接口抽象成某种资源
如想delete多个id怎么办?全部写在url中吗(delete没有body)?不,你应该把删除多个ID抽象成某个任务(即抽象成另一种资源),然后对这个资源使用post。比如用户的登录和登出,不适合对用户这个资源进行操作,应该抽象成对session这个资源进行操作。
想使用restful必须要有这样的抽象能力。。
知乎对restful一个总结(个人觉得挺到位的):
看Url就知道要什么(资源)
看http method就知道干什么
看http status code就知道结果如何
一定要有以资源为主体的思维。之前也有人说过restful是名词,rpc是动词,大概想表述的也是这个意思。
5、知乎中有人说json-rpc性能比restful好?
其实是json-rpc能运行在类似于websocket上,是websocket的性能比http好。这种说法有点问题。
像zabbix,json-rpc底层承载还是使用http,反而需要序列化和反序列化的时间,性能好?不见得吧。
6、说回zabbix,其API设计风格到底是咋样的?
首先,开放的API都是使用http的post方法调用的,post的参数遵循json-rpc2.0的规范。如果把所有的API接口看成一种资源,那它的这个API可以说是遵循了restful风格。
其次,最新奇的一点来了,其API的URL只有一个!!只有一个!!格式如下:
POST http://company.com/zabbix/api_jsonrpc.php HTTP/1.1
Content-Type: application/json-rpc
{"jsonrpc":"2.0","method":"apiinfo.version","id":1,"auth":null,"params":{}}
去看了api_jsonrpc.php,这个php脚本要解决的就是,首先拿到http的body数据,接下来用json-rpc2.0规范去解析,拿到method到底是什么,接下来去调用相应的方法。这个脚本做的就是RPC中提到的要解决方法映射问题。
有意思的是,method全都是以这样的形式A.B,给人一种感觉,A是类,B是A中某个方法。zabbix中所有的方法都用php脚本实现了,对应的每一个A都是独立的一个php文件,B是A中的某个方法,且名称是一一对应的,即无需维护参数中的名称与调用方法的映射关系。
假设不使用zabbix的Php脚本来实现类似的功能,使用类的getMethod的方式,通过反射来调用个人觉得也是可行,当然方法名称自然也是要一一对应的。
暂时不能理解,为什么zabbix要这样设计(仅用一个URL,在json-rpc的method字段去标注具体的方法)?或者这样设计的好处在哪里?知乎上有人这样说:
我见过最高明的restful设计,是只使用一个url,然后,用post请求,传method动词参数。可谓一个restful在手,打遍天下无敌手。
这难不成说的就是zabbix????
最后,引用知乎上的一段话:
所谓代码风格、接口形式、各种林林总总的格式规定,其实都是为了在团队内部形成共识、防止个人习惯差异引起的混乱。JSON-RPC当然也是有规范的,但相比REST实在宽松太多了。
如果一个开发团队规定必须在url里写action,所有请求都是POST,可以吗?当然也没问题,只是不要拿出去标榜自己写的是RESTful API就行。
规范最终还是为了开发者和软件产品服务的,如果它能带来便利、减少混乱,就值得用;反之,如果带来的麻烦比解决的还多,那就犯不上纯粹跟风追流行了。(作者:Vincross 链接:https://www.zhihu.com/question/28570307/answer/163638731)
---------------------
作者:x6696
来源:CSDN
原文:https://blog.csdn.net/x6696/article/details/81839893
版权声明:本文为博主原创文章,转载请附上博文链接!