在微服务架构或分布式环境下,服务注册与发现技术不可或缺,这也是程序员进阶之路必需要掌握的核心技术之一,本文经过图解的方式带领你们轻轻松松掌握。程序员
引入服务注册与发现组件的缘由
先来看一个问题,假如如今咱们要作一个商城项目,做为架构师的你应该怎样设计系统的架构?你内心确定在想:这还不容易直接照搬淘宝的架构不就好了。但在现实的创业环境中一个项目多是九死一辈子,若是一开始投入巨大的人力和财力,一旦项目失败损失就很大。web
做为一位有经验的架构师须要结合公司财力、人力投入预算等现状选择最适合眼下的架构才是王道。大型网站都是从小型网站发展而来,架构也是同样。面试
任何一个大型网站的架构都不是从一开始就一层不变的,而是随着用户量和数据量的不断增长不断迭代演进的结果。算法
在架构不断迭代演进的过程当中咱们会遇到不少问题,技术发展的本质就是不断发现问题再解决问题,解决问题又发现问题。数据库
单体架构
在系统创建之初可能不会有特别多的用户,将全部的业务打成一个应用包放在tomcat容器中运行,与数据库共用一台服务器,这种架构通常称之为单体架构。tomcat

单体架构-应用和数据库共同部署服务器
在初期这种架构的效率很是高,根据用户的反馈能够快速迭代上线。可是随着用户量增长,一台服务的内存和CPU吃紧,很容易形成瓶颈,新的问题来了怎么解决呢?微信
应用与数据分离
随着用户请求量增长,一台服务器的内存和CPU持续飙升,用户请求响应时间变慢。这时候能够考虑将应用与数据库拆开,各自使用一台服务器,你看问题又解决了吧。restful

单体架构-应用和数据库分离架构
忽然有一天扫地阿姨不当心碰了电线,其中一台服务器掉电了,用户全部的请求都报错,随之而来的是一系列投诉电话。
集群部署
单实例很容易形成单点问题,好比遇到服务器故障或者服务能力瓶颈,那怎么办?聪明的你确定想到了,用集群呀。

应用集群部署
集群部署是指将应用部署在多个服务器或者虚机上,用户经过服务均衡随机访问其中的一个实例,从而使多个实例的流量均衡,若是一个实例出现故障能够将其下线,其余实例不受影响仍然能够对外提供服务。
随着用户数量快速增长,老板决定增长投入扩大团队规模。开发团队壮大后效率并无获得显著的提升,之前小团队能够一周迭代上线一次,如今至少须要两到三周时间。
业务逻辑愈来愈复杂,代码间耦合很严重,修改一行代码可能引入几个线上问题。架构师意识到须要进行架构重构。
微服务架构
当单体架构演进到必定阶段后开发测试的复杂性都会成本增长,团队规模的扩大也会使得各自工做耦合性更严重,牵一发而动全身就是这种场景。
单体架构遇到瓶颈了,微服务架构就横空出世了。微服务就是将以前的单体服务按照业务维度进行拆分,拆分粒度可大可小,拆分时机能够分节奏进行。最佳实践是先将一些独立的功能从单体中剥离出来抽成一个或多个微服务,这样能够保障业务的连续性和稳定性。

微服务架构
如上图将一个商用应用拆分为六个独立微服务。六个微服务可使用Docker容器化进行多实例部署。
架构演化到这里遇到了一个难题,若是要查询用户全部的订单,用户服务可能会依赖订单服务,用户服务如何与订单服务交互呢?订单服务有多个实例该访问哪个?
一般有几种解决办法:
(1)服务地址硬编码
服务的地址写死在数据库或者配置文件,经过访问DNS域名进行寻址路由。

服务元数据硬编码
服务B的地址硬编码在数据库或者配置文件中,服务A首先须要拿到服务B的地址,而后经过DNS服务器解析获取其中一实例的真实地址,最后能够向服务B发起请求。
若是遇到大促活动须要对服务实例扩容,大促完须要对服务实例进行下线,运维人员要作大量的手工操做,很是容易误操做。
(2)服务动态注册与发现
服务地址硬编码还有一个很是致命的问题,若是一台实例挂了,运维人员可能不能及时感知到,致使一部分用户的请求会异常。
引入服务注册与发现组件能够很好解决上面遇到的问题,避免过多的人工操做。
架构演进总结
在单体架构中一个应用程序就是一个服务包,包内的模块经过函数方法相互调用,模型足够简单,根本没有服务注册和发现一说。
在微服务架构中会将一个应用程序拆分为多个微服务,微服务会部署在不一样的服务器、不一样的容器、甚至多数据中心,微服务间要相互调用,服务注册和发现成为了一个不可或缺的组件。
服务注册与发现基本原理
服务注册与发现是分为注册和发现两个关键的步骤。
服务注册:服务进程在注册中心注册本身的元数据信息。一般包括主机和端口号,有时还有身份验证信息,协议,版本号,以及运行环境的信息。
服务发现:客户端服务进程向注册中心发起查询,来获取服务的信息。服务发现的一个重要做用就是提供给客户端一个可用的服务列表。
服务注册
服务注册有两种形式:客户端注册和代理注册。
客户端注册
客户端注册是服务本身要负责注册与注销的工做。当服务启动后注册线程向注册中心注册,当服务下线时注销本身。

客户端注册
这种方式的缺点是注册注销逻辑与服务的业务逻辑耦合在一块儿,若是服务使用不一样语言开发,那须要适配多套服务注册逻辑。
代理注册
代理注册由一个单独的代理服务负责注册与注销。当服务提供者启动后以某种方式通知代理服务,而后代理服务负责向注册中心发起注册工做。

代理注册
这种方式的缺点是多引用了一个代理服务,而且代理服务要保持高可用状态。
服务发现
服务发现也分为客户端发现和代理发现。
客户端发现
客户端发现是指客户端负责向注册中心查询可用服务地址,获取到全部的可用实例地址列表后客户端根据负载均衡算法选择一个实例发起请求调用。

客户端发现
这种方式很是直接,客户端能够控制负载均衡算法。可是缺点也很明显,获取实例地址、负载均衡等逻辑与服务的业务逻辑耦合在一块儿,若是服务发现或者负载平衡有变化,那么全部的服务都要修改从新上线。
代理发现
代理发现是指新增一个路由服务负责服务发现获取可用的实例列表,服务消费者若是须要调用服务A的一个实例能够直接将请求发往路由服务,路由服务根据配置好的负载均衡算法从可用的实例列表中选择一个实例将请求转发过去便可,若是发现实例不可用,路由服务还能够自行重试,服务消费者彻底不用感知。

代理路由服务注册
心跳机制
若是服务有多个实例,其中一个实例出现宕机,注册中心是能够实时感知到,而且将该实例信息从列表中移出,也称为摘机。
如何实现摘机?业界比较经常使用的方式是经过心跳检测的方式实现,心跳检测有主动和被动两种方式。
被动检测是指服务主动向注册中心发送心跳消息,时间间隔可自定义,好比配置5秒发送一次,注册中心若是在三个周期内好比说15秒内没有收到实例的心跳消息,就会将该实例从列表中移除。

心跳机制-被动检测
上图中服务A的实例2已经宕机不能主动给注册中心发送心跳消息,15秒以后注册就会将实例2移除掉。
主动检测是注册中心主动发起,每隔几秒中会给全部列表中的服务实例发送心跳检测消息,若是多个周期内未发送成功或未收到回复就会主动移除该实例。

心跳机制-主动检测
业界经常使用的服务注册与发现组件对比
了解服务注册与发现的基本原理后,若是你要在项目中使用服务注册与发现组件,当面对众多的开源组件该如何进行技术选型?
在互联网公司里,有研发实力的大公司通常会选择自研或者基于开源组件进行二次开发,可是对于中小型公司来讲直接选用一款开源软件会是一个不错的选择。
经常使用的注册与发现组件有eureka,zookeeper,consul,etcd等,因为eureka在2018年已经宣布放弃维护,这里就再也不推荐使用了。

业界开源组件
下面结合各个维度对比一下各组件。
组件 | 优势 | 缺点 | 接口类型 | 一致性算法 |
---|---|---|---|---|
zookeeper | 1.功能强大,不只仅只是服务发现; 2.提供watcher机制能够实时获取服务提供者的状态; 3.普遍使用,dubbo等微服务框架已支持; |
1.没有健康检查; 2.须要在服务中引入sdk,集成复杂度高; 3.不支持多数据中心; |
sdk | Paxos |
consul | 1.开箱即用,方便集成; 2.带健康检查; 3.支持多数据中心; 4.提供web管理界面; |
不能实时获取服务变换通知 | restful/dns | Raft |
etcd | 1.开箱即用,方便集成; 2.可配置性强 |
1.没有健康检查; 2.需配合三方工具完成服务发现功能; 3.不支持多数据中心; |
restful | Raft |
从总体上看consul的功能更加完备和均衡。接下来以consul为例详细介绍一下。
Consul——值得推荐的服务注册与发现开源组件
简单认识一下Consul
Consul是HashiCorp公司推出的开源工,使用Go语言开发,具备开箱便可部署方便的特色。Consul是分布式的、高可用的、 可横向扩展的用于实现分布式系统的服务发现与配置。
Consul有哪些优点?
-
服务注册发现:Consul提供了经过DNS或者restful接口的方式来注册服务和发现服务。服务可根据实际状况自行选择。
-
健康检查:Consul的Client能够提供任意数量的健康检查,既能够与给定的服务相关联,也能够与本地节点相关联。
-
多数据中心:Consul支持多数据中心,这意味着用户不须要担忧Consul自身的高可用性问题以及多数据中心带来的扩展接入等问题。
Consul的架构图

Consul架构
Consul 实现多数据中心依赖于gossip protocol协议。这样作的目的:
-
不须要使用服务器的地址来配置客户端;服务发现是自动完成的。
-
健康检查故障的工做不是放在服务器上,而是分布式的。
Consul的使用场景
Consul的应用场景包括服务注册发现、服务隔离、服务配置等。
服务注册发现场景中consul做为注册中心,服务地址被注册到consul中之后,可使用consul提供的dns、http接口查询,consul支持health check。
服务隔离场景中consul支持以服务为单位设置访问策略,能同时支持经典的平台和新兴的平台,支持tls证书分发,service-to-service加密。
服务配置场景中consul提供key-value数据存储功能,而且能将变更迅速地通知出去,借助Consul能够实现配置共享,须要读取配置的服务能够从Consul中读取到准确的配置信息。
- END -
絮叨:天气愈来愈冷,你们能够可添加个人我的微信号:smileCoder1024,拉你进技术交流群,一块儿抱团取暖吧~
热门推荐(点击可阅读):
做者简介:
博主从华中科技大学硕士毕业,是一个对技术有追求,对生活有激情的程序员。几年间浪迹于多个一线互联网大厂,具备多年开发实战经验,若是你热爱技术或者你也不知足现状喜欢搞事情,那你不妨关注我,让咱们一路同行,一块儿分享技术干货、交流面试技巧,吐槽职场故事。我有技术和故事,你来吗?
大家点个“在看”雷架会兴奋一夜睡不着~
架构师必定要懂啊~
本文分享自微信公众号 - 爱笑的架构师(DancingOnYourCode)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。