当前位置: 首页 > news >正文

有了TCP为什么还需要HTTP?再用RPC?这次彻底讲明白了

掘金原文(个人技术文章优先在掘金发布):https://juejin.cn/post/7559981310472470562
记得刚工作那会儿,第一次接触RPC概念时,我内心满是疑惑——明明HTTP用得好好的,为什么要搞出个RPC?直到参与了几个微服务项目后,我才真正能理解它们各自的价值。今天,就让我们一起理清这些协议之间的关系。

从网络基础说起:TCP的能力与局限

刚开始接触网络编程时,我觉得TCP已经足够完美——它能够建立稳定的连接、保证数据可靠传输、处理网络拥塞,这似乎就是网络通信的全部需求。

但在实际开发中,我遇到了一个基础却关键的问题:

// 发送方连续发送两条独立消息
socket.write("Hello");
socket.write("World");// 接收方可能一次收到:"HelloWorld"
// 完全无法区分原始的消息边界

这一现象常被称作TCP粘包问题,但这其实是一种误解。其本质是TCP作为字节流协议的无边界特性:TCP只负责可靠地传输字节序列,却不关心这些字节应该如何被组织成有意义的业务消息。

TCP的三个核心特性:

  • 面向连接:通信前需要通过三次握手建立连接
  • 可靠传输:通过确认、重传、排序等机制保证数据可靠送达
  • 基于字节流:数据没有自然边界,只是连续的字节序列(二进制)

个人理解: TCP就像是一个可靠的物流系统,保证把所有的货物(字节)都按顺序送达,但它会把所有货物都装进一条连续的传送带(字节流)——货物确实都到了,但接收方需要自己根据包裹上的信息(应用层协议)来重新拆分和识别每个独立的包裹。

所谓“粘包”,其实是一个伪命题。TCP传输的是字节流,而非消息包。如何在流中界定消息,是应用层协议需要解决的问题。

HTTP协议的出现:为数据赋予意义

面对TCP的局限性,应用层协议应运而生。HTTP协议通过在TCP之上定义明确的报文格式,解决了消息边界和语义表达的问题。

HTTP通过标准的报文结构定义消息边界:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 48{"name": "Alice", "email": "alice@example.com"}

关键就在于Content-Length: 48这个头部——它明确告诉接收方消息体的确切长度,从而解决了TCP的粘包问题。

HTTP协议的主要价值:

  • 定义消息边界:通过Content-Length或chunked编码标识消息范围
  • 标准化通信语义:GET、POST、PUT、DELETE等标准方法
  • 丰富的能力扩展:缓存控制、内容协商、状态管理
  • 通用兼容性:被所有主流平台和语言支持

结论: TCP解决了"可靠传输"的问题,而HTTP等应用层协议解决了"传输什么"和"如何解析"的问题。

新的困惑:为什么要在HTTP之上再引入RPC?

随着分布式系统的发展,大家都能发现基于HTTP的服务间调用会存在一些不便:

// 基于HTTP的服务调用需要大量样板代码
HttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost("http://user-service/getUser");
post.setHeader("Content-Type", "application/json");String jsonBody = "{\"user_id\": 123}";
post.setEntity(new StringEntity(jsonBody));HttpResponse response = client.execute(post);
if (response.getStatusLine().getStatusCode() == 200) {String responseBody = EntityUtils.toString(response.getEntity());User user = objectMapper.readValue(responseBody, User.class);
}
// 太多的底层细节需要处理!

每次调用都需要处理HTTP状态码、异常情况、序列化反序列化等重复工作。这让我们开始思考:能否让远程服务调用像调用本地方法一样简单?

RPC的核心理念:透明化的远程调用

RPC(Remote Procedure Call),又叫做远程过程调用,其目标就是让远程服务调用对开发者透明。

// 理想的RPC调用方式
User user = userService.getUser(123);// 而不是处理各种网络通信细节

重要概念澄清(基于个人理解):
RPC本身不是具体的协议,而是一种调用范式技术思想。它的核心目标是让程序员能够像调用本地方法那样调用远程服务。

但是我们不能说“使用RPC协议”,因为RPC本身不是协议。

正确的表述方式:

  • ✅ "我们使用gRPC协议进行RPC调用"
  • ❌ "我们使用RPC协议"

因为RPC本身不是协议,而gRPC、Thrift、Dubbo等才是具体的协议实现。

RPC与HTTP的关系:不同维度的技术

RPC与HTTP的关系这是最容易产生混淆的地方。通过学习和实践,我个人理解为:

RPC和HTTP根本不在同一个技术层级:

  • RPC是一种调用范式,对标的是本地方法调用
  • HTTP是一种具体的应用层协议
  • RPC可以通过HTTP实现,也可以通过自定义的TCP或UDP协议实现

比如gRPC选择基于HTTP/2协议实现,而很多早期的RPC框架使用自定义的TCP二进制协议。

RPC协议与RPC框架的完整生态

RPC协议:通信的基础规范

协议主要定义三个核心方面:

  1. 消息格式:定义消息如何开始、结束,头部和体部的结构
  2. 序列化方式:规定数据如何编码和解码
  3. 传输规则:确定通信流程和交互模式

