TransportClient详细说一说

好的,我们来详细说一说 Elasticsearch 的 ​**TransportClient**。

核心定位:历史功臣,现已退休

TransportClient 是 ​Elasticsearch 官方提供的、早期的 Java 客户端 ,用于连接到 Elasticsearch 集群并执行操作(索引、搜索、管理数据等)。它曾经是 Java 应用集成 Elasticsearch 的推荐 方式,​但在 Elasticsearch 5.x 版本后被标记为废弃,并在 7.0 版本中完全移除

为什么需要了解它?​

  • 维护旧代码库:​ 如果你在维护运行在 ES 5.x 或更早版本上的应用代码,你肯定会遇到它。
  • 理解历史文档/教程:​ 网上有很多基于它的旧资料。
  • 了解演进过程:​ 理解为什么它被替代有助于理解现代客户端的设计哲学。

TransportClient 的核心特性和工作方式

  1. 基于传输层(Transport Layer):​

    • 它不使用 HTTP/REST API。
    • 它直接与 Elasticsearch 集群中的节点建立二进制 TCP 连接
    • 通信协议是Elasticsearch原生的传输协议 (基于 Netty 实现),而不是 HTTP。这通常在相同的硬件和网络条件下可以提供比 HTTP 更高的性能和更低的延迟(尤其是在大量操作时),因为协议更紧凑,开销更小。
  2. 节点发现与连接管理:​

    • 初始连接:​ 你需要提供一个或多个种子节点 的地址(通常是集群中几个节点的主机名/IP 和端口,默认是 9300)。端口 9300 是节点间内部通信的默认传输端口。
    • 集群感知:​ TransportClient 启动后会连接到这些种子节点。
    • 获取集群状态:​ 通过这些种子节点,它可以获取集群完整的拓扑信息(包括所有数据节点、主节点等的地址)。
    • 维护连接池:​ 它会对已知的数据节点维护一个连接池,以便后续请求使用。
    • 动态感知:​ 集群发生变化时(节点加入/离开),TransportClient 能感知到(虽然有时会有短暂的延迟)并调整其连接池。
  3. 请求分发 (Load Balancing/Failover):​

    • 当你的应用代码通过 TransportClient 发出请求(例如 client.prepareIndex(...).execute()client.prepareSearch(...).execute())时,客户端会负责:
      • 根据请求的类型(写操作通常路由到主分片所在节点,读操作可以路由到任意拥有分片副本的节点)和配置的负载均衡策略(如 round-robin、基于 ping 响应时间的策略等)。
      • 从连接池中选择一个合适的节点发送请求。
      • 如果请求失败,它会自动尝试发送到另一个合适的节点(Failover)​
      • 对应用代码屏蔽集群内部节点通信的复杂性。开发者无需手动选择将请求发送给哪个节点。
  4. 异步与非阻塞:​

    • 执行方法通常返回一个 ActionFuture(支持 .actionGet() 同步等待结果)。
    • 更现代的方式是通过添加 ActionListener 参数来提供回调函数,实现完全的异步非阻塞调用。
  5. 序列化:​

    • 使用高效的二进制序列化(如 Thrift, MessagePack),而不是 JSON over HTTP。这减少了数据大小和解析开销。
  6. 模块化与扩展:​

    • 你可以添加插件(如 x-pack 的安全模块)来扩展其功能(如认证、加密)。
    • 支持配置连接池大小、超时、SSL/TLS、嗅探器行为等。

一个简单的工作流程示例(索引文档)​

复制代码
// 1. 创建客户端实例 (旧方式)
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node1.mydomain.com"), 9300)) // 种子节点 1
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node2.mydomain.com"), 9300)); // 种子节点 2

// 2. 准备索引请求
IndexResponse response = client.prepareIndex("my_index", "_doc", "1") // 索引名,类型名(6.x后基本弃用),文档ID
        .setSource(jsonBuilder()
                .startObject()
                .field("user", "kimchy")
                .field("message", "trying out Elasticsearch")
                .endObject()
        )
        .get(); // .get() 是同步等待响应,也可以使用 .execute() + Listener 异步

// 3. 处理响应(检查状态等)
if (response.status() == RestStatus.CREATED) {
    // ...
}

// 4. 关闭客户端
client.close();

