不是后端也应该知道的「 web 服务、子服务、服务的部署」

web 服务是什么

1. 定义

我们先来看一个很通俗的定义,来自于wiki。

Web service 指的是,一个平台通过 web 向其它平台来提供服务。

更专业一点的定义怎么说呢?我们来看一下 W3C 对 web service 的定义。

Web service 是一个软件系统,使得不同机器可以在网络间进行互动操作。

2. 要素

想要实现一个平台在网络间调用另一个平台的服务,至少需要明确三点:

  • 如何将平台上的代码作为服务暴露出去供其它平台调用;
  • 使用什么样的网络协议通信;
  • 使用什么样的格式作为通信内容。

从 WSDL 理解 web service 的要素

要回答以上问题,我们可以先简单的了解一下什么是 WSDL,Web Services Description Language,网络服务描述语言。我们知道服务的提供方其实本质上是由代码编写而成,而服务的调用方通过发起一个网络请求来调用服务。那么通俗的说,WSDL 做的事情就是,描述了如何根据调用方发送的网络请求,找到服务提供方,进而找到要运行哪一段代码,从而得到结果返回给调用方。

WSDL 是基于 XML 格式的文档,包括两部分,抽象定义和具体定义。

WSDL的抽象定义

WSDL 的抽象定义,独立于提供服务的平台和服务实现的语言,定义了该服务通过什么样的网络协议、使用什么样的消息格式与调用方通信。网络协议是不受限制的,可以是 http、ftp、smtp 等其它网络传输协议,不过大部分情况下我们使用的是 http 协议。消息格式也是多种多样的,最初唯一被广泛使用的消息格式是基于 XML 格式的 SOAP,简单对象访问协议,后来 REST 流行了起来,出现了基于 REST + XML 的消息格式,再后来发展为 REST + JSON 的消息格式,也就是我们现在应用最广泛的一种。

WSDL 的具体定义

WSDL 的具体定义,与平台和语言相关,定义了一个具体的服务调用,请求参数和返回参数是怎么样的、以及通过哪一部分代码的运行可以得到结果等等。

咖啡馆的类比

我们使用一个咖啡馆来类比 WSDL 的工作原理,咖啡馆是服务提供方,提供了下单、取餐、付款等服务,咖啡馆的员工手册则相当于提供服务的代码,顾客是服务调用方。WSDL 的抽象定义,定义了顾客如何找到咖啡馆的位置,以及顾客和咖啡馆的员工使用哪国语言进行交流等等;而 WSDL 的具体定义,则定义了每一个具体的服务,如下单服务,顾客需要提供什么,工作人员在员工手册的哪一页可以找到下单的操作流程,以及工作人员会返回什么给顾客,等等。

WSDL 文档可以由服务的实现代码自动生成,反之也可以通过定义好的 WSDL 文档生成代码框架。

3. 应用方式

最常见的两种 web service 的组织形式是:RPC 远程过程调用,REST 表述性状态转移。从本质上来说,两者定义的都是规范,一个是面向过程的远程调用规范,一个是面向资源的远程调用规范。

RPC 远程过程调用

RPC,Remote Procedure Call,远程过程调用,定义了平台与平台之间面向过程进行服务调用的规范。它的本质思想是,将一个平台上的多个函数过程,作为一个服务,提供给另一个平台调用。所以以 RPC 为规范的服务,需要关心的是「我要做一件什么事」。RPC 规范是协议无关的,可以使用各种网络协议实现。

REST 表述性状态传递

那么 REST 又是什么?不知道 REST 没关系,如果你接触过 GET、POST、PUT、DELETE 这样的请求,不要怀疑,这种我们通常意义上所说的 http 请求大部分都是基于 REST 规范而来的。基于 REST 规范设计的 api 也称之为是 RESTful 的 api,这样的 api 的主题必须是资源,它关心的是「我要对某个资源进行什么样的操作」。为什么 REST 可以流行起来呢?这就跟我们为什么要用面向对象的思想进行编程是一个道理,万物皆对象,外物皆资源。这里推荐一篇非常通俗的讲解 REST 规范的文章 如何给老婆解释什么是RESTful。

RPC 与 REST 的比较

总的来说,PRC 与网络协议无关,关心的是过程;REST 基于 http 协议,关心的是资源。下图演示了针对相同的有关用户的操作,REST 形式的服务(左边)和 RPC 形式的服务(右边)设计上的区别。

那么在具体的使用场景下,对于两种设计规范,我们应该如何选择呢?我觉得二者的取舍,可以类比于函数式编程与面向对象的编程,各自有各自适合的场景,甚至在某些场景下,使用二者皆可且各有利弊。重要的是要理解这两个设计规范的本质和初衷,并根据实际场景和个人的使用习惯最初抉择。

