面试造飞机系列:看架构师如何设计微服务接口

2023-05-16

来源 | 后端技术学堂

责编 | Carol

封图| CSDN下载于视觉中国 

在微服务设计中,服务间接口通信设计常见的有两种方式:RPC  和 REST,关于微服务和 RPC  的更多细节,可以参考我上一篇文章 面试都在问的微服务,一文带你彻底搞懂!

这篇文章主要介绍什么是 REST 风格设计以及 RESTful 接口。阅读完本文你将收获以下知识点:

  • 什么是 REST 和 RESTful

  • REST 接口设计规范是什么

  • REST 为什么要设计成无状态

  • 接口无状态真的是没有状态吗

  • RPC 和 REST 适用场景

REST 和 RESTful

REST(Representational State Transfer,表述性状态转移) 是一种软件架构风格。REST提出了一组架构约束条件和原则,任何满足 REST 约束条件和原则的架构,都称为 RESTful 架构。

微服务之间需要相互通信以完成特定的业务处理,在典型的客户端-服务端设计模型中,客户端和服务端通通过消息请求-响应的方式交互协作,REST 就是这样一套微服务之间交互接口的设计约束和原则规范。

乍一看 REST「表述性状态转移」每个字都认得,连起来不知道什么意思。

这是作者 Roy Thomas Fielding 在他的博士论文里提出的概念,论文自然都是学术用语,不过感兴趣的同学可以去看看作者论文原文,地址我贴出来:https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

今天 lemon 用大白话帮你透彻理解这个概念,我们把「表述性状态转移」掰开来看,先搞明白什么是「表述性」,什么是「状态转移」。

表述性

「表述性」其实是缺少了主语的,主语是「资源」。完整的描述是「资源表述性」,也就是「资源的描述」。在网络通信中用什么描述资源呢?没错就是 URI(Uniform Resource Identifier,统一资源标识符)

这里有几个近义词先给大家先科普一下:

URI  是统一资源标识符,用来唯一的标识一个资源。

URL 是统一资源定位器,它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何定位这个资源,URL 是 URI 的子集。

URN  统一资源命名,是通过名字来标识资源。URN也是 URI 的子集。

在 HTTP 协议中用 URL 标识资源,也就是浏览器地址栏你看到的那一串网址。

地址栏URL

资源表述性

为了说明「资源描述性」接口设计的优点,我们来做一个接口设计方法的对比,举个栗子就清楚了。

传统的接口设计

先来看下传统的网络通信模式是怎么样的。假设lemon这个人物对象,在服务端的存储形式是一个c++class类型存储。

下面的过程展示,客户端发送请求服务端创建一个 lemon 对象的过程。

  1. 服务端定义存储结构头文件 lemon.h

class lemon{  string name;  string address;  uint64 phone;}
  1. 客户端代码引用服务端定义的lemon.h「互相引用头文件,增加了服务耦合性!」

  2. 客户端初始化一个 lemon 实例并序列化后通过网络接口发送给服务端。

class lemon lm;lm.name = "lemon";lm.address = "Shenzhen";lm.phone = 18666666666;
  1. 服务端接收消息,反序列化,存储传输过来的 lemon 对象

资源表述性接口设计

lemon 这个服务内部的对象,对外表现可以用一张图片来表示,也可以用包含lemon 的姓名、地址、电话等信息的 xml 或 json 格式的数据表示。

{name : "lemon",address:  "ShenZhen",phone  :  18666666666}
<?xml version="1.0" encoding="UTF-8" ?>	<name>lemon</name>	<address>ShenZhen</address>	<phone>18666666666</phone>

也就是说,lemon 这个「资源」在服务内部的存放形式对外不可见,外界客户端发起请求可以用不同的资源表述格式来获取服务端的资源。

(如果服务器会说话,他内心os 大概是这样的:  客户端你不用管我是如何保存这个对象的,只要你说的清楚想要什么对象,只管发来请求便是!)。

这样做最显然的好处是,减少了服务之间的耦合。客户端访问服务资源之前不需要知道资源在服务端的具体存储格式,只需描述资源形式即可修改、创建、更新、删除服务端的资源。

