数据交换协议:JDBC/ODBC、FTP/SFTP、Kafka、RESTful API、GraphQL

聊到数据交换,绕不开的就是协议。说白了,协议就是数据从一个系统跑到另一个系统时,大家约定好的「交通规则」。我做了这么多年数据架构,见过太多项目在协议选型上栽跟头——要么选错了工具,要么低估了场景复杂度。

今天咱们就把这五种主流协议掰开揉碎,看看它们各自擅长什么、不擅长什么。

JDBC/ODBC:数据库之间的直通车

JDBC(Java Database Connectivity)和 ODBC(Open Database Connectivity)是最传统的数据交换方式。它们的作用很简单:让应用程序直接连上数据库,执行 SQL,拿到结果。

适用场景:

  • 数据量不大(百万级以内)的批量查询
  • 需要实时读取数据库表的场景
  • ETL 工具(如 Kettle、Informatica)的底层连接

核心特点:JDBC 是 Java 生态的标准,ODBC 是 Windows 生态的标准。现在大部分数据库都支持 JDBC,ODBC 用得少了。

我记得有一次做银行报表系统,需要从 Oracle 拉取前一天的交易数据。当时团队直接用 JDBC 写了个定时任务,每天凌晨跑一次。数据量大概 200 万行,跑了半年都没出问题。但后来业务扩张,数据量涨到 2000 万行,JDBC 直连就开始卡了——查询超时、连接池爆满,搞得运维天天半夜被叫醒。

避坑指南:我曾经见过一个项目,用 JDBC 直连去拉每天上亿条日志数据。结果数据库直接被拖垮,生产环境挂了两个小时。JDBC/ODBC 不是万能的,数据量大了一定要加中间层。

FTP/SFTP:文件传输的老黄牛

FTP(File Transfer Protocol)和 SFTP(SSH File Transfer Protocol)是文件级别的数据交换协议。FTP 明文传输,SFTP 加密传输。现在生产环境基本只用 SFTP。

适用场景:

  • 批量文件交换(CSV、JSON、XML)
  • 跨组织、跨网络的数据传输
  • 非实时、定时调度的数据同步
特性 FTP SFTP
加密 无(明文) 有(SSH 加密)
端口 21(控制)/20(数据) 22
防火墙友好 差(需要动态端口) 好(单端口)
适用场景 内网、非敏感数据 外网、敏感数据

我个人习惯是:只要涉及跨网络传输,一律用 SFTP。别图省事用 FTP,万一数据被截获,背锅的是你。

举个例子,我之前做政府项目,需要和社保局交换参保数据。对方只支持 SFTP,每天凌晨三点推送一个压缩包过来。我们这边写个监听程序,文件一到就解压、校验、入库。这种模式稳定得很,跑了两年没出过岔子。

小技巧:SFTP 传输大文件时,建议先传 .tmp 后缀的临时文件,传完再重命名。这样能避免对方读到不完整的文件。

Kafka:流式数据的主动脉

Kafka 不是传统意义上的「协议」,它是一个分布式消息系统。但因为它定义了生产者-消费者之间的数据交换规范,所以咱们也把它归到协议里聊。

适用场景:

  • 高吞吐、低延迟的实时数据流
  • 日志采集、用户行为追踪
  • 微服务之间的异步解耦
  • 数据中台的实时数据管道

Kafka 的核心优势是「削峰填谷」。你想想看,双十一零点瞬间涌入几亿条订单数据,数据库根本扛不住。但用 Kafka 做缓冲,生产者只管往里面写,消费者按自己的节奏慢慢消费,系统就不会被冲垮。

关键概念:Topic(主题)、Partition(分区)、Consumer Group(消费组)。分区数是 Kafka 性能的关键,一般建议分区数不超过 Broker 数量的 10 倍。

我记得有个电商项目,需要实时同步订单数据到数据中台。最开始用 JDBC 直连,数据库压力太大。后来改成 Kafka,订单服务把数据发到 Topic,数据中台订阅消费,两边都轻松了。吞吐量从每秒几百条提升到几万条。

// 生产者示例(Java)
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

Producer<String, String> producer = new KafkaProducer<>(props);
producer.send(new ProducerRecord<>("order-topic", "order-12345", "{'orderId':12345,'amount':99.9}"));
producer.close();

避坑指南:我曾经遇到过 Kafka 消息丢失的问题。原因是生产者没有开启 acks=all,导致 Leader 挂了之后消息没同步到 Follower。生产环境一定要把 acks 设成 all,别为了那点性能牺牲可靠性。

RESTful API:系统间的通用语言

RESTful API 是基于 HTTP 协议的数据交换方式。它用 GET/POST/PUT/DELETE 对应 CRUD 操作,数据格式通常是 JSON 或 XML。

适用场景:

  • 系统间的实时接口调用
  • 微服务之间的同步通信
  • 对外提供数据服务(Open API)
  • 移动端和后端的数据交互

说白了,RESTful API 就是让两个系统像打电话一样,一问一答。你发个请求过去,对方立刻给你返回结果。这种模式简单直观,但缺点也很明显——如果对方响应慢,你就得一直等着。

方法 用途 幂等
GET 查询数据 是
POST 创建数据 否
PUT 全量更新 是
PATCH 部分更新 否
DELETE 删除数据 是

我个人习惯是:对外暴露的接口尽量用 RESTful,因为它的生态最成熟,各种语言都有现成的客户端。但内部系统之间,如果对性能要求高,我会考虑 gRPC 或者直接走消息队列。

小技巧:RESTful API 的响应一定要加分页、限流和超时控制。我曾经见过一个接口没做限流,被爬虫一刷直接打挂了,连带影响了十几个下游系统。

GraphQL:灵活查询的瑞士军刀

GraphQL 是 Facebook 推出的查询语言。它允许客户端精确指定需要哪些字段,服务端按需返回,不多不少。

适用场景:

  • 前端需要灵活组合数据的场景
  • 多端(Web、iOS、Android)共用一套接口
  • 数据模型复杂、关联关系多的系统

你想想看,传统 RESTful API 返回的数据结构是固定的。前端要三个字段,后端可能返回十个。用 GraphQL,前端可以这样写:

query {
  user(id: "12345") {
    name
    email
    orders {
      orderId
      amount
    }
  }
}

后端只返回 name、email 和 orders 里的 orderId、amount,其他字段一概不返回。这样网络传输量小,前端也省了解析的功夫。

核心优势:一次请求拿到所有需要的数据,避免 RESTful 的「N+1 查询问题」。比如你要查一个用户和他的所有订单,RESTful 需要先调 /user/12345,再调 /user/12345/orders,而 GraphQL 一次搞定。

我记得有个项目是做移动端资讯 App,内容模型特别复杂——文章、评论、作者、标签、分类,各种关联。用 RESTful 写接口,前端调了七八次才拼出完整页面。后来改成 GraphQL,一次查询全搞定,页面加载速度提升了 40%。

避坑指南:GraphQL 的查询复杂度很难控制。我曾经见过前端写了个嵌套十层的查询,直接把数据库查挂了。一定要做查询深度限制和耗时限制,别让客户端为所欲为。

协议选型对比

说了这么多,到底怎么选?我整理了一张对比表,方便你快速决策:

协议 实时性 数据量 复杂度 典型场景
JDBC/ODBC 高 小-中 低 数据库直连查询
FTP/SFTP 低 大 低 批量文件交换
Kafka 高 极大 中 实时数据流
RESTful API 高 小 低 系统间实时调用
GraphQL 高 小 中-高 灵活查询、多端共用

选型的时候,记住一个原则:没有最好的协议,只有最合适的场景。数据量大、实时性要求不高,用 SFTP;需要高吞吐实时流,用 Kafka;系统间简单调用,用 RESTful;前端需要灵活查询,用 GraphQL。

协议选型决策流程

下面这张图是我自己总结的选型流程,帮你快速定位该用哪种协议:

数据交换协议选型决策流程 开始选型 是否需要实时交换? 是 数据量大吗? 是 Kafka 否 需要灵活查询? 是 GraphQL 否 RESTful 否 文件批量交换? 是 SFTP 否 JDBC/ODBC 选型说明 1. 实时 + 数据量大 → Kafka(高吞吐流式处理) 2. 实时 + 数据量小 + 灵活查询 → GraphQL(前端按需取数) 3. 实时 + 数据量小 + 固定查询 → RESTful API(标准接口) 4. 非实时 + 文件批量 → SFTP(安全可靠) 5. 非实时 + 数据库直连 → JDBC/ODBC(简单直接) 6. 混合场景:Kafka + RESTful 组合使用,Kafka 做缓冲,RESTful 做查询 7. 跨组织交换:优先 SFTP 或 RESTful API,避免暴露数据库直连

嗯,这张图基本覆盖了日常工作中 90% 的选型场景。你只要顺着流程走一遍,基本不会选错。

最后说一句:协议选型不是一锤子买卖。系统在发展,数据量在增长,需求在变化。我建议你每半年复盘一次当前的协议选型,看看是否需要调整。别等到系统扛不住了才想起来改,那时候代价就大了。