分布式系统搭建:服务发现揭秘

CAP理论

加州大学终身教授与著名计算机科学家Eric Allen Brewer90年代末提出了CAP理论,理论断言任一个基于网络的分布式系统,最多只能满足“数据一致性”、“可用性”、“分区容错性”三要素中的两个要素。

该理论后被MIT证明可行,故架构师无需将精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍。

 

CAP理论也即被捧为“分布式系统设计”的重要评分标准,其包含下述三项定义:

 

  • Consistency(一致性):集群中所有节点在同一时刻可见同样的值。

  • Availability(可用性):健康的节点在限时内,可返回可靠的结果。

  • Partition tolerance(分区容错性):集群中某些节点失联后,集群仍可继续服务。

 

那为什么一个系统只能同时满足三要素中的两个要素呢?我们来看看下面例子:

 

1.首先使分布式系统满足“分区容错性”要素:

当上海、台北服务器共用数据存储时,上海数据中心存储的宕机将造成台北服务器也不可用,拓扑图如下。


 

如何来满足分区容错性:我们可在各数据中心分别建存储机制,在各数据中心存储进行写操作的同时,触发存储同步,保障数据中心间存储数据同步。

故当任一数据中心存储宕机,也不会造成其它数据中心的存储读写操作,如下图所示:


 

2.满足“分区容错性”的前提下,“一致性”,“可用性”两者只可选其一假定当前两地存储中的数据为“版本1”,此时上海与台北数据中心网络中断,存储间无法同步。然后上海服务器将数据版本更新为“版本2”,由于同步受阻,台北数据中心仍保存数据版本“版本1”,如下图所示:

 


“台北服务器向台北分区存储进行查询”这一动作在CAP理论模型下只能满足下述情况之一

 

CP)保障“一致性”,放弃“可用性”

等待网络恢复正常,上海存储将“版本2”同步至台北存储,台北存储将满足“一致性”的数据“版本2”返回给服务器。

由于网络恢复时间的不确定性,请求可能会超时,违反“可用性”限时的条件。

AP)保障“可用性”,放弃“一致性”

台北存储在“可用性”高响应的驱动下将过期数据“版本1”返回给服务器。

由于返回的“版本1”与最新数据“版本2”不一致,违反了“一致性”。

 

CAP理论小结:

无论CPAP还是CA,在CAP理论驱动下的系统,都以SLAService Level Agreement)为系统最终评估基准。目前SLA 59乃至69的系统,都会以AP设计为重,略微放弃一致性来换取系统的“活”。

 

目前主流的分布式系统设计理论BASEBasically Available 基本可用)(Soft State 软状态)(Eventual Consistency 最终一致性)则是对CAPAP理论的扩展,通过实现“最终一致性”来保障SLA的同时确保信息准确。

基于BASE理论设计的主要的产品则为主流NoSQL数据库:包括CassandraMongoDBRedis, CouchDB等。

 

故在AP模型稳定的情况下,SLA指标中能有几个9,与Consistency(一致性)的算法实现密切相关,下面我们来看一下“一致性算法”


一致性算法Raft

20世纪80年代开始,一致性算法的研究就没有停止过,主流的实现则依赖共享内存(Shared memory)和消息传递(Messages passing)。直至21世纪的今天,基于“消息传递”为一致性算法实现的系统占到了绝大多数。

 

微软研究院首席科学家、2013年图林奖获得者LeslieLamport1990年提出的一种基于消息传递且具有高度容错特性的一致性算法Paxos该算法的典型应用场景为分布式数据库:在一个多节点的分布式系统中,“使用一致性算法”保证每个节点执行相同的命令序列,确保每个节点的状态一致。

 

Google的分布式锁服务ChubbyApache的分布式服务框架ZooKeeper都是基于Paxos算法进行的实现。Paxos也是类似算法中最为可靠与广知的,但Paxos算法的流程复杂与实现困难导致世界级产品数量极少。

 

2013年来自Stanford大学的DiegoOngaroJohn Ousterhout发布论文“In Search of an Understandable Consensus Algorithm”,公布了的新的分布式协议研究称为Raft,它是一个为真实世界应用建立的协议,主要注重协议的落地性和可理解性。

 

时至今日,Raft的易实现性使其成为与Paxos同级别的一致性算法,在RaftGithub官网上,已发布了十多种Raft一致性算法的实现,生态圈日渐强大。详细信息可见:https://raft.github.io/

主流的服务发现框架EtcdConsul等都是基于Raft一致性算法实现的。Google开源的容器集群管理Kubernetes作为Docker生态圈中重要一员,也是基于Raft来管理一致性的。

 

Raft算法拆解后主要包含三大功能,各功能运作的完整流程也可参考Raft可视化网站,让我们通过生动的图形来了解Raft算法的秘密吧!

网址:

http://thesecretlivesofdata.com/raft/

 

1.       Leader选取

Raft服务集群中有3个角色LeaderCandidateFollowerLeader则会统一管理Follower与自己的状态机同步。

 

Raft使用心跳机制来触发选举Leader。在没有Leader的情况下在Follower默认的“选举计时器”(150毫秒到300毫秒超时)超时后,将会推举自己为Candidate,当大多数(n/2+1 )节点同意后将会升级为Leader。然后LeaderFollower间使用心跳进行状态维护,只要心跳是在“心跳计时器”超时范围内,Leader状态则可永久保持。

 

Raft算法内,只会存在一个Leader与多个Follower,集群维护单个数服务器。

 

*在极端多Follower“选举计时器”同时超时,多Candidate同时出现的情况下,则以收到其他Follower推举回应同时重置“选举计时器”的时间点来决定最终Leader

 

Leader选举的流程如下,图来自Stanford论文:


 

2.       日志复制、同步:

Leader角色负责日志同步,流程如下:

Leader收到客户端信息,则先写入本地日志文件,同时将信息发给其他Follower。当大多数Follower保存至本地成功,则回复Leader成功,Leader获取大多数Follower回复后,提交本地写入的日志,并则通知客户端收到信息。

 

Follower有丢包或者奔溃,Leader将进行重试来保障一致性。所以数据的最终提交、状态机的维护将由Leader决定。Leader会保障多数节点写入信息来进行最终提交。

 

如下图所示,Leader上最后写入的x<-4未被提交,则是由于仅有Leader1/4Follower,共2/5的节点写入此日志。而x<-5则有Leader1/2Follower,共3/5 (n/2+1)节点写入此日志,Leader发现大多数节点3/5已写入信息成功,做了最终提交。

 


 

3.       安全性:

Leader作为Raft集群的控制核心,也存在奔溃的可能。此时则集群中任意Follower可推举自己为CandidateRaft的安全性保障当Follower如没有获得当前完整Committed entries(见上图)时,则无法成为Candidate。此安全性举动保障了数据的可靠性,不会丢数据。

 

如要保障新选举的Leader不会将过期脏数据同步至Follower。安全性检查会在做数据的提交时,也检查当前Leader所要提交的数据至少有一个存储在大部分Follower上。

 

当新Leader在工作的同时,老Leader突然恢复工作。Raft的安全性保障使用Term号的方式使老Leader发出的过期Term号对所有Follower都不生效。保障了老Leader不会触发错误同步,直至降级为Follower

 

Raft一致性算法小结:

Raft通过算法实现强一致性。但是其单一Leader节点的设计在写操作量大的情况下会造成单点写瓶颈。故使用场景为读操作大于写操作的,对一致性要求高的系统。

 

服务发现框架Consul介绍

ConsulHashicorp公司使用Go语言编写的开源项目,其核心是基于RaftCAP一致性算法)与GossipBASE最终一致性算法)进行实现的。基于RaftGossipConsul集群,可保障Consul Server集群(服务端)间的数据一致性同步,Consul Server集群与集群间、Consul Agent(客户端)与Agent间的数据最终一致性同步。

 

*Gossip最终一致性算法尝试解决的问题是:在一个有界网络中,每个节点都随机地与其他节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致。Gossip具有“去中心化的特点”,也天然具有分布式容错,虽然无法保证在某个时刻所有节点状态一致,但可以保证在最终所有节点一致。

 

