问题:数据库
咱们如今有多少个服务?缓存
服务愈来愈多时,服务 URL 配置管理变得很是乱服务器
服务对外的地址变了,其余全部有使用到的服务都要改地址网络
增长服务,增长服务实例等,都要作运维工做session
客户端经过服务端的负载或路由访问目标服务。架构
服务端负责负载和转发请求,自身或者经过第三方工具,自动发现新的服务实例,并定时检测心跳维护注册表。负载均衡
优势:
服务发现功能对于客户端而言是透明的
缺点:
增长了一次转发,集中式的作法没有去中心化运维
提问:
1.nignx/F5有服务地址列表,也有负载均衡功能,属于服务端发现吗?
主要缺了“发现”功能,服务实例动态增减并不能主动识别微服务
2.服务实例本身往服务端发送注册请求不能够吗?
服务实例是服务提供者,也多是服务消费者;若是往注册中心发送注册请求,那么也能够从注册中心拉注册表,这样直接作客户端发现不是更好?工具
客户端自身就能够肯定服务提供者的可用实例地址列表和使用负载均衡策略。
服务提供者向注册中心发送注册和心跳。
服务端只负责维护注册表,并对外提供服务。
优势:
客户端能够灵活、智能地制定负载均衡策略
去中心化
缺点:
客户端与注册中心耦合,须要实现与注册中心交互的代码
服务提供者:
向注册中心发送请求,发送信息
服务消费者:
向注册中心发送请求,获取信息
注册中心:
提供接口给服务发现客户端调用
维护服务实例信息集合
集群之间信息同步
服务提供者:向注册中心发送请求,发送信息
1.发送请求问题:
发送请求的工具用什么,okhttp、resttemplate?
请求失败怎么办,要重试吗?重试的策略是什么?
2.注册中心地址问题:
发送信息给全部注册中心仍是发送一个成功就好了?
注册中心有多个的话,优先访问哪一个呢,访问失败的要记录起来下次不访问了吗?
地址写在配置里,若是有增长或调整,全部客户端都要改?
3.发送注册/心跳问题:
注册和心跳调同一个接口仍是分开两个接口比较好?
注册后,除了要定时发送心跳,实例信息有改变的状况下,要发给注册中心吗?
做为一个中间件如何提升可扩展性?
eureka的答案是装饰器模式
JerseyClient:
执行rest请求的工具,eureka有RestTemplate的替换实现方案
统计信息:
根据请求类型进行统计,请求时间总计、请求失败次数总计等
重定向:
返回的http code是302则表示要重定向(注册中心迁移?)更换重定向的url再次发起请求,最多重定向10次
失败重试机制:
已经请求失败的server url记录下来下次再也不请求;
若是失败的url过多(好比所有都失败的状况,多是客户端网络有问题),超过阀值,则清空失败的url记录,把他们从新当成可用的url ,这里要获取注册中心地址列表,用于重试
会话:
请求失败的url记录多久,永久记录吗?使用session机制若是20分钟没请求过,则重置上面的全部机制
session有效时长20分钟左右(有随机增减)
1.发送信息给全部注册中心仍是一个?
不论是AP仍是CP,服务提供者只需与一个注册中心交互成功就行,服务提供者不关心注册中心之间的数据同步
2.客户端如何保证发送到任意一个注册中心成功呢?
配置多个注册中心地址,失败了就换下一个再试
3.注册中心地址变动问题
配置了多个注册中心地址后,若是注册地址有增删改怎么解决
将注册中心地址放到配置中心 或 DNS txt记录,客户端定时去刷新获取
(就算是存在本地配置文件,eureka也会开启定时任务定时去取)
注册后,除了要定时发送心跳,实例信息有改变的状况下,要发给注册中心吗?
eureka的答案是须要:
1.实例状态变动
2.配置信息变动
LeaseExpirationDurationInSeconds 心跳有效期
LeaseRenewalIntervalInSeconds 心跳频率
3.健康检查处理器的增减(用于获取实例状态)
服务消费者:向注册中心发送请求,获取注册表信息
1.发送请求问题(同服务提供者)
2.注册中心地址变动问题(同服务提供者)
3.全量仍是增量获取应用实例信息
若是消费者本地实例信息为空,则全量获取,不然增量获取,关键逻辑在注册中心,这里较简单
将上面结论进行汇总
注册中心:
提供接口给服务发现客户端调用
维护服务实例信息集合
集群之间数据同步
如何作增量更新?
查询是否须要缓存?
如何作增量更新?
eureka的答案是维护一个队列 recentlyChangedQueue
细心的观众会发现,为何接收到心跳,不会增长到recentlyChangedQueue?
队列里存的是引用类型,和应用实例列表是同一个地址,接收到心跳进行实例更新,定时维护最近变更实例队列时查到实例信息变更,而后继续将其保留在队列里,这样增量查询下次同样能查到该实例的信息
为何要自我保护?
若是失效的实例过多,有没有多是注册中心出了问题?
上一分钟接收到心跳总数<= 实例总数*2(默认30s一次心跳) * RenewalPercentThreshold()(默认0.85)进入自我保护则不会剔除任何实例
如何作集群同步?
eureka的答案仍是维护队列,这里注册、心跳、下线都会入队,批量进行同步,失败的加到失败重试队列
接收到的全部请求,都要同步吗?
要通过过滤, 每种类型只取最新一条去同步便可
注册中心地址变动
同服务发现客户端同样,定时刷新注册中心地址,而后更新集群节点
(右键新标签打开可查看大图)
区域(Region):
从设计而言,每一个 Amazon EC2 区域都与其余 Amazon EC2 区域彻底隔离。这可实现最大程度的容错能力和稳定性。在区域之间传输数据须要收费。
可用区(Availability Zone ,AZ):
若是您的实例分布在多个可用区且其中的某个实例发生故障,则您可对您的应用程序进行相应设计,以使另外一可用区中的实例可代为处理相关请求。可用区由区域代码后跟一个字母标识符表示;例如,us-east-1a。
地域(Region):
不一样地域的云服务器 ECS、关系型数据库 RDS、对象存储服务 OSS 内网不互通。
不一样地域之间的云服务器 ECS 不能跨地域部署负载均衡,即在不一样的地域购买的 ECS 实例不支持跨地域部署在同一负载均衡实例下。
可用区(Zone):
可用区是指在同一地域内,电力和网络互相独立的物理区域。同一可用区内实例之间的网络延时更小。
理解region和az的概念后,咱们须要作什么是否是就简单多了?
1.服务发现客户端,优先与相同的AZ进行通信
2.服务发现客户端,查询注册中心地址列表时,只取相同region下全部AZ的注册中心地址
2.注册中心,也只须要将数据同步给相同region的全部AZ便可
不过属于哪一个区,好像没有特殊的配置吧?
eureka.client.availability-zones.us-east-1=zone2,zone1
eureka中取上面配置的第一个可用区为优先使用的可用区
注:虽然region之间是数据隔离的,可是eureka也支持从其余region同步信息(经过http请求)
连连看,将以下类图与咱们架构图里对象进行对应(右键新标签打开可查看大图)
eureka server 是ap仍是cp?
服务启动后会不会立刻注册到注册中心?
服务提供者注册到注册中心后,服务消费者最快多久可以查询到该提供者?
为何接收心跳后不入队,那么更新心跳后启不是增量查询查不到了?
集群同步的队列,为何要通过一道中转才进行消费?
部分图片摘自以下文章: