0%

二、云原生时代下如何访问远程服务

[toc]

访问远程服务#

1 远程服务调用#

这一个章节主要讲解rpc的设计理念和发展历史。
先是讲解了IPC(进程间通信)所需要的各个必要因素
接着解释RPC 是IPC的一种特例(这是最初科学家们的想法)
但PRC存在很多可靠性的问题,并不能直接等同IPC的扩展。

接着提出了RPC的三个基本问题:

  1. 如何表示数据
    即序列化协议, 有grpc的proto-buffer、json、xml、java-rmi基于java自带序列化之列的
  2. 如何传递数据
    基于什么网络协议传输
    java-rmi的远程协议
    JSON-RPC协议
    SOAP协议(web service 简单对下访问)
  3. 如何表示方法
    如何定义方法,如何在不同语言、不同系统环境中保证 方法签名唯一。
    需要对接口描述定义语言有一个选型

再后面讲解了rpc的发展历史
CORBA的使用过于复杂,被抛弃
SOAP使用xml很简单,但是性能奇差
可以看出RPC想同时满足简单、普适、高性能是很难的
于是得出一个结论:

不存在完美的RPC框架

最近几年的RPC框架更倾向于往高层次、插件化发展。
即不再独立解决RPC的所有问题,而是提供一些扩展点由用户自己选择(比如dubbo)
可以任意切换json或者fastjson等序列化方式
可以切换传输协议等。

2 REST#

rest并不是一种远程调用协议, 他只能说是一种风格。
REST的传输效率提升潜力有限,但是可以简化调用。

2.1 REST核心概念(基于HTTP超文本传输协议)#

  • 资源
    资源指你希望获取或者修改的东西、信息本身,他的表现形式可以不同,但是里子是相同的
  • 表征
    就是表现资源的形式,用html还是pdf来返回
  • 状态
    指的是服务端对某次会话是否持有状态。
    例如读下一篇文章时,当前文章id由服务端存储还是浏览器存储,这就是有状态和无状态的区别。
  • 转移
    就是服务端提供的行为逻辑, 通常叫做 资源的转移
  • 统一接口
    就是HTTP协议里提供的GET\HEAD\POST\PUT\DELETE\TRACE\OPTIONS这七种操作,通过这些操作触发转移
  • 超文本驱动
    浏览器的行为经常是通过服务端返回的url或者各种信息触发了驱动行为
  • 自描述消息
    为了方便客户端识别表征,返回类似于Content-Type等内容,方便用何种字符集处理

2.2 REST核心设计原则#

  1. 客户端与服务端分离
    服务端不处理渲染, 由客户端来处理
  2. 无状态
    尽可能希望服务端不要存储rest会话状态,达到分布式的高价值回报。
    但是不太可能特别是客户端持有会话数量级很大的情况下,所以仍旧会持有一定状态
  3. 可缓存
    服务端的应答中要直接或者间接告知客户端是否可以缓存,缓存多久
  4. 分层系统
    客户端不需要知道是否真的连接到了最终的服务器
    代表是CDN内容分发网络
  5. 统一接口
    面向资源编程
    系统设计时聚焦在资源而不是行为上
    例如面向行为时, 登录就是login接口,注销就是logout接口
    而面向资源时,登录就是PUT Session, 注销就是DELETE Session
  6. 按需代码
    客户端的代码可以有一部分让服务端发回进行装载。

2.3 REST的好处#

  • 降低服务接口的学习成本
  • 资源天然具有集合与层次接口
    这样很多资源可以很容易组合在一起并让使用者想到接口url是什么
    例如获取 用户 icyfenix的购物车中的第2本书,这个是有层次的,那么接口就是GET /user/icyfenix/cart/2
  • REST绑定于HTTP协议,HTTP又是大家非常熟悉的

2.4 RMM(Richardson提出的restful成熟度模型)#

第0级:完全不rest#

提供的api定义里总是包含了各种动作,例如
/queryXXX
/applyXXX
类似于RPC的行为接口
坏处是一旦要提供其他对XXX的操作,必须重新编写接口,无法对XXX的查询能力进行复用!

第1级:开始引入资源的概念#

api的endpoint定义应该围绕名词+资源id而不是动词来定义。
POST /doctors/mjones 获取医生的档期
POST /schedules/{id} 触发对这个id的调度

第2级: 引入统一接口,映射到HTTP方法上#

上面的method都是POST,实际上可以把HTTP方法的method、返回码都给利用上

  • 对一个资源的增加用POST,删除用DELETE,更新用PUT
  • 依赖HTTP的返回码定义资源可能的异常情况。例如201代表创建成功,409代表冲突(被人抢先预约)
  • 利用HTTP自带的认证和授权信息。

第3级:超文本控制,转移行为通过响应控制#

第2级里, 所有接口的定义仍然需要使用者自己查询文档来记忆和应用
实际上应该只需要一个操作起始入口, 例如获取医生的档期接口
这个接口要返回的body里,已经告知了对应资源的名称,例如档期资源的key就叫做schedules
那么就能马上知道下一个接口查询用schedules了!
这样代码里可以做好适配,当你要把档期的key名做修改时,客户端代码根本不用变动!

2.2.4 REST的不足和争议#

  1. restful面向资源编程只适合做CRUD,不适合过于复杂的业务逻辑
  • 面向过程编程,以算法和处理过程为中心,这符合计算机世界中主流的交互方式
  • 面向对象编程,将数据和对象行为统一起来,因为这符合现实世界的主流交互方式
  • 面向资源编程,数据作为主体,行为看成统一接口,为了符合网络世界的主流交互方式
  1. rest不利于事务支持
    作者不同意这个观点, 认为不会有阻碍,取决于系统的事务设计
  2. rest没有传输可靠性支持
    虽然确实没有类似于重发等机制的保证,但rest接口一般尽可能要求幂等性,来做到应用代码做重发时可以不用担心重复的问题
  3. 缺少对资源做部分或者批量处理的能力
    rest语义里不能涵盖这种情况,得定义特殊的接口或者参数,那么低3级里面就不能涵盖了。

相关思考#

基于REST的规范,调用者可以非常快速地理解自己需要的接口内容是什么样的,例如华为云当前的很多云服务公开接口都会基于REST理念进行开放, 并且各云服务的开放接口都会集成到API Explorer华为云SDK中心供开发者直接调用,这些平台提供了丰富的接口文档和示例代码,帮助开发者更快地上手和使用 REST 接口。

相信未来REST 规范将会变得更加流行和普及。随着云计算和大数据技术的不断发展,REST 接口将会被广泛应用于各种领域,例如医疗、金融、电商等。REST 接口的开放性、可扩展性和易用性,将会为开发者带来更加高效、便捷和可靠的开发体验。