状态转移

搞懂了「资源描述性」接下来看下什么是「状态转移」?状态转移就是客户端通过一系列请求动作,推动服务端的资源状态发生变化,资源的状态可以在「创建-修改-查看-删除」之间转移。

资源状态转移

资源状态的变化在宏观上的反应就是业务流程推进。打个比方,你去银行系统开户、查余额、销户,这个过程你推动了你的银行账户这个「资源」经历了不同的状态转移让你完成了不同的业务操作。

REST的约束条件

协议选择

REST 本身并没有提到底层应该使用什么协议,日常实践案例中最常用的是基于 HTTP 的 RESTful 实现。

这是因为 HTTP 协议自带的动词 GET/POST/PUT/DELETE 可以作为推动状态转移的方法,另外HTTP 的制定了规范的状态码。还有其他的一些 HTTP 特性,这些特性使得在HTTP 之上实现 REST 要简单得多,而如果使用其他协议的话,就需要自己实现这些特性。

请求规范

RESTful 架构中,发生状态转换的是「资源」,所以URI 中一般只能包含代表「资源」的名词,并且推荐是复数,而不应该在 URI 中包对资源进行操作的动词。

对资源执行的CURD「增删改查」动作应该在HTTP请求方法的GET/POST/PUT/DELETE中体现。

符合REST规范的写法:

POST http://www.test.com/lemon   // 创建Get http://www.test.com/lemon    // 查询PUT http://www.test.com/lemon    // 修改DELETE http://www.test.com/lemon //删除

不符合REST规范的写法:

POST http://www.test.com/Createlemon  // 创建POST http://www.test.com/Querylemon   // 查询POST http://www.test.com/Modifylemon  // 修改POST http://www.test.com/Deletelemon  //删除

状态码

服务端消息响应携带状态码,指示客户端进行下一步处理。符合 RESTful 规范的接口返回状态码都是通用的,不需要额外约定,利用HTTP Status Code 状态码 表示请求处理结果,降低了微服务间互操作成本。

下面是常见的HTTP状态码:

  • 200 - 请求成功

  • 301 - 资源(网页等)被永久转移到其它URL

  • 404 - 请求的资源(网页等)不存在

  • 500 - 内部服务器错误

无状态

RESTful接口要求是「无状态」。无状态指的是任意一个Web请求必须完全与其他请求隔离,当客户端发起请求时,消息本身包含了服务端识别这一请求上下文所需的全部信息。

无状态不是真的没有状态

接口「无状态」更确切的说是服务端无状态,整个会话还是需要状态维持的。要完成一个业务流程,一般客户端与服务端需要多次的消息交互,我们知道HTTP 协议是「无状态协议」,这就需要服务端能够识别几个独立 HTTP 请求的「状态信息」,从而将他们关联到一个业务流程中。

还是举例子银行系统取款的例子:

  • 用户lemon要登录银行系统,首先需要在登录页面输入用户名和密码,这时候产生一个登录请求

  • 服务端收到登录请求,执行登录逻辑并返回操作结果

  • lemon登录之后点击取款100万,产生一个取款请求

  • 服务端收到取款请求,执行取款逻辑并返回操作结果

取款业务流程

这里有个问题,服务端在不同时间点收到登录请求和取款请求,这两个请求都是用户 lemon 产生的,如果不在技术层面做对独立的 HTTP 请求做关联的话,服务端就无法知道这两个请求其实是都是用户lemon 「取款业务」的组成部分。

技术方案

服务端要能识别请求的「状态信息」,有两种技术方案:

  1. Session 方式。服务端保存会话状态,客户端每次请求携带session-id

    服务端维护一个会话状态信息列表,用session-id唯一标识一个状态信息,session-id一般包含在HTTP响应的Set-Cookie头部返回给客户端,后续客户端请求携带包含session-id信息的cookie头部,服务端解析cookie取出session-id,去维护的状态列表中取回该消息对应的状态信息,这样就把无状态的HTTP变成有状态的了。

