1. HTTP 外部接口调用 (基础版)
这通常指使用 HttpClient、OkHttp 或 Spring 的 RestTemplate 显式地调用一个 URL。
-
底层协议: 标准的 HTTP/1.1 (通常)。数据序列化多为 JSON 字符串。
-
通信特点: 文本传输,头部信息(Header)重,建立连接开销较大。
-
核心痛点: * 硬编码: 你需要手动拼接 URL(如
http://192.168.1.100:8080/user/get)。-
无自动发现: 如果服务 IP 变了,你得改配置。
-
无负载均衡: 需要自己写逻辑或靠外部 Nginx。
-
-
适用场景: 跨公司、跨语言的接口对接(如调用支付宝支付接口、天气预报接口)。
-
案例:
javaimport java.io.*; import java.net.HttpURLConnection; import java.net.URL; public class HttpClientPostExample { // POST 请求(发送 JSON) public static String doPost(String urlStr, String jsonBody) throws Exception { URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置请求方法 conn.setRequestMethod("POST"); // 设置超时 conn.setConnectTimeout(5000); conn.setReadTimeout(5000); // 设置请求头 conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("Accept", "application/json"); // 允许输出 conn.setDoOutput(true); // 写入请求体 try (OutputStream os = conn.getOutputStream()) { byte[] input = jsonBody.getBytes("UTF-8"); os.write(input, 0, input.length); } int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED) { BufferedReader reader = new BufferedReader( new InputStreamReader(conn.getInputStream(), "UTF-8") ); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); return response.toString(); } else { throw new RuntimeException("HTTP请求失败,响应码:" + responseCode); } } public static void main(String[] args) throws Exception { // 示例 JSON 数据 String json = "{\"title\":\"foo\",\"body\":\"bar\",\"userId\":1}"; String result = doPost("https://jsonplaceholder.typicode.com/posts", json); System.out.println(result); } }关键点说明:
-
HttpURLConnection:JDK 原生,无需额外依赖,但功能相对基础 -
Apache HttpClient:功能更完善,支持连接池、重试、认证等高级特性
-
超时设置:避免网络问题导致程序卡死
-
编码处理:使用 UTF-8 避免中文乱码
-
资源释放:正确关闭流和连接
2. Dubbo + Zookeeper (高性能 RPC 版)
Dubbo 是一个典型的 RPC (Remote Procedure Call) 框架,它的设计目标是让分布式调用像调用本地方法一样简单且高效。
-
底层协议: 默认使用 Dubbo 协议 (基于 TCP 的长连接)。数据序列化使用 Hessian2(二进制)。
-
通信特点: 二进制传输,没有冗余的 HTTP 头,性能极高。支持双向通信。
-
注册中心 (Zookeeper): 充当"通讯录"。服务提供者上线时把地址写进去,消费者订阅并缓存这些地址。
-
调用体验: * 面向接口: 消费者只需要引入服务方的
InterfaceJAR 包,直接@DubboReference即可。- 高性能: 适合内部高并发、低延迟的业务。
-
适用场景: 对性能要求极高的系统、纯 Java 开发的大规模微服务集群。
-
案例:
java// Dubbo 方式:需要指定版本号,调用逻辑相对透明,但背后配置复杂 @DubboReference(version = "1.0.0") private GreetingService greetingService;
3. Spring Cloud 微服务调用 (全家桶版)
Spring Cloud 并不是单一框架,而是一套微服务解决方案。它内部的调用(如 OpenFeign)本质上是 RESTful HTTP 的"高级封装"。
-
底层协议: 依然是 HTTP (JSON)。
-
组件搭配: * 注册中心: Nacos / Eureka / Consul(代替了 Zookeeper 的生态位)。
- 调用组件: OpenFeign 。它让你写一个接口并打上
@FeignClient注解,底层自动转换成 HTTP 请求。
- 调用组件: OpenFeign 。它让你写一个接口并打上
-
通信特点: 相比 Dubbo 性能略逊(因为 HTTP 头部开销和 JSON 解析),但通用性极强,对防火墙友好,调试方便(直接用浏览器或 Postman 就能测)。
-
生态优势: 提供了配置中心 (Config)、网关 (Gateway)、熔断 (Sentinel/Resilience4j) 等全套组件,集成度极高。
-
适用场景: 追求开发效率、生态完整、或存在跨语言需求(如 Java 调 Python)的微服务系统。
-
案例:
java// Spring Cloud (OpenFeign) 方式:声明式调用,就像调用本地接口一样 @FeignClient(name = "greeting-service") public interface GreetingClient { @GetMapping("/say/{name}") String sayHello(@PathVariable("name") String name); }
三者核心差异对比表
| 特性 | HTTP 外部接口 | Dubbo + Zookeeper | Spring Cloud (OpenFeign) |
|---|---|---|---|
| 通信协议 | HTTP (应用层) | Dubbo/TCP (传输层) | HTTP (应用层) |
| 序列化方式 | JSON / XML (文本) | Hessian2 / ProtoBuf (二进制) | JSON (文本) |
| 性能 | 较低 | 极高 (低延迟/高吞吐) | 中等 |
| 耦合度 | 极低 | 较高 (需共享接口 JAR) | 中等 (面向 REST 接口) |
| 服务发现 | 静态配置 / Nginx | 动态发现 (Zookeeper) | 动态发现 (Nacos/Eureka) |
| 负载均衡 | 外部均衡 (Nginx) | 客户端负载均衡 | 客户端负载均衡 (LoadBalancer) |
| 开发体验 | 手写 URL,较繁琐 | 像本地方法调用一样流畅 | 声明式接口调用,很方便 |
总结建议
-
如果你是调别人的接口 :选 HTTP,因为你无法控制对方的技术栈。
-
如果你追求极致性能 :选 Dubbo,TCP+二进制序列化能让你的服务器榨干每一分性能。
-
如果你想要开发快、功能全 :选 Spring Cloud,它的全家桶能帮你快速搞定限流、网关和监控,且社区极其活跃。