web service 与子服务

在谈子服务之前,我们来继续之前咖啡馆的假设,从而理解什么是子服务以及我们为什么需要子服务。

为什么我们需要子服务

设想一个咖啡馆的正常运作,需要以下职能人员的参与。

  • 前台:负责创建、修改、删除客户的订单
  • 收银员:收取订单相应的费用、找零、管理咖啡馆的日常支出
  • 服务生:为客户配送咖啡到相应的座位上,回收餐具
  • 清洁工:维护店内清洁、桌椅摆放、空调灯光等硬件设施
  • 经理:保证店铺正常运行,解决问题和异常情况

对于这些职能人员来说,核心要素有三点:

  1. 他们所做的工作有明确的界限划分;
  2. 他们互相之间可能需要进行交流;
  3. 他们共同维护了咖啡馆的运作。

为什么咖啡馆不是由一个非常厉害的全能的人承担所有的工作呢?这个很容易理解:

  • 首先厉害的人比普通人更加难找到;
  • 而且要同时兼顾这么多的工作内容是更加容易出错的;
  • 还有最重要的一点是,如果他生病了,整个店就完全没有办法运作下去。

那么将咖啡馆的例子映射到 web 服务上,提供一个单一的 web 服务来支持整个咖啡馆的运作自然也是不合理的:

  • 想要维护好一个大型的系统比维护好一个小型的系统更加困难;
  • 业务逻辑冗杂的系统更容易出错;
  • 如果这个系统的一小块内容出现问题很容易导致整个系统的崩盘。

那么如何拆分一个服务系统呢,答案就是子服务了。我们将整个系统根据职能的划分拆分成5个子服务,分别对应到上文的5种职能人员。

  • 订单管理服务
  • 账户管理服务
  • 餐具管理服务
  • 店内环境管理服务
  • 性能监控与异常处理服务

同样的这些子服务的核心要素如下:

  • 这5个子服务所提供的接口有明确的界限划分;
  • 子服务之间可以互相调用;
  • 共同保证了整个咖啡馆的运作。

理解了子服务的概念以及 web service 为什么需要子服务之后,新的问题出现了:子服务如何进行合理的拆分?如何管理多个子服务?子服务间如何通信?

这里就不得不提到 SOA 了。

通过 SOA 架构组织子服务

SOA,Service Oriented Architecture,是一个面向服务的架构设计,通俗的说它也是一个规范,定义了如何管理服务的集合及他们之间的通讯方式。它本质上和 web service 以及子服务都没有绝对的依赖关系,它甚至比 web service 出现的更加早。然而人们在 web service 上发现了它的用武之地,也就是说 SOA 刚好可以在 web service 的管理上体现它的价值。于是乎,造成了几乎所有 SOA 的应用场景都与 web service 相关这样的现状,也导致了这两个概念一定程度上发生了混淆。

既然 SOA 框架是对服务的集合的管理,那么它究竟比单纯的服务拆分多做了哪些事情呢?

我们来看一下下图这个简单的例子。假设我们要将整个系统拆分成4个子服务:ACCOUNT、C2D、ASK、DESIGN。左边为单纯的服务拆分,右边为基于 SOA 框架的服务拆分。

  • 左边:单纯的进行了服务拆分,形成了4个互独立的服务。这里其实就出现了两个问题:客户端需要关心我请求的 api 到底是属于哪个服务的,然后再往相应的服务端发送请求;虽然服务做了拆分,但是如果其中一个服务出现问题挂掉了,那么整个架构中的服务都不可用。
  • 右边:将这4个子服务作为一个服务的集合,并简单地应用了 SOA 架构。可以看到除了四个子服务之外,最上层还多了一个 gateway,而最下层也多了三个底层模块。最下层的三个底层模块很好理解,有一些工作是每个子服务都需要做的,比如版本控制、性能监控等,底层就是抽出了这样的公共模块以便子服务复用。最上层的 gateway,网关,顾名思义,你们如果想访问我管理的这些子服务,直接访问我就好了;也就是说客户端只需要向 gateway 发送请求,gateway 会根据所配置的规则将请求转发到正确的子服务上,这也就解决了上文所述左边的设计中遇到的两个问题。

子服务及子服务的部署

1. 服务的实现

web 服务是一个软件系统,软件系统是通过代码形成的。那么这样一个软件系统是如何从一大坨代码转化为稳定的、可访问的、可更新的服务的呢?