session会话

  1. Token 方式。服务端不保存会话状态,客户端每次请求都携带完整的会话状态信息(一般是加密的)给服务端。

    Token也称作是「令牌」或临时证书签名,状态信息都被加密到token中,这样每当服务器收到请求后解密token就能获取该请求对应的状态信息,也就能把不同的请求消息关联到同一个业务流程中来,和session方式有类似的效果,只不过这次的状态信息不保存在服务端。

Token会话

以上两种实现中,第一种 Session 方式是有状态的,第二种 Token 方式是无状态的。

如果你要实现 RESTful 接口最好按第二种技术方案实现,当然要实现无状态也还有其他方式,思路都是「服务端不保持会话状态」就对了。

为什么要无状态

为了高可用性和负载均衡需求,多个微服务通过负载均衡实现分布式集群化部署,集群中每个服务都是独立和对等的。如果服务器在收到客户端请求之时不可用或者宕机,无状态请求可以由任何其他可用服务器处理并作出应答,这在分布式应用中非常重要。

REST无状态接口

想象一下如果服务端保存状态,一个事务内的每个请求都必须落到同一台服务器去处理,这就失去了分布式的意义和优势。

所以, RESTful 接口要求是无状态的,是为了更好的适应分布式业务场景,发挥微服务集群优势。

REST 和 RPC

这两个概念经常出现在微服务架构设计中,REST 是一种软件架构接口设计风格,RPC 是一种计算机通信协议,看起来是两个不同的概念,没法比较。

但是有些书中把它们放在一起比较,真要比较的话,我个人倾向于把 REST 具体化为一种基于HTTP 并按照 REST 约束设计的通信协议,这样两个通信协议才有比较性。

回顾下RPC

RPC (Remote Procedure Call)远程过程调用是一个计算机通信协议。我们一般的程序调用是本地程序内部的调用,RPC允许你像调用本地函数一样去调用另一个程序的函数,这中间会涉及网络通信和进程间通信,但你无需知道实现细节,RPC框架为你屏蔽了底层实现。

RPC 是一种服务器-客户端Client/Server模式,经典实现是一个通过发送请求-接受回应进行信息交互的系统。

适用场景

很多 RPC 框架提供的消息传输都是基于二进制的,比如ThriftProtocol buffers。这样做的好处是消息结构比较紧凑,对于频繁调用或者大流量、低时延要求的应用场景,能够显著减少网络开销;另一个约束是某些 RPC 框架有很强的技术耦合性,比如 Dubbo 只能用于 java 技术栈。综上,RPC 「更加适用于系统内部微服务之间的高效通信」

RESTful接口由于提供了统一的基于 HTTP的 REST 设计标准,只需 web 框架支持 HTTP 协议,并设计RESTful 风格的接口即可,极大的方便了第三方服务接入调用,「适合用于微服务系统对外暴露的接口设计标准」

写在最后

本文是微服务架构设计中接口选型的一个小方面,很多人会觉得现在工作面试,不管是大厂还是小公司,都是面试造飞机,工作拧螺丝。个人认为即使你在入职之后接触不到架构方面的工作,也要有一颗架构的心,高度决定认知,如果只盯着手上的那颗螺丝那和咸鱼有什么区别?

老规矩。感谢各位的阅读,文章的目的是分享对知识的理解,技术类文章我都会反复求证以求最大程度保证准确性,若文中出现明显纰漏也欢迎指出,我们一起在探讨中学习。

同时,欢迎所有开发者扫描下方二维码填写《开发者与AI大调研》,只需2分钟,便可收获价值299元的「AI开发者万人大会」在线直播门票!

推荐阅读:你知道吗?其实 Oracle 直方图自动统计算法存在这些缺陷!(附验证步骤)
你公司的虚拟机还闲着?基于 Jenkins 和 Kubernetes 的持续集成测试实践了解一下!一站式杀手级 AI 开发平台来袭!告别切换零散建模工具那些神一样的程序员
比特币当赎金,WannaRen 勒索病毒二度来袭!通过 Python 代码实现时间序列数据的统计学预测模型
真香,朕在看了!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

