抽丝剥茧 分布式服务框架设计 理论设计篇

1、概述

        前面几篇文章给大家详细的介绍了Zookeeper的基础概念以及应用的领域,今天我们讨论的话题是如何自研一套分布式服务框架。早些年有很多基于Dubbo和Zookeeper的分布式系统,这篇文章我们就来聊下如何设计一个分布式服务框架。

2、系统间交互

2.1、问题引入

        首先我们想象一下,在一个分布式系统的环境中肯定是会有多个子系统(服务),每个子系统都负责处理和自己相关的业务,当发现自己不具备处理某项业务的能力的时候 这个时候就需要依赖(耦合)其他系统提供的功能了。也就是我们老生常谈的系统间交互的过程。

        正如上图所示,Jerry想吃奶酪,但是需要依赖Tom才能拿到奶酪,这个过程就是一个系统间交互的过程,在这个过程里我们需要关注以下几点

1、Jerry需要找Tom  

2、找到Tom后需要告诉Tom自己想要吃个奶酪

3、Tom需要接受到Jerry的需求

4、Tom需要给Jerry一个奶酪,或者告诉他怎么找到奶酪

2.2、服务之间怎么沟通

如果我们需要设计一个系统,完成上述的交互过程,我们就需要考虑以下几点内容

1、Jerry怎么找到Tom,去哪里找

2、Jerry通过什么方式告诉Tom自己的需求

3、Tom通过什么方式接收Jerry的请求

4、Tom将奶酪或者奶酪的位置以什么样的形式返回给Jerry

        这个时候我们就需要制定一套规范,Tom每次外出活动的时候 需要把自己的位置告诉Spike,同样的Jerry每次出去玩的时候也需要将自己的位置告诉Spike。这样的话大家不仅可以自由的活动,并且还能够通过Spike联系到对方。

2.3、服务注册中心

        如上图所示 Spike 记录了 Tom和Jerry的位置。当Jerry 需要调用Tom对外提供的服务的时候,就可以先询问Spike,通过Spike获取到Tom的ip,同样的Tom需要访问Jerry的时候也可以通过Spike获取到Jerry的ip。这样Tom 和Jerry  就都知道了对方的位置,也就能找到对方了。在这个过程中 Spike扮演的角色就是服务注册中心。

        服务注册中心的作用之一就是记录各个服务的注册信息,并且还提供服务发现的功能呢,就类似Spike会记录Tom And Jerry 的IP,还能告诉Jerry Tom的ip,或者告诉Tom Jerry的位置,

2.4、通信协议

        在这个过程中Jerry可以获取到Tom的ip,这样Jerry 就能够往Tom那里发送一个数据包,告诉Tom自己的需求,但是 这个数据包要怎么发出去呢?以什么样的组织形式发出去呢?Tom是否能够正常的解析? 

        这个时候就需要引入了网络通信协议了,通信协议是个比较庞杂的东西,后面我们再单独聊。我们先假设Tom和Jerry之间都是使用HTTP协议进行通信。

 2.5、Jerry 拿到了奶酪

我们重新回到2.1章节的4个问题上面来

1、Jerry 可以从 Spike 哪里获取到 Tom的ip

2、Jerry 通过HTPP协议 将自己的需求 发送给Tom

3、Tom接收到Jerry 发送的HTTP请求后按照HTTP协议的格式和规范解析

4、Tom 将奶酪或者奶酪的信息 放在请求主体中返回给Jerry

好了,经过上面的4个步骤,Jerry 就能够拿到一块奶酪了。

3、顶层设计

        我们大体上已经梳理清楚了Jerry 拿到一块奶酪的整个流程了,现在我们就来将这个流程落地,形成一款优秀的框架,首先我们需要做技术选型和架构设计的工作

3.1、功能规划

        我们本次实现的是一款简洁优雅的分布式服务框架,前期我们需要实现的功能主要是 服务注册、服务发现、远程调用 这三块,他们是一个分布式服务框架的核心,后面我们再基于这核心的三大块逐步优化和完善,让我们的这款框架达到生产可用的要求。

项目以 jar 包的形式发布出去,第三方应用引入了这个 jar 就能基于它构建一套分布式系统。

