微服务探索与实践—服务注册与发现

前言

微服务从大规模使用到现在已经有很多年了,从之前的探索到一步步的不断完善与成熟,微服务已经成为众多架构选择中所必须面对的一个选项。服务注册与发现是相辅相成的,所以一般会合起来思索。其依托组件有很多,比如Zookeeper,Consul,Eureka等等。

本文,我们将探讨服务注册和发现的概念及其使用机制,以使得微服务能够在不知道其确切位置(通常是URL)的情况下消费其他服务。由于本文主要是个人实践的一些总结,总会有不足之处,也希望各位看官帮忙完善。本系列前一篇文章请移步总述

服务注册与发现探讨

为什么需要

服务是在具有单独部署周期的不同计算机上运行的单个或较小的代码库,可明确解决相关的问题域。不正确的服务设计可能导致重复的服务创建,同时也无法进行架构层面的复用。

如果没有服务注册与服务发现,那么服务的位置将会耦合到消费者服务里面,最终将会导致整个系统的架构变得死板而又难以维护。事实上,在比较简单的系统架构里,采用静态配置的方式是非常简单而又效果显著的,毕竟所有服务都在同一位置,而且很少发生变更。

而在微服务里,其目标之一就是使系统能够独立开发、部署及升级扩展,随着系统的进一步复杂,服务位置也发生变更,那么静态配置就会变得十分鸡肋,此时我们需要变更我们的策略,那就是在消费其他服务的时候采用静态配置。那么核心问题就来了,服务是如何发现它们索要消费的服务的IP地址和端口号的?既是动态配置,在多实例场景下,配置在专门的系统里是最好的选择,ZK和Consul等也就应运而生。

简单的通信流程

我们来看一下一个简单的服务通信流程

640?wx_fmt=png

透过这张图,我们可以知道,服务调用时,无需知道目标服务的真实地址,只需要知道服务Key,然后到服务发现系统里获取对应的地址即可。

这张图虽然比较简单,但是传递的信息却有很多:

服务如何确定自身的IP地址及端口?

在消费方拿到被消费方的地址以后,应采用何种方式调用?

我们如何添加新服务并删除已弃用的服务?

如果服务在运行过程中出现问题,如何快速发现并提前通知?

作为集中化管理的服务注册与发现中心挂了,咋整?

服务信息注册

一般可以创建服务注册表,该服务注册表是服务及其实例及其位置的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。客户端查询服务注册表以查找服务的可用实例。服务注册表可能会调用服务实例的运行状况检查API来验证它是否能够处理请求。我们已经有了现成的工具,就是Consul等,那么我们的关注点就是服务地址的注册了。

最简单的解决方案就是手动配置。我们思考一个问题,如果我们需要对该服务进行水平扩展,再增加一个实例的时候,仍然需要我们手动配置,但是我们已经不想手动配置了,在DevOps时代,再使用手动配置,就显得不那么专业了,而且人工的介入,也增加了系统运维的成本与风险。

所以我们选择,自动获取本机IP地址,但是这里有一个问题,也是我在实际运用中遇到的问题就是本地会有多个网卡的情况,这是比较麻烦的,所以那时候我建议每台机器只配置一个网卡,以减少不确定性,但是后来,遇到一个新的问题就是,当我想在服务器上安装代理,以获取请求包信息的时候,容易改变系统的运行环境,依然存在着不确定性。后来我在网上查看是否其他方案的时候,始终没有一个比较好的解决方案,后来有人说,直接往服务注册中心发送一个Socket连接就可以了,通过Socket实例获取本机IP,网上也有人介绍这种方案。

至于端口获取,相对简单一点,我们使用的就是直接配置在服务里。

服务注册本身就是要在有限人力干预的情况下,支持不同应用之间的运行与交互。

服务注册扩展至之其他信息的注册

这个地方更多的是考虑服务消费方的负载均衡策略、调用策略以及容错的可配置性。640?wx_fmt=png

在被消费方做了集群部署的时候,这就是要求我们根据实际运行情况及时调整对服务的调用,那么该如何判断呢?在实现上可以考虑权重参数,该参数的设置应该来源于自身以及服务治理系统。