面试造飞机系列:看架构师如何设计微服务接口 的相关文章

  • 超声波换能器的几点总结

    超声波换能器是超声波测量的关键件 xff0c 必须保证超声波换能器的质量以及特性稳定 1 超声波换能器的激励信号频率接近谐振频率是触发信号强度最大 2 传感器是被动元器件 xff0c 激励信号进行激励会产生震动 xff0c 接收端接收信号
  • windows7安装ubuntu双系统教程

    转载自 xff1a http www cnblogs com masbay p 10745170 html windows7安装ubuntu双系统教程 一 先搞清楚自己电脑的类型 xff1a 本次安装的Ubuntu的电脑类型是MBR传统bi
  • STM32 串口详解

    目录 01 USART的特点 02 USART简介 2 1 数据传输模型 2 2 帧结构 2 3 波特率 03 STM32的USART 04 代码配置 01 USART的特点 USART是通用异步收发传输器 xff08 UniversalA
  • STM32串口开发之环形缓冲区

    01 简介 在之前的文章 stm32 串口详解 中 xff0c 我们讲解了串口的基本应用 xff0c 使用串口中断接收数据 xff0c 串口中断发送回包 xff08 一般可以使用非中断形式发送回包 xff0c 在数据接收不频繁的应用中 串口
  • 第六章 类域

    第六章 类域 一 类作用域 使用 访问全局变量 int x 61 1 namespace wd int x 61 20 class Test public Test int value x value void print int x co
  • 步进电机使用总结之噪声、振动的抑制

    不正确地驱动步进电机很容易导致电机发出 嗡嗡 的噪声和很大的振动 当驱动步进电机时 xff0c 如果发现步进电机处于静止状态时 xff0c 其内部都发出很明显的噪音 xff0c 有点类似线圈快速变化那种 xff0c 一般是由于线圈电流过大导
  • ADRC自抗扰控制学习

    入门 自抗扰控制01 xff1a 为何ADRC会成为百年PID算法的继承者 xff1f http news eeworld com cn mp ZLG a23516 jspx 自抗扰控制02 ADRC如何避免执行错误命令 http news
  • 关于串级PID控制的理解

    1 关于内环积分器 飞控里经常会用到串级PID控制 xff0c 通常设计方法为从内环到外环 xff0c 如速度环 位置环 内环通常为PD控制 xff0c 或P控制 xff0c 因为要保证一定带宽 xff0c 而积分器会抑制内环的带宽 xff
  • UMD代码格式

    span class token punctuation span span class token keyword function span span class token punctuation span root span cla
  • Tomcat Server.xml配置详解

    在理解Tomcat配置之前 xff0c 需要先熟悉一下Tomcat的架构 xff0c 便于更好的修改配置 一 Tomcat结构 server xff1a 即服务器 xff0c 每个tomcat程序启动后 xff0c 就是一个server s
  • Linux下U盘、SD卡挂载与卸载

    1 手动挂载 卸载 U盘 SD卡 对于ARM Linux来说 xff0c 第一次使用U盘或SD时 xff0c U盘这个文件目录是不能直接进入的 xff0c 我们需要对其进行挂载 xff0c 然后再接下来的使用中就可以直接进行使用了 通过再网
  • Java 阻塞队列--BlockingQueue

    1 什么是阻塞队列 xff1f 阻塞队列 xff08 BlockingQueue xff09 是一个支持两个附加操作的队列 这两个附加的操作是 xff1a 在队列为空时 xff0c 获取元素的线程会等待队列变为非空 当队列满时 xff0c
  • 大厂SQL经典面试题(二)留存问题

    留存率 是用户分析的核心指标之一 xff0c 留存问题也是一个经常考的题目 问题 现场写一道SQL 给定用户表Users 求出每个日期对应的活跃用户数 次日留存用户数 次日留存率 指标定义 某日活跃用户数 某日活跃的去重用户数 N日留存用户
  • 程序猿代码面试指南 PDF

    前言 今年是最难求职年 xff0c 我希望通过这篇文章能帮大家提高求职成功率 这篇文章分为简历篇 面试篇 谈薪酬篇 xff0c 包括了找工作过程中各个环节的技巧和防坑指南 这篇文章就是给大家分享左神这本 程序员代码面试指南 IT名企算法与数
  • 从 Java 代码逆向工程生成 UML 类图和序列图

    前言 本文面向于那些软件架构师 xff0c 设计师和开发人员 xff0c 他们想使用 IBM Rational Software Architect 从 Java 源代码来逆向工程生成 UML 类和序列图 逆向工程经常被用来从已有的源代码中
  • http的三次握手

    在http的三次握手当中 xff0c 首先客户端发起一个我要发送一个数据包的请求 xff0c 发送到服务端 xff0c 这里面呢会有一个标志SYN 61 1 Seq 61 X xff0c syn是一个标识 xff0c 就是我这是一个创建请求
  • SQL优化面试专题

    介绍 xff1a 无论您是创建Web应用程序的开发人员 xff0c 还是参与Web测试的DBA或测试人员 xff0c SQL方面的技巧在数据库编程和数据库验证中都非常重要 因此 xff0c 我们整理了QL性能优化方面的面试问题 SQL性能优
  • Docker容器:将带UI的程序直接转为Web应用,so easy

    摘要 xff1a 使用Docker容器 xff0c 将带UI的程序 xff0c 直接转换为Web应用 很方便 xff0c 跟大家分享一下 本文分享自华为云社区 使用Docker容器 xff0c 将带UI的程序 xff0c 直接转为Web应用
  • 38道多线程核心面试题(附答案)

    前言 今天给大家分享的是比较全面的多线程面试题 xff0c 大家在面试的过程中不免会被问到很多专业性的问题 xff0c 有的时候回答的并不是那么全面和精细 xff0c 这仅仅代表个人观点 1 如何预防死锁 xff1f 1 首先需要将死锁发生
  • Java程序员,最常用的20%技术有哪些?

    1 基本的数据结构和算法真的非常重要 xff1a 不管你做过多少项目或者是熟悉多少框架和工具 xff0c 面试和考察一个人还是大部分停留在基本功上 所以 xff0c 在每天工作开发之余 xff0c 应保证一定的时间段不断去打磨自己的基本功