一个有一定流量的服务一般是由类似这样的结构组成的。

上层是一个负载均衡器(load balancer),下层是多个相同的节点(node)。

  • 负载均衡器:将针对这个服务的请求,合理的分发到下面的某一个节点上,以尽量达到这样的目的:请求尽可能的被完成(例如其中一个节点没有正常运行不会导致请求失败)、每个节点承担均匀的压力(例如同时有一万个请求,不至于扎堆到同一个节点上去导致节点出现性能问题)。负责均衡器可以通过网络设备、虚拟 ip、nginx 反向代理、甚至仅仅是一段代码来实现。
  • 节点:每个节点都是等同的,每个节点上都运行着相同的服务,等待处理负载均衡器转发过来的请求。节点可以是一个物理机、虚拟机、也可以是一个 docker 容器。

2. 服务的部署

服务的部署,简单来说就是将该服务的软件系统的最新代码克隆到每一个节点上,再在每一个节点上将服务运行起来。那么服务的更新无非就是重新对每一个节点进行一次部署。

但是不要忘记,在一个节点上重新运行服务会导致该节点的服务有一个短暂的罢工,那么如何保证在完成对服务的更新的同时,保证对于客户端来说服务不会出现挂掉的状态?这时候就需要一定的部署策略。

注:下图中绿色节点均表示未更新节点,蓝色节点均表示已更新节点

1)滚动部署

滚动部署,每次只更新 n 个节点,等待前 n 个节点部署好了,再更新下 n 个节点,这样可以保证同一时间只可能最多有 n 个节点处在不可用状态。

下面四张图是一个滚动部署过程的例子,例子中 n 为 1。

首先更新第一个节点。

待第一个节点更新完毕之后,更新第二个节点。

待第二个节点更新完毕之后,更新第三个节点。

待第三个节点更新完毕之后,更新第四个节点。全部的节点都完成了更新。

滚动部署的缺点是,在部署过程中,客户端可以同时访问到更新前的服务和更新后的服务。

2)蓝绿部署

蓝绿部署,如下面三张图所示,分为三个步骤。

首先新增四个节点,并将新版的服务部署上去。

全部部署好之后将负载均衡器指向新的四个节点。

移除原有的旧版本服务的四个节点。

蓝绿部署解决了滚动部署会同时出现新旧服务并存的缺点,但是对资源的要求更高。

3)灰度发布

灰度发布是平滑过渡的一种发布方式。让一部分用户继续用旧版本的服务,一部分用户开始体验新版本的服务,如果用户对新版本没有什么反对意见,那么逐步扩大范围,将所有的旧版本服务更新为新版本服务。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以避免产生无法挽回的影响。灰度发布的实现如下面三张图所示。

首先更新一个节点。

然后通过负载均衡器按照一定的规则筛选出 20% 的用户(比如用户 id 除以 5 余 0),并将这 20% 的用户所发出的全部请求都转发到已经更新过的节点。

再更新第二个节点,并将包含之前那 20% 的用户的 50% 的用户的请求转发到两个更新过的节点上去。

以此类推直到所有节点更新完毕,100% 的用户的请求都会请求到新的服务。这里需要注意的是,灰发的用户百分比最好和更新节点的占比相近,这样可以保证每个节点可以承受相似的压力。如果只更新了一个节点,而转发了 90% 的用户的请求到新服务上,那么这个节点很可能会出现性能问题。

原文地址:https://www.cnblogs.com/CQqf2019/p/11149646.html

时间: 2024-08-29 13:30:54

不是后端也应该知道的「 web 服务、子服务、服务的部署」的相关文章

100offer举办的「寻找实干和坚持的技术力量」开源项目投票排名分析程序