RPC框架:基于协议的完整解决方案

现代RPC框架在基础协议之上提供了企业级的能力:

  • 核心层:实现通信协议本身
  • 组件层:提供序列化、服务发现、负载均衡等基础组件
  • 治理层:包含容错、监控、注册中心等运维能力
  • 应用层:让开发者透明地进行远程方法调用

总结: 协议定义了机器之间如何对话,框架让开发者无需关心对话过程而专注业务逻辑。

现代架构中的技术选型:各司其职的分工

通过参与实际项目,我逐渐理解了HTTP和RPC在现代架构中的分工原则。针对大部分公司而言,基本上都是如此。

内部服务调用:RPC框架的优势领域

微服务架构内部,RPC框架因其性能优势成为首选:

RPC的高性能主要源于:

  1. 高效的序列化

    // JSON序列化:可读性好但体积大
    {"id": 123, "name": "Alice", "age": 30}  // 约40字节// Protobuf二进制:体积小,解析快
    \x08\x7B\x12\x05Alice\x18\x1E  // 仅11字节
    // 体积减少70%以上,序列化速度提升明显
    
  2. 协议开销优化

    • 长连接减少TCP握手开销
    • 多路复用提升连接利用率
    • 头部压缩减少传输数据量
  3. 专为性能设计

    • 精简的协议头设计
    • 二进制编码效率
    • 零拷贝等技术应用

对外API暴露:HTTP协议的不可替代性

当需要向外部提供API时,HTTP协议展现出其独特价值:

HTTP的通用性优势:

  • 无与伦比的生态系统:所有平台、语言、设备都支持HTTP
  • 成熟的工具链:浏览器、Postman、curl等调试工具
  • 网络友好性:80/443端口普遍开放
  • 易于测试调试:直接通过浏览器或命令行工具测试
// 前端调用HTTP API简单直接
fetch('/api/users/123').then(response => response.json()).then(user => {displayUser(user);});

真实世界的架构实践

现代互联网公司的典型架构体现了清晰的分层设计:

image

这种架构的智慧:

  • 内外有别:对外保证兼容性,对内追求性能
  • 关注点分离:网关处理横切关注点,业务服务专注核心逻辑
  • 协议转换:在网关层完成HTTP到RPC的协议转换

总结与核心观点

针对文章内容,整体总结一下:

技术演进脉络:

  1. TCP层:解决网络层的可靠传输问题
  2. HTTP层:解决应用层的消息格式和语义问题
  3. RPC层:优化分布式系统的服务调用体验

现代架构的最佳实践:

  • 公司内部服务调用:优先采用RPC框架(如gRPC、Dubbo)

    • 核心原因:极致性能。二进制编码、协议开销低、长连接复用
  • 对外暴露接口:普遍采用HTTP协议(及RESTful风格)

    • 核心原因:无与伦比的通用性。生态系统成熟,客户端兼容性好

核心结论:
这是一个"内外有别"的最佳实践——性能至上的内部集群采用RPC框架,兼容性优先的对外开放接口采用HTTP协议。

本文内容是作者在学习过程中的个人理解和总结,可能存在不准确或理解有误的地方,欢迎倔友们指正。

当然我也已经练习长达两年半了😄,理论上🤌应该没问题。
image

http://www.jsqmd.com/news/49819/

相关文章:

  • 11.24午夜盘思
  • Java调用第三方接口的方法
  • 2025留学代写危机应对指南:5家靠谱机构助你重返校园
  • 2025美国大学停学应对全攻略:5大靠谱机构助你重返学术轨道
  • 2025美国紧急转学机构推荐深度解析:靠谱机构认准这些核心优势,危机中重启留学之路​
  • 第35天(中等题 数据结构)
  • 2025美国留学求职机构实力解析:你的职场Offer引路人在哪?
  • Universal Fit 3-Button Metal Flip Remote Key (5pcs/lot) – KEYDIY KD NB29-3 for Euro/American Cars
  • 2025美国科研中介TOP5解析:从课题对接至成果落地全程护航
  • 根据缺少的文件查找deb包
  • 第一个Vue2程序
  • 2025美国留学生求职中介TOP5:厚仁教育领衔,精准匹配名企资源
  • CF1097F Alex and a TV Show
  • Git 最速上手
  • Ubuntu 24.04 安装 libncurses.so.5
  • Universal 3-Button Flip Remote Key for VW - 5pcs/Lot (VW Compatible, Mechanic Owner Friendly)
  • 48
  • 生成对抗网络训练优化技术解析
  • 基于相控微波光子滤波器的旋转诱导相位差解调
  • 2025.11.24博客
  • KEYDIY KD NB33-3 3-Button Universal Flip Remote Key for VW (5pcs/lot)
  • 警钟长鸣 - -Graphic
  • 博客园你好
  • 2025.11.24总结
  • 第一天—C++语法基础
  • Linuxの磁盘管理
  • 实验三:类和对象_基础编程2
  • 2025年度最新橱柜定制厂家推荐榜单与选择指南:一份基于行业专业数据的权威分析报告,整木/实木/原木等材质橱柜十大主流供应商解析,全屋定制优质选择
  • Day1-20251124
  • AI元人文:思维跃迁自述