随机推荐

  • Linux 程序编译过程详解

    大家肯定都知道计算机程序设计语言通常分为机器语言 汇编语言和高级语言三类 高级语言需要通过翻译成机器语言才能执行 xff0c 而翻译的方式分为两种 xff0c 一种是编译型 xff0c 另一种是解释型 xff0c 因此我们基本上将高级语言分
  • 关于485总线 A、B端上拉下拉电阻选择

    问 xff1a about rs485 用电阻上拉 B用电阻下拉 A B间用电阻连接 xff0c 这些电阻参数大致多少 xff1f 我们公司的设计是 TTL输入都用光偶隔离 输出加上拉和下拉 xff0c 中间加TVS和2个电阻串联 xff0
  • JAVA集合框架(一)-ARRAYLIST

    1 ArrayList的特点 存放的元素有序元素不唯一 可以重复 随机访问快插入删除元素慢非线程安全 2 底层实现 底层初始化 xff0c 使用一个Object类型的空对象数组 xff0c 初始长度为0 源码 Object类型对象数组引用
  • Java如何将两个数组合并为一个数组呢?

    数组 xff1a 数组 xff08 Array xff09 是有序的元素序列 1 若将有限个类型相同的变量的集合命名 xff0c 那么这个名称为数组名 组成数组的各个变量称为数组的分量 xff0c 也称为数组的元素 xff0c 有时也称为下
  • pca9548及vsc9548的设备树简单挂载

    简述 pca9548及vsc9548是iic拓展器件 xff0c 主要是防止iic器件地址冲突 通过写其0x0寄存器可切换0 7路iic 设备树挂载 这里用到了vsc9548 xff0c 且在第7路上挂在了eeprom器件 i2c 64 f
  • 类的作用域

    类的作用域简称类域 xff0c 它是指在类的定义中由一对花括号所括起来的部分 每一个类都具有该类的类域 xff0c 该类的成员局部于该类所属的类域中 在类的定义中可知 xff0c 类域中可以定义变量 xff0c 也可以定义函数 从这一点上看
  • 常见问题(持续更新)

    近期整理的初级开发遇到的问题 xff0c 希望对大家有用 1 Unsatisfied dependency expressed through field 39 baseMapper 39 于是在pom xml中搜索mybatis关键字 x
  • orb-slam中的orb特征

    1 ORB特征简介 ORB是Oriented FAST and Rotated BRIEF xff08 oFAST and rBRIEF xff09 的简称 xff0c ORB的名字已经说明了其来源 xff0c 其实ORB特征是采用FAST
  • 计算机组成原理 第二篇:总线 1.总线原理和意义

    总线是什么 总线是连接多个部件的信息传输线 是各部件共享的传输介质 总线可以传输的原理 总线实际上是由许多传输线或通路组成 每条线上保持的电平高低即是所传输的信号 每条线可一位一位地传输二进制代码 一串二进制代码可以在一段时间内逐一传输完成
  • 主流深度学习算法简介

    深度学习算法简介 1 深度学习主流算法包括 1 1 CNN 卷积神经网络 卷积神经网络 xff08 CNN xff09 是最常见的深度学习方法之 一 自20 世纪80 年代后期以来 xff0c CNN 已应用于视觉识别与分类任务 xff0c
  • 常见外贸英文术语(下)

    很多从事外贸行业的人都会用Skype IntBell AntTone等网络电话和客户沟通 xff0c 但是有时候会因为一些外贸行业的专业英文术语闹出笑话 今天就让我们来总结一些外贸常见英文术语 xff0c 让你和客户沟通更加顺畅 xff01
  • Phpstorm2018 使用破解补丁永久激活

    1 安装phpstorm xff0c 安装包请自行官网下载 http www jetbrains com phpstorm download 2 下载JetbrainsCrack jar文件 xff0c 存放至你的phpstorm执行文件同
  • va_start 与 va_end用法

    1 包含头文件 include lt stdarg h gt 2 使用方法 参考 http www cnblogs com hanyonglu archive 2011 05 07 2039916 html include lt stdio
  • jetson-sd卡制作(批量烧写)

    jetson系列如果使用sd卡开发 xff0c 开发完成后可以不用重新制作根文件系统 拷贝目前的SD卡即可实现批量烧写 一 开发好的SD卡制作img文件 1 将sd卡插到PC端 xff0c 查看sd卡设备 eg dev sdd fdisk
  • 结构体知识点

    结构体的结构如下 xff1a span class token comment 关键字struct是数据类型说明符 xff0c 指出下面说明的是结构体类型 span span class token keyword struct span
  • SurfaceView 的一般绘制View用法(一)

    前段时间写了不少关于自定义View相关的文章 xff0c 最近两个项目同时开工 xff0c 忙成狗了 xff0c 这不是不写博客的理由哈 xff0c 今晚写一篇关于SurfaceView相关的博客 xff0c 还是和以前一样 xff0c 今
  • WorkerMan实现Web通讯(使用Vue实现前端页面逻辑)

    需要使用到的扩展 https github com tangbc vue virtual scroll list 最终效果 对话框 主页面 Main vue lt template gt lt div gt lt chat message
  • [VS][原创]vs2019新建项目提示未正确加载nvdapackage包

    第一步 xff1a 确认cuda 43 cudnn以及驱动程序都安装了 第二步 xff1a 从win11菜单栏搜索打开Developer Command Prompt for VS 2019 xff0c 注意要以管理员身份运行 xff0c
  • 2016年linux c程序员和初学者不得错过的精品图书18册

    1 图书名称 零点起飞学Linux C编程 图书信息 陈冠军 清华大学出版社 2013 09 01 2 图书名称 Linux C从入门到精通 图书信息 明日科 清华大学出版社 2012 12 01 3 图书名称 Linux C编程一站式学习
  • 面试造飞机系列:看架构师如何设计微服务接口

    来源 后端技术学堂 责编 Carol 封图 CSDN下载于视觉中国 在微服务设计中 xff0c 服务间接口通信设计常见的有两种方式 xff1a RPC 和 REST xff0c 关于微服务和 RPC 的更多细节 xff0c 可以参考我上一篇