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

来源 | 后端技术学堂

责编 | 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 代码实现时间序列数据的统计学预测模型
真香,朕在看了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/518376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

日均处理万亿数据!Flink在快手的应用实践与技术演进之路

董亭亭&#xff0c;快手大数据架构实时计算引擎团队负责人。目前负责 Flink 引擎在快手内的研发、应用以及周边子系统建设。2013 年毕业于大连理工大学&#xff0c;曾就职于奇虎 360、58 集团。主要研究领域包括&#xff1a;分布式计算、调度系统、分布式存储等系统。 本次的分…

css-字体样式

字体样式 <!--font-family: 字体font-size: 字体大小font-weight: 字体粗细color: 字体颜色--><style>body{font-family: "Arial Black", 楷体,serif;color: #cdbb21;}h1{font-size: 50px;}.p1{font-weight: bolder;}</style><!--字体风格 ob…

小网站的容器化(下):网站容器化的各种姿势,先跟着撸一波代码再说!

作者 | 王洪鹏责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;封图| CSDN下载于视觉中国 上篇文章&#xff1a;小网站的容器化(上) 中我们大致描述了下个人网站在日常维护中的痛点&#xff0c;文章的后半部分我们添加了一个纯静态网站容器化的简…

阿里云应用高可用 AHAS 正式商用,可一键提升云上应用可用性

在分布式架构环境下&#xff0c;服务间的依赖日益复杂&#xff0c;可能没有人能说清单个故障对整个系统的影响&#xff0c;构建一个高可用的分布式系统面临着很大挑战。 7月17日&#xff0c;阿里云应用高可用服务AHAS 正式商用&#xff0c;包含架构感知、流控降级和故障演练三…

机器学习在高德起点抓路中的应用实践

导读&#xff1a;高德地图作为中国领先的出行领域解决方案提供商&#xff0c;导航是其核心用户场景。路线规划作为导航的前提&#xff0c;是根据起点、终点以及路径策略设置&#xff0c;为用户量身定制出行方案。 起点抓路&#xff0c;作为路线规划的初始必备环节&#xff0c;…

css-阴影和超链接伪类

阴影和超链接伪类 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* 默认的颜色 */a{text-decoration: none; /* 去掉下划线 */color: #000000; /* 修改颜色 */}…

时尚电商新赛道:揭秘 FashionAI 技术

雷音是阿里巴巴研究员、淘系技术部 FashionAI 负责人&#xff0c;在淘系技术嘉年华硅谷站&#xff0c;他分享了《时尚电商新赛道— FashionAI 中的技术》 &#xff0c;旨在揭秘&#xff1a;从面向机器学习的知识重建切入&#xff0c;提出了在 AI 能力的推动下&#xff0c;让人值…

MQ 技术产品井喷,今天来详聊一下腾讯开源消息中间件 TubeMQ | 原力计划

作者 | kimmking来源 | CSDN博客&#xff0c;责编 | 夕颜出品 | CSDN&#xff08;ID:CSDNnews&#xff09;随着分布式技术的发展&#xff0c;MQ技术产品也出现井喷。目前除了各类常用的MQ&#xff0c;比如Apache的ActiveMQ&#xff0c;Kafka&#xff0c;Pulsar&#xff0c;Rock…

MongoDB compact 命令详解

为什么需要 compact 一图胜千言 remove 与 drop 的区别 MongoDB 里删除一个集合里所有文档&#xff0c;有两种方式 db.collection.remove({}, {multi: true})&#xff0c;逐个文档从 btree 里删除&#xff0c;最后所有文档被删除&#xff0c;但文件物理空间不会被回收db.col…

css-背景图片和渐变

背景图片 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* 边框 border 1px粗细 solid样式 red颜色*/div{width: 1000px;height: 700px;border: 1px solid red;/*…

GitOps 初探

前言 GitOps 的概念最初来源于 Weaveworks 的联合创始人 Alexis 在 2017 年 8 月发表的一篇博客 GitOps - Operations by Pull Request。文章介绍了 Weaveworks 的工程师如何以 Git 作为事实的唯一真实来源&#xff0c;部署、管理和监控基于 Kubernetes 的 SaaS 应用。 随后&…

老码农吐血建议:2020年,低于1w的程序员要注意了...

最近在知乎上&#xff0c;关于AI的这个话题又被顶起来&#xff0c;其中&#xff0c;这条回答让人印象深刻&#xff1a;在这短短的一条信息里&#xff0c;无疑显示出&#xff1a;AI行业缺人&#xff0c;高端岗位80万年薪恐怕也招不来&#xff01;小编上周在一个AI群里&#xff0…

重磅!容器集群监控利器 阿里云Prometheus 正式免费公测

Prometheus 作为容器生态下集群监控的首选方案&#xff0c;是一套开源的系统监控报警框架。它启发于 Google 的 borgmon 监控系统&#xff0c;并于 2015 年正式发布。2016 年&#xff0c;Prometheus 正式加入 Cloud Native Computing Foundation&#xff0c;成为受欢迎度仅次于…

Archsummit 2019重磅分享|闲鱼Flutter&FaaS云端一体化架构

作者&#xff1a;闲鱼技术&#xff0d;国有   讲师介绍 国有&#xff0c;闲鱼架构团队负责人。在7月13号落幕的2019年Archsummit峰会上就近一年来闲鱼在Flutter&FaaS一体化项目上的探索和实践进行了分享。 传统NativeWeb服务端混合开发的挑战 随着无线&#xff0c;Io…

Spring Cloud 云架构下的微服务架构:部门微服务(Dept)

作者 | springML来源 | CSDN 博客 责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;封图| CSDN下载于视觉中国 对于 Rest 基础架构实现处理是 SpringCloud 核心所在&#xff0c;其基本操作形式在 SpringBoot 之中已经有了明确的讲解&#xff0c;…

并发模式与 RPS 模式之争,性能压测领域的星球大战

本文是《如何做好性能压测》系列专题分享的第四期&#xff0c;该专题将从性能压测的设计、实现、执行、监控、问题定位和分析、应用场景等多个纬度对性能压测的全过程进行拆解&#xff0c;以帮助大家构建完整的性能压测的理论体系&#xff0c;并提供有例可依的实战。 该系列专…

Akka in Schedulerx2.0

1. 前言 Schedulerx2.0是阿里中间件自研的基于akka架构的新一代分布式任务调度平台&#xff0c;提供定时、任务编排、分布式跑批等功能&#xff0c;具有高可靠、海量任务、秒级调度等能力。 本篇文章以Schedulerx2.0为例子&#xff0c;介绍akka的应用场景&#xff0c;希望能给…

java.sql.SQLException: The server time zone value ‘???ú±ê×??±??‘ is unrecognized or represents more

【报错信息】 【百度翻译】 服务器时区值???????无法识别或表示多个时区。如果要利用时区支持&#xff0c;必须配置服务器或JDBC驱动程序&#xff08;通过ServerTimeZone配置属性&#xff09;&#xff0c;以使用更具体的时区值 【解决方法】 数据库连接配置conf.xml(…

【从入门到放弃-Java】并发编程-锁-synchronized

简介 上篇【从入门到放弃-Java】并发编程-线程安全中&#xff0c;我们了解到&#xff0c;可以通过加锁机制来保护共享对象&#xff0c;来实现线程安全。 synchronized是java提供的一种内置的锁机制。通过synchronized关键字同步代码块。线程在进入同步代码块之前会自动获得锁…

Redis 学习之一招击穿自己的系统,附送 N 个击穿解决大礼包 | 原力计划

作者 | Mark_MMXI来源 | CSDN博客&#xff0c;责编 | 夕颜出品 | CSDN&#xff08;ID:CSDNnews&#xff09;缓存的存在是为了在高并发情形下&#xff0c;缓解DB压力&#xff0c;提高业务系统体验。业务系统访问数据&#xff0c;先去缓存中进行查询&#xff0c;假如缓存存在数据…