来源于自身,是因为我们的服务可能部署在相对较差的机器上或者该服务本身只是一个备用系统,不应该承载过大的流量。

来源于服务治理系统,是因为在实际运行中,可能该系统已经出现问题,或者需要暂时下线,我们可以设置权重系数为0,以从消费服务本身来停止对该服务的调用。

权重参数只是其中一个,也是最容易想到和实现的一个,当然还有其他参数,只要是为了更好的优化服务间的调用,那么就可以注册进去,同时实现相应的调用策略。比如版本号,TTL等等。

一旦信息多了,就需要考虑如何及时获取变更,以调整调用策略。

服务发现

服务发现可以分为客户端发现或服务器端发现来确定要向其发送请求的服务实例的位置。客户端发现比较简单一些,直接向服务发现中心获取所需的被消费者服务的信息。而服务端发现相对来说,比较复杂,需要创建一个路由中心,由路由中心去发现被消费者的请求。我们这边用的比较多的是客户端发现。

确保发现的稳定性,首先就要确保服务注册中心的稳定性,其地址不应该频繁发生变化,所以我们可以在服务中配置我们的服务注册中的地址。此处需要多说明一下,就是作为服务注册中心系统,一定要保持高可用性,可以通过集群以及负载均衡来增强可用性。

服务实例的数量及其位置是动态变化的。通常为虚拟机和容器分配动态IP地址。最复杂的问题自然是如何及时获得被消费者服务变化后的地址?我们可以创建一个路由功能,用户可以客户端查询服务注册中心以查找服务的可用实例。服务注册中心可能会调用服务实例的运行状况检查API来验证它是否能够处理请求。

我们在系统启动的时候,会做个Reload,以加载最新信息。那么之后如何及时获取最新信息呢?通常情况下有两种,主动轮询和获取推送消息。

主动轮询带有随机性,如果恰恰好,可能会很及时,大多数情况下,可能没那么恰恰好,而且还要增加服务发现中心的负载压力。

推送方式在效果上可能更好一些,在具体实现上可能没有那么简单。

健康检查

一般而言,健康检查包括,客户端心跳和服务端主动探测两种方式,

首先来说,客户端心跳,就是客户端通过TCP或者HTTP的方式,告诉服务端自身的运行情况,当然客户端通知是有弊端的,比如客户端在某一时间点出现故障时,无法及时通知服务端,事后恢复运行后,告知的也只是当前的运行状态,即便这时再告诉服务端之前的运行状况,也对服务调用没有什么太大意义了,只是对服务本身的运行分析起到了一定作用。即便是保持正常连接的情况下,服务也未必是可以调用的,比如数据库挂掉。

一般而言,采用服务端探测的比较多一些,调用方式和客户端心跳差不多,但是仍然需要我们注意的是,客户端所提供的探测接口必须具有通用性,比如可以查一下次数据库等等,这样可以比较全面的反应系统的运行情况。

容灾与故障转移

容灾的原因有很多,比如服务不再使用、双11大流量的涌进,使得其中一些服务不可用,也就不得不针对性的对一些服务进行容灾处理,以集中资源给核心应用。在容灾过程中,可以给服务下线功能可以制定一些策略,以丰富功能的使用。.NET Core里面可以使用IApplicationLifetime来显示下线功能。当然也需要提供手动下线的接口。

容灾主要考虑方向是客户端容灾和服务端容灾。客户端容灾中,如果服务注册中心挂掉了,恢复运行可能需要一段时间,在这个过程中如果保证服务正常运行。在实际运行中非常有可能发生这种情况,我们可以将服务发现中心获取的信息缓存起来,缓存方式有很多,无外乎是本地内存、文件以及外部存储,本地内存还要还要考虑该服务重启过程中的数据丢失,所以可选的方式就有内存+文件方式。反之,为了达到容灾的要求,我们可以在获取服务发现中心返回的数据的过程中将数据存在到内存和文件中,可以采用异步方式存储。

如下图所示,在发现过程中,使用缓存功能,如果缓存都失效了,那就真的要game over一阵子了。

640?wx_fmt=png

服务端容灾,就比较简单了,因为现在大多数做的都是服务端容灾,比如集群等水平扩展方式, 可主动从其他节点同步相应的数据,也可等待master的同步。

总结

服务注册与发现在服务生命周期中发挥着重要作用。动态的服务注册和发现变得非常重要,它可以避免服务中断。在处理服务实例的容灾与故障转移时,尽量实现自动转移,并提供手动方式处理,而对于跨服务调用,尤其是该服务拥有多实例服务的时候,需要考虑负载平衡。

640?wx_fmt=jpeg


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

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

相关文章

快速沃尔什变换:从入门到背板(含推导过程)

前(che)言(dan) FWTFWTFWT是个神奇的东西。 然而网上多数讲解多数直接给结论,顶多用归纳法证一证。 所以本文会讲解FWTFWTFWT的推导过程。 虽然也用到了构造,但是好背得多 参考博客:https:/…

微服务探索与实践—总述

背景软件开发是一个不断发展的过程,从当初的面向过程为主到如今的面向对象的开发,软件开发者不断探索与实践更加符合时代发展要求的开发模式与架构思想,而这,也在极大程度上提高了软件开发的效率。微服务是一种架构模式或者说是架…

P4097 [HEOI2013]Segment 李超线段树

传送门 文章目录题意:思路:题意: 实现以下两个操作: (1)(1)(1)在平面上加入一条线段。记第iii条被插入的线段的标号为iii (2)(2)(2)给定一个数kkk,询问与直线xkxkxk相交的线段中,交点纵坐标最大的线段的编…

【CF1204D】Kirk and a Binary String【结论题】【LIS】

传送门 题意:给一个01串SSS,求一个等长的01串TTT SSS和TTT所有对应位置的子串最长不下降子序列长度(以下简称LIS\text{LIS}LIS)相同TTT中0的数量尽量多 ∣S∣≤100000|S| \leq 100000∣S∣≤100000 对于一个01串SSS,…

这周,全球首个IT技术全中文免费学习平台诞生了!太惊艳!

本周三的Developer Wednesday为大家揭秘了Microsoft Learn网站的全新学习模式一时间Microsoft Learn圈粉无数如果你正在为错过直播而暴风哭泣等一等,看这里!全程高清回播将为你持续解密这一次你一定不可以再错过了哦!什么是Microsoft Learn&…

【CF1182D】Complete Mirror【树的重心】

传送门 题意:给一棵NNN个结点的树,你需要钦定一个根,使得所有深度相同的点的度数相同。 N≤100000N \leq 100000N≤100000 用脑子想一想,就是根节点直接相连的子树都长得一模一样。 如果根节点度数大于1,我们发现它…

P1989 无向图三元环计数 思维 + 建图

传送门 文章目录题意:思路:题意: 统计无向图中三元环的个数。 思路: 很明显有一种暴力的方法,就是枚举每条边,让后再跑两个点的所有边,可以卡到复杂度O(m2)O(m^2)O(m2)。 我们可以考虑给点之…

十分钟了解Kubernetes

何为Kubernetes?最简单的一句话来概括Kubernetes。它就是一套成熟的商用服务编排解决方案。Kubernetes定位在Paas层,重点解决了微服务大规模部署时的服务编排问题。Kubernetes组件介绍了解Kubernetes都是从Pod开始的。Pod是Kubernetes最小的调度单元,所…

【CF1020C】Election【贪心】

传送门 题意:NNN个人给MMM个党派投票,开始时每个人选择一个党派投票(给定),每个人可以花费一定代价贿赂(每个人给定代价),求让1号党派胜出(票数严格最大)的最…

Codeforces Round #627 (Div. 3) E. Sleeping Schedule dp

传送门 文章目录题意:思路:题意: 给你一天hhh小时,初始时间是000,每天可以使时间aia_iai​或者ai−1a_i-1ai​−1,问最多可以让多少天的时间在[l,r][l,r][l,r]范围内。 思路: 算是个比较简单…

【CF1194E】Count The Rectangles【类扫描线】【单调性】【树状数组】

传送门 题意:给定NNN条与坐标轴平行的线段,保证不垂直的线段没有交点,求一共构成多少个矩形(以线段交点为顶点)。 1≤N≤50001\leq N\leq50001≤N≤5000 显然是个数据结构乱搞题。 直觉告诉我们先枚举一条线段。 假…

.NET Core 的过去、现在和未来

在最新的微软 Build 大会主题网站上,微软.NET 程序经理 Scott Hunter 发表了一篇文章,指出.NET Core 是.NET 的未来。去年,微软就已经确认 Visual Studio Live 中的.NET 框架将会被.NET Core 取代。将.NET Core 作为开源开发技术栈在 2014 年…

Ozon Tech Challenge 2020 (Div.1 + Div.2) C. Kuroni and Impossible Calcul 抽屉原理

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个数组ana_nan​&#xff0c;求∏1≤i<j≤n∣aj−ai∣modm\begin{matrix} \prod_{1\le i<j\le n} |a_j-a_i| \end{matrix}\bmod m∏1≤i<j≤n​∣aj​−ai​∣​modm。 n≤2e5,m≤1e3n\le2e5…

【HAOI2015】按位或【Min-Max容斥】【FWT】

传送门 题意&#xff1a;开始时你有一个数000,每次选出[0,2n−1][0,2^n-1][0,2n−1]中的一个数进行按位或&#xff0c;每个数选中的概率给定。求得到2n−12^n-12n−1的期望操作次数。 1≤n≤201\leq n\leq 201≤n≤20 神仙题 首先发现每一位都是独立的&#xff0c;可以分开考…

Visual Basic 兴衰记

这是一篇暴露年龄的文章。为什么这么说&#xff1f;因为现在年轻的程序员可能没有接触过当年红极一时的 Visual Basic。28 年前的 1991 年 4 月&#xff0c;Microsoft 发布了 Visual Basic 1.0 for Windows&#xff0c;次年 9 月&#xff0c;发布了 Visual Basic 1.0 for DOS。…

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated) D. Kuroni and the Celebration 交互 + 思维

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一颗树&#xff0c;每次可以询问两个点的lcalcalca&#xff0c;询问次数不能超过⌊n2⌋\left \lfloor \frac{n}{2} \right \rfloor⌊2n​⌋&#xff0c;求它的根。 n≤1e3n\le1e3n≤1e3。 思路&#xf…

【CF1047D】Little C Loves 3 II【构造】【赛瓦维斯特定理】

传送门 题意&#xff1a;给一个NMN \times MNM的空棋盘&#xff0c;每次选取两个曼哈顿距离为3的空格子放上棋子&#xff0c;问最多能放多少个。 1≤N,M≤1e91 \leq N,M \leq 1e91≤N,M≤1e9 暴力讨论 假装N≤MN \leq MN≤M ①N1N1N1 容易得到&#xff0c;详见代码 ②N2N…

函数式编程里的Materialization应该翻译成什么?

Materialization是函数式编程里的一个专业术语, 用于特指函数式编程中查询被实际执行并生成结果的这一过程.首先, 搜了一下中文资料, 暂时没有对该词的中文翻译, CSDN\博客园\阿里云上所有关于它的文档都没有做中文翻译, 直接沿用这个英文单词.难道轮到我来创造这个词的中文翻…

Ozon Tech Challenge 2020 (Div.1 + Div.2) E.Kuroni and the Score Distribution 构造

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 不难想到&#xff0c;长度为nnn的数组最多的满足条件的三元组序列是1,2,3....,n1,2,3....,n1,2,3....,n&#xff0c;对于每一个位置贡献为i−12\frac{i-1}{2}2i−1​&#xff0c;那么如果m…

【CF1209E】Rotate Columns【状压DP】【位运算】【贪心】

题意&#xff1a;给一个NMN \times MNM的矩阵&#xff0c;可以进行任意多次操作将一列轮换&#xff0c;求每一行的最大值之和的最大值。多组数据。 Easy VersionN≤4N \leq 4N≤4,M≤100M \leq100M≤100 Hard VersionN≤12N \leq 12N≤12,M≤2000M \leq2000M≤2000 看这数据…