这里先给我们的这个服务框架取个名字,暂时就先命名为 cheese(奶酪) 吧。

3.2、技术选型

        基础架构我们采用 SpringBoot 和 Zookeeper 来实现,这里Zookeeper的客户端工具我们使用Apache Curator。相关的版本信息如下

SpringBoot3.2.9
Zookeeper3.9.1
Apache Curator  

5.7.0

 3.3、架构设计

        我们已经知道了系统间交互的过程了,现在我们需要对上述过程进行架构设计,将前面整个交互的过程设计成一套可落地的方案。

        cheese 是一款分布式服务框架,我们从最顶层来看,cheese 需要实现远程调用的功能,这里我将它称为RemoteServer。

        对于服务消费者(Jerry)来说,我需要知道服务提供者(Tom)的IP和端口这些信息。所以cheese需要提供服务发现的能力,同样的服务提供者Tom需要将自己的IP和端口对外开放,cheese需要具备服务注册的能力。这里需要分别设计 RegistServer 和 DiscoveryServer 

        最后我们需要和Zookeeper交互,这里就将这个模块叫做CuratorExecute吧,整体的架构如下图所示

当然,我们还需要一个框架内部的监听机制,当应用启动的时候,所有的需要对外暴露的服务初始化完成后,需要将这个服务的信息 通过 CuratorExecute 存放 到 Zookeeper上。这里我将这个组件设计成一个ApplicationListener。

4、详细设计 

        从顶层设计上我们已经知道 Cheese 作为一款分布式服务框架 必须包含 RemoteServer 、RegistServer、DiscoveryServer、ApplicationListener以及CuratorExecute 这些组件,下面我们就一起来详细的聊聊这些组件要实现的功能 以及相互之间需要怎么协作。

4.1、RemoteServer设计

       RemoteServer 的主要 职责是远程调用,也就是承载服务消费者(Jerry)在获取到服务提供者(Tom)的ip和端口之后 将自己的请求发过去的能力。

      关于应用层协议 这里我们先采用HTTP协议,因此我们可以选择相对简单的HttpClient实现。

      这部分我们直接使用SpringBoot里面的 RestTemplate。我们可以直接将 RestTemplate 注入到 RemoteServer 中即可。

4.2、RegistServer 设计

       RegistServer 是一个服务注册的组件,功能上看 它需要承载的能力是 将自己对外暴露的服务通过 CuratorExecute 组件注册到Zookeeper上去。那么怎么在应用启动的时候获取到需要外暴露的服务呢。

一种可行的方案是 当应用启动的时候,我们设计一个 ApplicationListener 组件,由这个组件去寻找需要对外暴露的服务,然后交给 RegisterServer 

4.3、DiscoveryServer 设计

       服务发现组件 需要实现的功能就是 从zookeeper上获取一个有效的服务对应的IP和端口,然后交给 RemoteServer 组件。支撑 RemoteServer 远程调用的能力。在Cheese 里面 DiscoveryServer 的功能 需要CuratorExecute来支撑 

4.4、CuratorExecute设计

 CuratorExecute 是cheese与Zookeeper交互的核心, cheese 需要通过 CuratorExecute 操作

Zookeeper。并且他需要为  RegistServer 组件和 DiscoveryServer 组件 保驾护航。

CuratorExecute 的具体功能  我们使用 Apache Curator 来实现

4.5、ApplicationListener设计

        ApplicationListener 组件的功能是 需要在应用程序启动后 找到要对外暴露的服务,然后将它交给 RegisterServer 组件,该组件需要关注的是 怎么获取到需要对外暴露的服务,这里需要大家对Spring有一定基础了。Cheese 里面采用了Spring 内置的监听器机制实现的。

4.6、整体流程设计

我们已经分别设计了 RemoteServer 、RegistServer、DiscoveryServer、ApplicationListener以及CuratorExecute 这些组件。并且详细的规划了他们各自需要具备的能力,最后还提供了他们支撑的解决方案。

5、总结

        Cheese 是本篇文章的主角,关于她的雏形和项目架构相信大家已经有了很清晰的认知了,目前的设计虽然十分简陋,但我们的目标是先把Cheese生产出来,然后用起来,后续我们在使用的过程中发现了问题 在逐步的解决,让Cheese 持续的演进。

关于设计理论篇就先告一段落,接下来我们就需要进行编码落地了,具体可查阅 

抽丝剥茧 分布式服务框架设计 实战落地篇

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

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

相关文章

C++STL——list

C教学总目录 list 1、list简介2、构造函数3、迭代器4、访问和容量函数5、修改类函数6、操作类函数 1、list简介 list是带头双向循环链表&#xff0c;也是模板类&#xff0c;使用时要指明类型&#xff0c;包含于头文件<list> 由于list是双向循环链表&#xff0c;在任意位置…

YoloV8改进策略:Block改进|RFE模块,提高小物体的识别精度|即插即用|代码+修改过程

摘要 论文介绍 本文介绍了一种基于YOLOv5的人脸检测方法,命名为YOLO-FaceV2。该方法旨在解决人脸检测中的尺度变化、简单与困难样本不平衡以及人脸遮挡等问题。通过引入一系列创新模块和损失函数,YOLO-FaceV2在WiderFace数据集上取得了优异的表现,特别是在小物体、遮挡和困…

leaflet矢量瓦片vetorgrid显示聚合和图标裁剪显示不全的问题

1、问题现象 使用leaflet显示矢量瓦片会出现图片挤压的问题和图片裁剪显示不全的问题 2、解决办法和思路 1&#xff09;数据抽稀 方法一&#xff1a;在createTile方法通过控制feature在单张瓦片里面显示的数量&#xff0c;在小层级的时候进行筛选过滤&#xff0c;对点数据类…

Gitee push 文件

1、背景 想将自己的plecs仿真放到git中管理&#xff0c;以防丢失&#xff0c;以防乱改之后丢失之前版本仿真。此操作说明默认用户已下载git。 2、操作步骤 2.1 开启Git Bash 在文件夹中右键&#xff0c;开启Git Bash。 2.2 克隆文件 在Git Bash中打git clone git地址&#…

gitee 使用 webhoot 触发 Jenkins 自动构建

一、插件下载和配置 Manage Jenkins>Plugin Manager 搜索 gitee 进行安装 插件配置 1、前往Jenkins -> Manage Jenkins -> System -> Gitee Configuration -> Gitee connections 2、在 Connection name 中输入 Gitee 或者你想要的名字 3、Gitee host URL 中…

【JavaEE初阶 — 多线程】Thread类的属性

目录 Thread类的属性 1.Thread 的常见构造方法 2.Thread 的几个常见属性 2.1 前台线程与后台线程 2.2 setDaemon() 2.3 isAlive() Thread类的属性 Thread 类是JVM 用来管理线程的一个类&#xff0c;换句话说&#xff0c;每个线程都有一个唯一的Thread 对象与之关联&…

yocto是如何收集recipes,如何加入现有的bb文件

yocto通常是如何收集recipes: 在Yocto中&#xff0c;通过以下方式收集recipes&#xff1a; 层&#xff08;Layers&#xff09; Yocto项目使用层来组织recipes。层是包含配置文件、recipes和其他相关文件的目录结构。每个层有自己的目录&#xff0c;其中 recipes-* 目录用于存…

原生鸿蒙的竞争力到底如何?

目录 1. 崛起与挑战2. 安全机制3. 自动化检测前移4. 深入探讨开发者服务优势 1. 崛起与挑战 长期以来&#xff0c;移动操作系统市场被IOS和安卓所垄断&#xff0c;一直都难以推出完整的自主系统&#xff0c;面临诸多挑战&#xff0c;如推广困难、应用适配难度大&#xff0c;以及…

sublime Text中设置编码为GBK

要在sublime Text中设置编码为GBK&#xff0c;请按照以下步骤操作 1.打开Sublime Text编辑器, 2.点击菜单栏中的“Preferences”(首选项)选项&#xff0c;找打Package Control选项。 3.点击Package Control&#xff0c;随后搜索Install Package并点击&#xff0c;如下图 4.再…

KPRCB结构之ReadySummary和DispatcherReadyListHead

ReadySummary: Uint4B DispatcherReadyListHead : [32] _LIST_ENTRY 请参考 _KTHREAD *__fastcall KiSelectReadyThread(ULONG LowPriority, _KPRCB *Prcb)

Python爬虫:揭开淘宝商品描述的神秘面纱

在这个信息爆炸的时代&#xff0c;我们每天都在和时间赛跑。作为一名Python开发者&#xff0c;你是否曾梦想拥有超能力&#xff0c;能够瞬间揭开淘宝商品描述的神秘面纱&#xff1f;今天&#xff0c;就让我们一起化身为代码界的“福尔摩斯”&#xff0c;使用Python爬虫技术&…

HTML 多媒体标签详解:<img>、<object> 与 <embed>

文章目录 1. `<img>` 标签主要属性示例注意事项2. `<object>` 标签概述主要属性示例注意事项3. `<embed>` 标签概述主要属性示例注意事项小结在现代网页设计中,多媒体内容的使用变得越来越重要,因为它能够有效增强用户体验、吸引注意力并传达信息。HTML 提…

台式电脑如何改ip地址:全面解析与实操指南

有时候&#xff0c;由于IP地址冲突、网络安全、隐私保护或特定应用需求&#xff0c;我们可能需要更改台式电脑的IP地址。然而&#xff0c;对于不熟悉网络设置的用户来说&#xff0c;这一过程可能显得复杂而陌生。本文将通过全面解析与实操指南&#xff0c;帮助大家轻松掌握台式…

跟着红队笔记学习 tmux:渗透测试中的多终端利器

内容预览 ≧∀≦ゞ 跟着红队笔记学习 tmux&#xff1a;渗透测试中的多终端利器进入 tmux 前的准备tmux 概念简介tmux 基础操作会话管理命令会话管理快捷键会话内和会话外命令的区别 tmux 窗口和面板管理新建和管理窗口分割窗口为面板切换面板面板放大与恢复调整面板大小关闭面板…

【机器学习】24. 聚类-层次式 Hierarchical Clustering

1. 优势和缺点 优点&#xff1a; 无需提前指定集群的数量 通过对树状图进行不同层次的切割&#xff0c;可以得到所需数量的簇。树状图提供了一个有用的可视化-集群过程的可解释的描述树状图可能揭示一个有意义的分类 缺点&#xff1a; 计算复杂度较大, 限制了其在大规模数据…

移植 AWTK 到 纯血鸿蒙 (HarmonyOS NEXT) 系统 (2) - 移植 nanovg

AWTK 使用 nanovg 作为显示的后端&#xff0c;能否将 nanovg 成功移植到 HarmonyOS 上是一个关键问题&#xff0c;所以我们先尝试移植 nanovg&#xff0c;不过实际情况比预想的要简单&#xff0c;整个过程没有遇到任何意外的问题。 1. 将 AWTK 的代码取到 entry/src/main/cpp …

函数调用方法背后的原理

编译器实现函数调用时所遵循的一系列规则称为函数的“调用约定&#xff08;Calling Convention&#xff09;”&#xff0c;x86-64平台上的编译器随着操作系统的不同而有不同的约定。Windows上采用的是Wx64/Vector的标准,而类unix上采用systemV AMD64 ABI的调用标准。统一的调用…

Pinpoint(APM)进阶--插件开发

接上文 pinpoint支持编写插件来扩展监控的覆盖范围 这里重申下pinpoint一个trace的基本构成&#xff08;最小单元为span&#xff09; 插件结构 pinpoint插件由type-provider.yml 和实现组成 type-provider.yml 定义给插件使用的ServiceTypes和AnnotationKeys&#xff0c;并…

qt QPalette详解

1、概述 QPalette是Qt框架中用于管理颜色组和角色的一种机制。它允许开发者为应用程序中的不同组件&#xff08;如窗口、按钮、文本框等&#xff09;定义一套统一的颜色方案。QPalette通过定义颜色角色&#xff08;如背景色、前景色、选择色等&#xff09;和颜色组&#xff08…

什么是FUSE用户态文件系统

零. 文件系统 1. 为什么要有文件系统 文件系统是操作系统中管理文件和目录的一种机制。它提供了组织、存储、检索和更新文件的方法&#xff0c;主要如下&#xff1a; 数据组织&#xff1a;文件系统将数据组织成文件和目录&#xff0c;使用户能够更方便地管理和查找文件。每个…