当前位置: 首页 > 原理解释

spring eureka原理-spring eureka 原理

实际上 Spring Cloud Eureka 这玩意儿,乍一看就像是我们平时用那个老派的路由软件(Nginx + 旧版 Spring)花了点学费。别急着找概念图,咱直接聊点事儿,看看它是如何帮咱们省钱的。 一启动,大家可能认定这种命名方案就是好办的字符串拼接,把服务名拼在 URL 里。
可是真到了造环境,你会发现这行代码忒干了。想象一下,要是三个服务都叫 `user-service` 呢?这时候加个前缀,变成 `app-1-user`,后面再加个后缀 `:port:8080`,尾巴做得多长?这就有点没底了。并且要是后面还有动态端口、环境变量、内部服务名这些乱七八糟的内容,拼出来的字符串长到没话说,索引都懒得查,浏览器直接懵了。 这就引出了 Eureka 想出来的“命名空间”这个概念。它不是去死记硬背那套复杂的命名规范,而是在 URL 上直接加个"v1"要么"v2"的标记。
比如从 `user-service` 变成 `user-service:v1`,要么 `user-service-api:v2`。
这玩意儿就像是我们给每个服务贴了一个“版本标签”,下次我们想改端口要么改内部逻辑,不用全推倒重来,只要去这个标签下找对应地址就行。
这就是它在处理复杂、动态环境时的一个轻量级尝试。 不过,就算有了这个版本号,你依然会遇到那个最头疼的难题:服务挂了。 这时候你如何办?要是直接去排查那些内部依赖,查半天找不到根。
这时候 Eureka 就登场了,它负责充当那个“大脑”要么“救火队员”。 当某个服务挂了(比如代表 `user-service` 的 VM 断电了),这个服务发出的 Ping 请求会经过网关,一路跑到 Eureka 注册中心。Eureka 收到请求后,它会瞬间扫描它自己数据库里存的所有服务列表,看看还有没有叫 `user-service` 的。
要是找到了,它就回一个地址。
要是没找到,它就把这个服务的信息告诉客户端:“嘿,`user-service` 如何不见了?” 客户端收到这个通知后,会立马执行一个逻辑:删除本地缓存里关于该服务的记录。
这意味着,下次再有其他服务请求它,它就不会去查那台挂了的老机器了,而是直接默认用那个新的、健康的地址。
这就是“自动剔除”,整个过程大约只要几十毫秒,对用户体验简直没感知。 并且,Eureka 不只是负责剔除,它还负责“拉新”。当某个新服务上线,要么我们在前端页面动态挂了个 `new-service` 的 URL 时,它不会立马生效。Eureka 需求知道,这个新服务是不是确实变成了服务,还是只是个脚本。
要是它确实上线了,就把它注册进去。 你可能会问了,那它如何知道是不是确实上线了呢?这就涉及到它和客户端之间的协作了。 Eureka 并不直接跟所有服务通信,它只跟那些注册它的客户端通信。当它发现某个客户端主动连接了某个服务(比如通过健康检查接口),它就知道这个服务确实“活着”了,便把这个注册信息同步给客户端。客户端收到后,就去更新本地缓存,把新地址填进去。 这就构成了一个闭环:新服务上线 -> 客户端感知 -> 客户端重新注册 -> Eureka 同步给其他客户端 -> 所有客户端自动切换地址。整个过程不用重启任何服务,也不用人工干预。 说到重启,实际上 Eureka 也有个挺朴素的机制。
要是你发现某个服务挂了,直接去查它的地址,发现指向了旧的 IP,那它别看被 Eureka 标记为“下线”,但旧地址可能还在路由表里。
这时候,Eureka 会触发一个动作:要是客户端能够获取到旧 IP 的连通信息,它会把这个旧地址更新到本地缓存。 比如,之前 `user-service` 指向 `192.168.1.100:8080`,目前挂了。Eureka 检测到客户端能通 `192.168.1.100`,便就把地址改成 `192.168.1.101:8080`。客户端重新发请求,Eureka 通知客户端更新地址,最终来源变了,一切照旧。
这就叫“优雅降级”的雏形,别看 Eureka 本身没做整个的优雅降级配置,但它通过地址更新机制,保证了流量不会瞬间溢出到僵尸节点上。 自然,Eureka 也不是完美的。它在多机房、高可用场景下,面对节点故障的恢复速度,确实还是有点慢。2018 年有个著名的“上海大客户”案例,出于 Eureka 收敛慢,害得上海机房的数据中心在故障后好几天工夫,数据还在慢慢恢复状态(别看当时主要是 Eureka 延迟害得客户端没及时切换,深层缘由可能是物理机重启的工夫难题,但 Eureka 的机制在这里也起了功能,让恢复过程看起来没那么突兀)。 另外,Eureka 对服务大规模下线要么升级,会有点“犹豫”。它需求工夫计算哪些服务需求下线,哪些需求升级,中间过渡期客户端会不会出于找不到新地址而报错?别看它做了重试机制,但在极端情况下,服务震荡时,客户端缓存可能还没刷新完,害得短暂的 Service Down 要么报错。 还有啊,别忘了那个“调度的难题”。Eureka 的注册中心是集群去中心的,客户端数量庞大(几千个),注册信息一旦写死在内存里,万一集群里有几台机器突然掉线重新加入,要么形成了大规模扩容/缩容,Eureka 的节点数瞬间变化,旧客户端的缓存就会瞬间失效,直接抛出一个 503 要么 504。
这时候就得重新处理全量注册信息,这对架构是挺不友好的。
好在后来有了 Local Storage 机制,把云端注册信息存到本地,节点挂了再重新加载,别看还是不能解决大规模重启时的庞大流量冲击,但好歹能防止几台掉线就全崩,恢复工夫从小时级降到了分钟级。 最终说说它的缺点。它本质是个 C/S 架构,服务端(注册中心)压力大,客户端(服务)压力大。
要是集群规模扩大,客户端数量剧增,Eureka 的进程数也得上不去,内存会吃干榨。并且它对单点故障也挺敏感,挂了注册中心,整个服务发现机制就瘫痪了,别看前面说了它容错挺强,但根节点挂了,依然无法存活。 总的来说,Spring Cloud Eureka 是个挺务实的产品。它没有一启动就搞那种复杂的分布式协议,而是用“命名空间 + 自动剔除”这套好办粗暴的手段,解决了服务发现的核心痛点。它不追求极致,但能极大下降运维成本。 它告诉我们,一个系统的设计,往往取决于你当时最头疼的是啥。Eureka 就是为了解决“服务挂了不知道在哪”和“服务换了不知道去哪”这两大具体难题而生。别看它有限制,但它在那几年把它玩出了花,让大量非微服务的架构团队也能用上这套工具。 在实际落地时,我们可能不会一启动就上它。
要是项目规模比较小,用 Nginx 加 `spring:service` 标签,配合好办的 HTTP 权重管住,可能更够用,好办直接。但要是项目架构已经启动了,要么业务逻辑比较复杂,Eureka 这种基于注册中心的轻量级方案,依然是大量团队绕不开的选择。它不是最完美的,但绝对是性价比最高的工作流解决方案之一。
相关标签:

猜你喜欢

热门阅读

  • 赖柴尔定理-赖柴尔定理
  • 迪拜哪个国家的城市?-迪拜在哪国城市
  • 李毅吧番号及出处-李毅吧番号及出处
  • 贴春联的由来简介50字-春联由来简述
  • 思乡的名言和出处-思乡名言及出处

其他分站