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

前言

微服务从大规模使用到现在已经有很多年了,从之前的探索到一步步的不断完善与成熟,微服务已经成为众多架构选择中所必须面对的一个选项。服务注册与发现是相辅相成的,所以一般会合起来思索。其依托组件有很多,比如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,一经查实,立即删除!

相关文章

微服务探索与实践—总述

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

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

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

十分钟了解Kubernetes

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

【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 年…

Visual Basic 兴衰记

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

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

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

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

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

Exceptionless(二) - 使用进阶

作者:markjiang7m2原文地址:https://www.cnblogs.com/markjiang7m2/p/11100563.html官网地址:http://letyouknow.net在上一篇文章Exceptionless - .Net Core开源日志框架中就说到如何对Exceptionless进行本地化部署,不过我也跟大家…

基于 Kong 和 Kubernetes 的 WebApi 多版本解决方案

前言大家好,很久没有写博客了,最近半年也是比较的忙,所以给关注我的粉丝们道个歉。去年和朱永光大哥聊的时候提了一下我们的这个方案,他说让我有空写篇博客讲一下,之前是非常的忙,所以这次趁着有些时间就写…

CodeCraft-20 (Div. 2) D. Nash Matrix 构造 + dfs

传送门 文章目录题意:思路:题意: 给定一个n∗nn*nn∗n的矩阵,每个点上面都有一个xi,yix_i,y_ixi​,yi​,表示这个点到xi,yix_i,y_ixi​,yi​这个点停下,当xi−1,yi−1x_i-1,y_i-1xi​−1,yi​−1的时候代表…

从严治码-别人在项目中下毒,我该怎么治?

01 从软考说起从4月份开始,由于备考《系统集成项目管理工程师》的原因,博客没有持续更新,在上半年考试结束之后,又对项目进行了一些收尾的工作。下面就这段时间的学习作一个记录和总结吧。在学习的过程中,提炼了一些自…

学习MVVM设计模式后第一次用于生产

WPF的MVVM设计模式从winform转变到WPF的过程,难点主要还是在MVVM的设计模式。当然,如果依然采用winform的涉及方式,在每个控件背后绑定事件的方式运用在wpf中,依然可行,但是假如GUI改版,其背后绑定的特别为…

netcore mvc快速开发系统(菜单,角色,权限[精确到按钮])开源

基于netcore2.0 mvc 开发的 快速搭建具有如下特色的后台管理系统用户管理菜单管理角色管理权限管理[精确到按钮])代码生成器代码克隆到本地 用vs2017或以上版本 打开工程。项目结构如下:找到DbModel下面的初始化db脚本里面包含4张表的schema和初始化数据…

asp.net core 系列之Startup

这篇文章简单记录 ASP.NET Core中 ,startup类的一些使用。一.前言在 Startup类中,一般有两个方法:ConfigureServices 方法: 用来配置应用的 service 。 Configure 方法:创建应用的请求处理管道它们都在应用启动时,被AS…

译 | .NET Core 基础架构进化之路(一)

原文:Matt Mitchell翻译:Edi Wang随着 .NET Core 3.0 Preview 6 的推出,我们认为简要了解一下我们基础设施系统的历史以及过去一年左右所做的重大改进会很有用。如果您对构建基础结构感兴趣,或者想要了解我们如何构建与 .NET Core…

剑指 Offer 27. 二叉树的镜像

思路:递归 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:TreeNode* mirrorTree(TreeNode*…

Codeforces Round #626 (Div. 2) D. Present 按位贡献 + 快排新姿势

传送门 文章目录题意:思路:题意: 给你一个长度为nnn的序列aaa,让你计算 n≤4e5,a≤1e7n\le 4e5,a\le 1e7n≤4e5,a≤1e7 思路: 首先这个式子是n2n^2n2的,显然不能直接算,并且异或没有分配律&…

.NET开发框架(一)-框架介绍与视频演示

本文主要介绍一套基于.NET CORE的SPA高并发、高可用的开发框架.我们暂且称它为:(让你懂.NET)开发框架。以此为主线,陆续编写教程,讲述如何构建高并发、高可用的框架。(欢迎转载与分享)它标准化了…

译 | .NET Core 基础架构进化之路(二)

原文:Matt Mitchell翻译:Edi Wang(接上篇 译 | .NET Core 基础架构进化之路(一))Maestro 及依赖流.NET Core 3.0 基础结构难题的最后一部分就是我们所说的依赖项流。这不是 .NET Core 的唯一概念。除非它们…