由于100offer举办的「寻找实干和坚持的技术力量」开源项目投票活动没有按照票数排序的功能,所以本文写了个小程序来实现这个功能,代码如下: import org.jsoup.Jsoup; import org.jsoup.nodes.Element; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /**

从0開始学习 GitHub 系列之「07.GitHub 常见的几种操作」

之前写了一个 GitHub 系列,反响非常不错,突然发现居然还落下点东西没写,前段时间 GitHub 也改版了,借此机会补充下. 我们都说开源社区最大的魅力是人人多能够參与进去,发挥众人的力量,让一个项目更完好.更强壮.那么肯定有人疑问,我自己眼下还没有能力开源一个项目,可是想一起參与到别的开源项目中.该怎么操作呢?那么今天,就来给大家一起介绍下 GitHub 上的一些常见的操作,看完之后你就知道方法了. 我们姑且以 Square 公司开源的 Retrofit 为例来介绍. 打开链接: http

带你从二次元的角度看建筑「摩根·帝巢丨湛江工程资质×××」

我从小到大是个十足的动漫迷,从小学开始迷恋日本漫画直至现在.从<哆啦A梦>.<樱桃小丸子>这批经典到后来的<海贼王>.<火影忍者>这批灌输热血的鸡汤--但如今似乎更流行二次元动漫. 二次元动漫不仅盛产帅哥美女,还有就是美到让人停止呼吸的建筑!带你从二次元的角度看建筑「摩根·帝巢丨湛江工程资质×××」 引人入胜的故事情节.个性另类的角色设定自然是一部动漫制作成功的必要元素,但是,二次元动漫中呈现的各种或空灵的或美轮美奂的建筑群,也无一不给人以崇高的感觉. 如果

SpringCloud微服务之跨服务调用后端接口

SpringCloud微服务系列博客: SpringCloud微服务之快速搭建EurekaServer:https://blog.csdn.net/egg1996911/article/details/78787540 SpringCloud微服务之注册服务至EurekaServer:https://blog.csdn.net/egg1996911/article/details/78859200 SpringCloud微服务之集成thymeleaf访问html页面/静态页面&热部署:https

宜信技术学院上榜「2019中国技术品牌影响力企业榜」

12月25日,开发者社区和专业技术媒体SegmentFault发布了2019 中国技术品牌影响力企业榜.凭借过去一年对宜信科技成果和技术实践的传播以及在金融科技领域探索方面的积极努力,宜信技术学院登上榜单前10. 宜信技术学院成立于2017年,专注于分享与传播宜信技术团队的研发实践成果与技术解决方案.经过多年的探索和实践,宜信技术团队沉淀了海量的软件研发经验,特别是在金融科技领域,积极探索软件技术在金融服务与金融安全保障方面的智能化.创新性的技术解决方案,并取得了非常多的技术成果.2019年,围

Android 背景可滑动登录界面 「 实现不压缩背景弹出键盘 」

Android 背景可滑动登录界面 废话不多说,先看下实现后的效果: 实现思路 看到上边 gif 图的效果,主要列举一下实现过程过程中遇到的难点. 如何使键盘弹出时候不遮挡底部登录布局: 当键盘弹出的时候如何不压缩背景图片或者背景延伸至「屏幕以外」: 从 「 windowSoftInputMode 」 说起 相信大家都清楚,Google 官方提供给开发者控制软键盘显示隐藏的方法不多,「windowSoftInputMode」算是我们可控制的软键盘弹出模式的方法之一.关于其属性的说明Google

Linux 小知识翻译 - 「为什么安全是互联网的问题?」

当然,虽说「由于有心怀不轨的人在,一定要注意安全问题」.但另一方面,也有人认为「如果互联网自己就考虑好安全问题的话,那么用户就不用再担心安全问题了」. 虽然经常有人这样说「与远程机器通信的时候,避免使用明码传输数据的telnet,而是使用加密传输数据的SSH」,但也有人认为,通信本身这种容易被窃听的机制才是问题所在. 这得从互联网诞生的秘密说起了.互联网的前身被称为「ARPANET」,是以美国国防部为中心研究的,用于军事上的通信网络. 这个网络仅仅是以研究为目的,非常有限的一些人在使用,本来就不

「祭3900万、瞄准27国」 英特尔征穿戴点子!

SONY.三星等等不少大厂纷纷抢进穿戴装置,全球处理器龙头英特尔除了年初CES展上,已经秀了不少穿戴概念之后,现在更进一步广发英雄帖,向美国.日本.台湾等全球27个国家素人,征求创意穿戴点子,预计要送出的总奖金高达130万美元,相当于台币近3900万,同时还成立穿戴装置部门,为的就是希望做出最具创意的穿戴产品,同样身为芯片大厂,台湾的联发科一点也不逊色,除了也成立穿戴装置事业群之外,更打算推出一款名为「胶囊」的软件包,让穿戴开发者可以快速设计产品,被称为是「破坏式」的创新. 英特尔发展穿戴装置,

XE7 提交 App(iOS 8)提示「does not contain the correct beta entitlement」问题修复

XE7 提交 App 后,在「Prerelease」里被提示了: Build 1.0.0 does not contain the correct beta entitlement. For more information, see the iTunes Connect Developer Guide. 可能因为 XE7 来不急跟上 iOS8 的变化,不过相信很快就会有 XE7 的更新来修复这个问题. 在网上可以搜寻到很多相关的问题,也有提供解决的方案,但在 XE7 需要如下方式来修复: 重新