Consul的特色非常适合融入当前互联网公司的微服务架构,可轻松覆盖多种操作系统。官方已经发布的Consul客户端支持Mac OS XFreeBSDLinuxSolarisWindows等多种操作系统,发布在这些操作系统上的Restful API都可轻松接入Consul集群。

 

Consul产品开源的同时也提供了多种语言的接入SDK,包括GoPythonPhpScalaJavaErLangRubyNode.js.NETPerl等,大大降低了开发人员的接入工时。

 

下图为Consul在多数据中心部署的架构图,单数据中心内使用Raft算法保障服务端一致性,同时使用Gossip协议进行跨数据中心(WAN Gossip)同步,与客户端间(LAN Gossip)同步。

两种一致性算法结合使用的Consul集群可保证各个节点的数据一致。


 

.NET API服务如何接入Consul服务发现框架

首先将Consul以服务端模式部署在至少3台(总台数为单数)服务器上,然后在.NET API部署服务器上安装Consul Agent模式

由于.NET API多运行于Windows服务器上,可使用nssm.exehttp://www.nssm.cc/)来进行从命令行至windows服务的包装,保障跨Windows会话的安全性。

 

服务端启动脚本,需使用-ui-dir来指定UI项目路径

Consul  agent -server -bootstrap-expect 2 -data-dir  D:\TGOP\ServiceDiscovery\ConsulData -node=TGOP-Consul-Server1 -bind=172.16.11.211  -dc=Shanghai-DC1 -client=172.16.11.211 -ui-dir=./UI

 

Agent端启动脚本仅需加入指定Consul服务端集群

Consul  agent -data-dir D:\TGOP\ServiceDiscovery\ConsulData  -node=TGOP-Consul-Agent-LucasPC -bind=127.0.0.1 -dc=Shanghai-DC1 -client=127.0.0.1  -join tgop-apistore.vipabc.com

 

Consul服务端与Agent端启动后,可通过http://consulserver:8500/ui 地址进行Consul集群健康状态管理。


 

.NET API服务发布与发现的SDK接入方法:

 

通过Nuget包管理器还原并安装Consul.NET SDK安装包,当前版本为7.0.5。使用SDK安装包中提供的ConsulClient.Agent.ServiceRegister方法进行“服务注册”,可使用的默认Agent地址为http://127.0.0.1:8500/ 核心方法如下

Task<WriteResult>  ServiceRegister(AgentServiceRegistration service, CancellationToken

 ct = null);

 

使用ConsulClient.Agent. ServiceDeregister方法进行“服务注销”

Task<WriteResult> ServiceDeregister(string serviceID, CancellationToken ct = null);

 

使用ConsulClient.Health.Service方法进行“服务发现”,将会返回符合要求的服务列表,后通过主流负载均衡算法进行最终服务筛选,完成服务发现流程。

Task<QueryResult<ServiceEntry[]>> Service(string  service, string tag, bool passingOnly, CancellationToken ct = null);

 

.NET API启动与退出时集成Consul.NET SDK相应的注册与注销方法,完成服务自注册。在.NET API需要与其他API进行通讯时,使用服务发现方法完成地址查询,后发起Restful HTTP请求完成API调用。

进行服务注册时,需通过AgentServiceRegistration.AgentServiceCheck类型将心跳HTTP的接口信息,心跳间隔信息等同时递交注册,ConsulAgent将会以配置好的间隔对服务进行心跳检查,来保障任意Agent进行“服务发现”时,获取的注册API为可用的。

 

Consul服务发现框架集成小结:

Consul集群基础设施部署完毕,相应SDK语言包成熟的基础上,用户开发的Restful API可轻松接入集群。Consul的核心架构于一致性算法的基石上,各服务节点的信息可靠性、可用性得到高保障,服务与服务之间可无障碍进行沟通,形成微服务网。

 

参考文献:

https://en.wikipedia.org/wiki/Eric_Brewer_(scientist)

https://en.wikipedia.org/wiki/CAP_theorem

http://www.julianbrowne.com/article/viewer/brewers-cap-theorem

https://en.wikipedia.org/wiki/Raft_(computer_science)

https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf

https://en.wikipedia.org/wiki/Paxos_(computer_science)