为什么它被废弃和移除?(关键原因)​

  1. 版本绑定紧密 (Biggest Issue):​

    • TransportClient 必须与目标 Elasticsearch 集群的主版本号严格匹配 (例如,5.6 的客户端只能连 5.x 集群,不能连 6.x 或 7.x)。这给集群升级带来了巨大的痛苦,要求应用及其依赖的客户端库必须同时升级。
    • 服务器端协议的任何微小改动都可能破坏客户端的兼容性。维护 ES 团队需要为每个版本的服务器维护对应的各个语言的客户端。
  2. 双重维护负担:​

    • Elasticsearch 团队需要维护两套暴露给用户的 API:传输层协议和 HTTP/REST API。移除 TransportClient 允许他们将精力集中在改进和维护更通用的、跨语言的 HTTP/REST API 上
  3. HTTP/REST API 的成熟与优化:​

    • 随着 HTTP/2 的普及、更好的序列化技术和网络栈优化(Elasticsearch 现在使用 Netty for HTTP too),HTTP 协议的性能差距已经显著缩小,很多场景下可以接受或差异不大
    • HTTP 协议具有无与伦比的通用性和可调试性curl, Kibana Console, 浏览器插件),开发者友好,跨语言支持完美。
  4. 安全性:​

    • HTTP 协议上配置 TLS 加密和认证(Basic Auth, PKI, Token)是标准、成熟的做法。
    • 原生传输协议上的安全配置(X-Pack Security)不如 HTTP 标准化和广泛支持。
  5. 部署灵活性:​

    • 在云/Kubernetes 环境中,将集群暴露给外部应用通常通过 HTTP LB/Ingress 进行。让应用通过传输协议直接连接后端节点,绕过这些负载均衡器,会引入部署和维护的复杂性,并可能破坏 LB 的健康检查等功能。
    • HTTP API 可以轻松地放在负载均衡器之后。
  6. 集群内部的强耦合:​

    • TransportClient 需要知道集群内部节点的地址。在某些网络配置下(如 VPC peering, different security groups)可能会增加配置难度。

TransportClient 的现代替代品

官方推荐并积极维护的替代客户端是:

  1. Java High Level REST Client:​ (在 ES 7.15 及更早版本是主流推荐)
    • 通过 HTTP (端口 9200) 与集群交互。
    • 接受并返回领域对象(Request/Response objects)。
    • 支持异步 (async() + ActionListener 回调)。
    • 屏蔽了 HTTP 连接的细节(像 TransportClient 屏蔽传输连接一样)。
    • 版本要求更宽松:​ 客户端版本可以连接到等于或低于其版本的 ES 集群(例如,7.15 的客户端可以连 7.x 的所有版本)。升级更平滑。
  2. Java API Client (New, preferred in 8.x+):​ (从 ES 7.15 开始提供,8.x 后更成熟)
    • 同样基于 HTTP。
    • 使用强类型、面向对象的方法 来构建请求和解析响应(IndexRequest.withJson() 取代了很多字符串拼接)。
    • 更好地利用了 Java 的语言特性(泛型、流式 API),提供了更好的类型安全和 IDE 支持。
    • 进一步抽象和简化了接口。
    • 使用 JSON 编组库(Jackson)进行高效的(反)序列化。
    • 同样遵循主版本号一致规则(8.x客户端连8.x集群),但内部机制通过HTTP,版本管理和维护成本显著低于旧的TransportClient。

总结

TransportClient 是一个时代的产品,它通过高效的二进制协议和集群感知能力为早期Java应用接入Elasticsearch提供了强大的解决方案。然而,其与ES服务器版本的紧密绑定、维护负担、以及HTTP/REST API技术栈的成熟,最终导致了它被废弃并移除。现代应用开发应避免使用TransportClient ,转而使用基于HTTP/REST API的Java High Level REST Client ​ (兼容旧项目) 或更新的、面向对象的 ​Java API Client​ (推荐用于新项目)。它们提供了几乎相同的易用性(甚至更优的API设计)、良好的性能、更高的安全性、跨语言兼容性和更平滑的升级路径。

相关推荐
SelectDB21 小时前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode2 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220703 天前
如何搭建本地yum源(上)
运维
大树886 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠6 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质6 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工6 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智6 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_6 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉6 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造