为什么要使用Spring Cloud,而不是HTTP直接调用接口?
从底层技术上看,微服务之间互相调用,本质上就是发 HTTP 请求,拿到 JSON 结果,然后解析。
如果你只有 2 到 5 个微服务 ,且并发量不大,你完全可以直接用 HttpClient、RestTemplate 甚至 OkHttp 硬调,不需要 Spring Cloud。
但是,当你的系统真正成长为一个有几十上百个微服务、面临高并发和复杂业务场景 的庞大帝国时,如果还只用"原生 HTTP 调用",你就会发现代码根本写不下去,系统也随时处于崩溃边缘 。
Spring Cloud 的存在,不是为了替代 HTTP,而是为了解决"纯粹使用 HTTP 调用"时无法忍受的痛点(也就是微服务治理问题)。
我们来看看,如果不加框架,只用原生 HTTP,你会遇到什么灾难:
灾难 1:IP 地址硬编码(你要调谁?)
假设订单服务要调用户服务。
- 原生 HTTP: 你必须在代码里写死
http://192.168.1.100:8080/user/get。- 痛点: 用户服务为了扛住压力,部署了 5 台机器(.101, .102... .105)。你怎么调?自己写个随机算法轮询吗?如果 .100 这台机器挂了,你还要改代码重新发布订单服务吗?
- Spring Cloud (Nacos/Eureka): 你只需要写
userService.getUser()。框架会自动去"注册中心"查,用户服务现在活着的 5 台机器 IP 是多少,然后自动帮你挑一台调。
灾难 2:代码又臭又长(开发体验极差)
- 原生 HTTP: 每次调用,你要拼 URL、处理参数、写
try-catch捕获网络异常、用Jackson把 JSON 转成 Java 对象。如果调 50 个接口,你的业务代码里全是一堆底层的网络通信垃圾代码。 - Spring Cloud (OpenFeign): (划重点:OpenFeign 底层依然是 HTTP!) 但它让你像调本地方法一样写接口。只要加几个注解,拼接 URL、JSON 转换、异常处理,框架全替你干了,业务代码极其清爽。
灾难 3:雪崩效应(一个挂了,全盘崩溃)
- 原生 HTTP: 用户服务突然卡顿了,响应时间从 50ms 变成了 5 秒。此时来了 1000 个请求,订单服务的线程池瞬间被这 1000 个等待 HTTP 响应的线程占满。结果:用户服务只是慢,订单服务却被拖死了。 接着其他依赖订单服务的服务也死了,整个系统雪崩。
- Spring Cloud (Sentinel/Hystrix): 框架会监控你的 HTTP 调用。发现失败率过高或响应太慢,直接熔断 (快速返回失败,不再发请求)或者降级(返回一个默认的兜底数据),保护你的订单服务不被拖死。
灾难 4:前端/APP 怎么调用?(网关问题)
- 原生 HTTP: 你有订单服务(端口 8001)、用户服务(端口 8002)、商品服务(端口 8003)。前端难道要配置三个 IP 吗?跨域问题怎么解决?每个服务都要单独写一遍登录鉴权逻辑吗?
- Spring Cloud (Gateway): 提供一个统一的入口(端口 8080)。前端只访问 8080,网关根据 URL 自动把请求路由到后面的 8001/8002/8003,并且在网关层统一做鉴权、限流、日志记录。
灾难 5:改个配置要重启半个机房(配置管理)
- 原生 HTTP: 数据库密码要改,或者某个业务开关要调整,你需要去修改每个微服务的
application.yml,然后一台台重启。 - Spring Cloud (Nacos Config/Apollo): 配置统一放在配置中心,在网页上改一下,微服务不用重启,实时生效。
总结:打个比方
- 直接用 HTTP 调用: 就像你自己造了一辆发动机(HTTP),然后自己组装底盘,自己焊方向盘,每天自己开车去送货。 刚开始能跑,但你要送货越来越多时,你会累死。
- Spring Cloud: 它没有自己造发动机 (底层通信依然是 HTTP/REST,甚至你可以换成 RPC),但它给你提供了一辆自动化、带导航、带防撞气囊、带自动驾驶的物流卡车 。
所以,我们用 Spring Cloud,不是因为 HTTP 不能用,而是因为当服务数量多到一定程度时,我们需要一套标准的机制来管理这些 HTTP 调用(寻址、负载均衡、容错、路由)。Spring Cloud 就是这套机制的集大成者。