https://en.wikipedia.org/wiki/Gossip

https://raft.github.io/

http://thesecretlivesofdata.com/raft/

https://www.consul.io/docs/internals/architecture.html

https://www.nuget.org/packages/Consul

相关文章: 

  • Consul入门

  • 使用C# 和Consul进行分布式系统协调

  • Consul 服务注册与服务发现

  • 搭建consul 集群

原文地址:http://www.rcgus.com/gyys377188451/2352438.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

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

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

相关文章

SSL / TLS 协议运行机制详解

转载自 SSL / TLS 协议运行机制详解 互联网的通信安全&#xff0c;建立在SSL/TLS协议之上。 本文简要介绍SSL/TLS协议的运行机制。文章的重点是设计思想和运行过程&#xff0c;不涉及具体的实现细节。如果想了解这方面的内容&#xff0c;请参阅RFC文档。 一、作用 不使用SS…

在ASP.NET Core Web API上使用Swagger提供API文档

我在开发自己的博客系统&#xff08;http://daxnet.me&#xff09;时&#xff0c;给自己的RESTful服务增加了基于Swagger的API文档功能。当设置IISExpress的默认启动路由到Swagger的API文档页面后&#xff0c;在IISExpress启动Web API站点后&#xff0c;会自动重定向到API文档页…

一文告诉你 Java RMI 和 RPC 的区别

转载自 一文告诉你 Java RMI 和 RPC 的区别 RPC 远程过程调用 RPC&#xff08;Remote Procedure Call Protocol&#xff09;远程过程调用协议&#xff0c;通过网络从远程计算机上请求调用某种服务。一次RPC调用的过程大概有10步&#xff1a; 1.执行客户端调用语句&#xff…

Java架构师必须知道的 6 大设计原则

转载自 Java架构师必须知道的 6 大设计原则 在软件开发中&#xff0c;前人对软件系统的设计和开发总结了一些原则和模式&#xff0c; 不管用什么语言做开发&#xff0c;都将对我们系统设计和开发提供指导意义。本文主要将总结这些常见的原则&#xff0c;和具体阐述意义。 开发…

Flux --gt; Redux --gt; Redux React 入门 基础实例教程

本文的目的很简单&#xff0c;介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6、会一些React、有看过Redux相关的文章&#xff0c;这篇入门小文应该能帮助你理一下相关的知识 一般来说&#xff0c;推荐使用 ES6ReactWebpack 的开发模式&#xff0c;但Webpa…

mybatisplus 强制制空 空覆盖原来的字符串

ApiModelProperty(value "证件照片url") TableField(value "id_photo_url",fill FieldFill.UPDATE) private String idPhotoUrl; 方法一 Data EqualsAndHashCode(callSuper false) Accessors(chain true) TableName("base_party_member") A…

微软开源Visual Studio测试平台VSTest

IT之家1月21日消息 微软在MSDN博客上宣布&#xff0c;开源旗下Visual Studio测试平台VSTest。这一平台是具备高扩展性的单元测试执行框架&#xff0c;能够在不同的核心之间实现并行化&#xff0c;提供进程隔离&#xff0c;并能够整合进Visual Studio。 目前&#xff0c;VSTest能…

线程的状态与调度

当我们使用new关键字新建一个线程&#xff0c;这个时候线程就进入了新建状态&#xff08;New&#xff09;&#xff0c;也就是图中未启动状态&#xff1b;调用start方法启动线程&#xff0c;这个时候就进入了可运行状态&#xff0c;也就是就绪状态&#xff08;Runnable&#xff…

深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题

转载自 深入JVM系列&#xff08;三&#xff09;之类加载、类加载器、双亲委派机制与常见问题 一&#xff0e;概述 定义&#xff1a;虚拟机把描述类的数据从Class文件加载到内存&#xff0c;并对数据进行校验、转换解析和初始化&#xff0c;最终形成可以被虚拟机直接使用的java…

Fabio 安装和简单使用

Fabio&#xff08;Go 语言&#xff09;&#xff1a;https://github.com/eBay/fabio Fabio 是一个快速、现代、zero-conf 负载均衡 HTTP(S) 路由器&#xff0c;用于部署 Consul 管理的微服务。 Fabio 由 eBay Classifieds Group 开发&#xff0c;用于处理 marktplaats.nl 和 kij…

计算密集型分布式内存存储和运算平台架构

1. 相关概念 1.1 内存数据库 关系型数据库处理永久、稳定的数据&#xff0c;内存数据库就是将其数据放在内存中&#xff0c;活动事务只与内存数据打交道&#xff0c;重新设计了体系结构并且在数据缓存、快速算法、并行操作方面也进行了相应的改进&#xff0c;所以数据处理速度比…

【深入Java虚拟机】之四:类加载机制

转载自 【深入Java虚拟机】之四&#xff1a;类加载机制 类加载过程 类从被加载到虚拟机内存中开始&#xff0c;到卸载出内存为止&#xff0c;它的整个生命周期包括&#xff1a;加载、验证、准备、解析、初始化、使用和卸载七个阶段。它们开始的顺序如下图所示&#xff1a; 其中…

违反ClassLoader双亲委派机制三部曲第二部——Tomcat类加载机制

转载自 违反ClassLoader双亲委派机制三部曲第二部——Tomcat类加载机制 前言&#xff1a; 本文是基于 ClassLoader双亲委派机制源码分析 了解过正统JDK类加载机制及其实现原理的基础上&#xff0c;进而分析这种思想如何应用到Tomcat这个web容器中&#xff0c;从源码的角度对 违…

红包的技术升级之旅

鸡年春节&#xff0c;红包再次成为年味儿最重要的催化剂。先是腾讯QQ钱包推出“LBSAR天降红包”等三种创新有趣的玩法&#xff0c;支付宝上线AR实景红包&#xff0c;微博亦推出视频红包等形式。虽然微信退出红包营销让人稍有意外&#xff0c;但用户对红包的热情仍未消减。 事实…

java中生成1000~10000之间的随机数

要生成在[min,max]之间的随机整数&#xff0c;可使用Random类进行相关运算&#xff1a; Random random new Random(); int s random.nextInt(max)%(max-min1) min; random.nextInt(max)表示生成[0,max]之间的随机数&#xff0c;然后对(max-min1)取模。 以生成[1000,10000]…

C# 7.0新功能

下面是对C#7.0 版本所有语言功能的描述。随着 Visual Studio “15” preview 4 的发布&#xff0c;大部分功能可以被更灵活的应用。现在正是时候将这些功能介绍给大家&#xff0c;你也可以借此让我们知道你的想法。 C#7.0 增加了很多新的功能&#xff0c;更专注于数据的消费&am…

MybatisPlus学习(四)条件构造器Wrapper方法详解

https://www.cnblogs.com/xianz666/p/13857733.html MybatisPlus学习&#xff08;四&#xff09;条件构造器Wrapper方法详解 文章目录 1、条件构造器2、QueryWrapper 2.1、eq、ne2.2、gt、ge、lt、le2.3、between、notBetween2.4、like、notLike、likeLeft、likeRight2.4、isN…

使用ueditor实现多图片上传案例

UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器&#xff0c;具有轻量、可定制、用户体验优秀等特点。开源基于BSD协议&#xff0c;所有源代码在协议允许范围内可自由修改和使用。百度UEditor的推出&#xff0c;可以帮助不少网站开发者在开发富文本编辑器所遇…

自定义ClassLoader和双亲委派机制

转载自 自定义ClassLoader和双亲委派机制 ClassLoader ClassLoad&#xff1a;类加载器&#xff08;class loader&#xff09;用来加载 Java 类到 Java 虚拟机中。Java 源程序&#xff08;.java 文件&#xff09;在经过 Java 编译器编译之后就被转换成 Java 字节代码&#xff0…

ASP.NET Core 1.0 开发记录

ASP.NET Core 1.0 更新比较快&#xff08;可能后面更新就不大了&#xff09;&#xff0c;阅读注意时间节点&#xff0c;这篇博文主要记录用 ASP.NET Core 1.0 开发简单应用项目的一些记录&#xff0c;以备查阅。 ASP.NET Core 1.0 相关 Nuget 程序包源&#xff1a;https://api.…