java-design-patterns 中的 Ambassador 模式:为遗留远程服务构建客户端侧代理
示例工程教程【免费下载链接】java-design-patternsDesign patterns implemented in Java项目地址https://gitcode.com/GitHub_Trending/ja/java-design-patterns点击查看免费下载Ambassador大使模式的核心思想是在客户端旁边部署一个辅助服务实例由它代为执行远程共享资源的通用连接功能。本文以 java-design-patterns 仓库中的ambassador模块为主线通过完整的 Java 源码示例讲解该模式如何为难以修改的遗留远程服务注入限流、延迟检测、日志与重试能力读完即可理解其角色划分、关键实现与适用场景并可直接对照仓库源码动手运行验证。模式目标PropósitoAmbassador 模式为客户端提供一个辅助服务实例并将访问共享远程资源时常见的横切功能委托给该实例处理。翻译自微软官方架构文档的定义指出Ambassador 服务可以看作是与客户端共存于同一进程外的代理out-of-process proxy它适合用来承接客户端侧的通用连接任务——如监控、日志、路由、安全例如 TLS与弹性resilience处理并且这些能力的实现与语言无关。该模式经常与遗留应用或其他难以修改的应用搭配使用用以扩展其网络能力同时也能让专门的团队独立落地这些特性。在 java-design-patterns 的 ambassador 模块 中模块的入口类 App.java 的注释对这一意图做了同样的概括大使服务为另一个远程服务提供接口同时额外承载监控、日志、路由、安全等被“卸载”下来的通用连接任务这对代码库难以改造的遗留应用尤其有价值。动机一个真实的遗留服务场景文档给出了一个非常贴近实际的例子一个远程服务拥有大量客户端访问其提供的某项功能。该服务是遗留应用已经无法升级。大量用户请求正在引发连接问题。需要在客户端侧实现新的请求频率限制规则同时加入延迟latency检测与日志记录。这正是 Ambassador 模式的典型发力点远程服务本身不可修改所有增强能力只能在客户端侧完成。如果把这些逻辑直接塞进每个客户端会造成大量重复代码并侵入业务逻辑而 Ambassador 模式把这些共性能力收敛到一个专门的辅助对象中让客户端代码保持干净。核心角色与协作关系从仓库源码可以归纳出该模式在本项目中的四个参与角色对应包com.iluwatar.ambassador下的类角色类/接口职责共享接口RemoteServiceInterface.java声明long doRemoteFunction(int value)由远程服务与大使服务共同实现保证客户端面向接口编程远程服务RemoteService.java以单例Singleton形式模拟遗留远程应用执行真正的业务计算并模拟随机耗时与偶发失败大使服务ServiceAmbassador.java实现同一接口在调用远程服务前附加延迟检测、日志与带退避的重试客户端Client.java只与本地大使服务交互不直接接触远程服务类图见 ambassador/etc/ambassador.urm.pngPlantUML 源文件位于 ambassador/etc/ambassador.urm.puml可以清晰看到RemoteService与ServiceAmbassador都实现RemoteServiceInterface而Client仅持有ServiceAmbassador引用。代码示例完整实现1. 共享接口远程服务与大使服务都实现同一个接口这是模式的关键——对客户端而言大使服务就是远程服务的“本地替身”interface RemoteServiceInterface { long doRemoteFunction(int value) throws Exception; }2. 远程服务遗留应用模拟远程服务以单例形式存在源码中由static synchronized getRemoteService()保证唯一实例每次调用会随机睡眠 0~999ms并根据延迟是否超过阈值THRESHOLD源码中为 200ms决定返回value * 10还是失败值-1Slf4j public class RemoteService implements RemoteServiceInterface { private static RemoteService service null; static synchronized RemoteService getRemoteService() { if (service null) { service new RemoteService(); } return service; } private RemoteService() {} Override public long doRemoteFunction(int value) { long waitTime (long) Math.floor(Math.random() * 1000); try { sleep(waitTime); } catch (InterruptedException e) { LOGGER.error(Thread sleep interrupted, e); } return waitTime 200 ? value * 10 : -1; } }需要说明的是当前仓库源码 RemoteService.java 在示例基础上做了两处演进——随机数生成被抽象为 RandomProvider.java 接口便于测试注入固定值成功/失败的魔法数字-1被提炼为 RemoteServiceStatus.java 枚举常量FAILURE(-1)。此外源码将成功条件统一为waitTime THRESHOLD与文档示例中waitTime 200的写法在语义上互为镜像实际效果一致延迟不超过 200ms 即成功。注释中明确说明这种随机耗时与偶发-1是为了模拟客户端必须应对的连接问题。3. 大使服务核心增强逻辑ServiceAmbassador是模式的灵魂它实现了延迟检测与带退避的重试防止在远程服务出现连接问题时继续施压。两个关键常量是RETRIES 3最多重试次数与DELAY_MS 3000重试前等待 3 秒Slf4j public class ServiceAmbassador implements RemoteServiceInterface { private static final int RETRIES 3; private static final int DELAY_MS 3000; ServiceAmbassador() { } Override public long doRemoteFunction(int value) { return safeCall(value); } private long checkLatency(int value) { var startTime System.currentTimeMillis(); var result RemoteService.getRemoteService().doRemoteFunction(value); var timeTaken System.currentTimeMillis() - startTime; LOGGER.info(Time taken (ms): timeTaken); return result; } private long safeCall(int value) { var retries 0; var result (long) FAILURE; for (int i 0; i RETRIES; i) { if (retries RETRIES) { return FAILURE; } if ((result checkLatency(value)) FAILURE) { LOGGER.info(Failed to reach remote: ( (i 1) )); retries; try { sleep(DELAY_MS); } catch (InterruptedException e) { LOGGER.error(Thread sleep state interrupted, e); } } else { break; } } return result; } }对照源码 ServiceAmbassador.java其类注释将这套机制概括为为 Client 提供访问 RemoteService 的接口并以一种在连接出问题时不会给远程服务增加压力的安全方式附加日志、延迟测试与服务调用。这正是 Ambassador 模式“卸载共性连接任务”价值的具体化checkLatency记录调用耗时毫秒这是客户端侧延迟监控的雏形safeCall失败后最多重试RETRIES次每次间隔DELAY_MS形成最简单的熔断/退避语义避免雪崩式重试压垮遗留服务。4. 客户端客户端只持有一个本地大使服务实例业务代码保持简洁完全不感知重试与延迟检测的细节Slf4j public class Client { private final ServiceAmbassador serviceAmbassador new ServiceAmbassador(); long useService(int value) { var result serviceAmbassador.doRemoteFunction(value); LOGGER.info(Service result: result); return result; } }5. 组装与运行两个客户端同时使用该服务对应源码 App.java 中的main方法public class App { public static void main(String[] args) { var host1 new Client(); var host2 new Client(); host1.useService(12); host2.useService(73); } }运行结果解读文档给出了运行上述示例后的典型输出Time taken (ms): 111 Service result: 120 Time taken (ms): 931 Failed to reach remote: (1) Time taken (ms): 665 Failed to reach remote: (2) Time taken (ms): 538 Failed to reach remote: (3) Service result: -1可以这样解读host1value12首次调用延迟 111ms低于阈值成功返回12012 × 10host2value73连续三次调用延迟931ms、665ms、538ms都超过阈值三次尝试全部失败最终返回-1且每次失败后都间隔了 3 秒重试——注意重试后的失败返回值本身已是 -1说明大使层已按RETRIES上限结束尝试。这套调用与重试的时序关系可以参考模块自带的时序图 ambassador/etc/ambassador-sequence-diagram.png客户端调用大使服务大使检查延迟并调用远程服务失败时进入延迟等待后重试直至成功或耗尽次数。模式的价值与适用场景从源码与文档可以确认Ambassador 模式适用且仅适用于这类情境远程服务是遗留系统无法或极难修改需要在不改动远程服务的前提下把连接性能力在客户端侧补齐。它的直接收益包括为远程服务提供一个本地接口抽象了网络细节在客户端实现日志记录、熔断circuit breaking、重试与安全控制而远程服务无需任何改动。典型用例控制对另一个对象的访问实现日志/记录能力实现熔断机制委托远程服务的调用任务简化网络连接的建立与维护这些用例在仓库中的体现非常直观ServiceAmbassador同时承载了日志LOGGER.info、延迟监控checkLatency、重试/熔断safeCall与RETRIES/DELAY_MS常量三类横切能力客户端则只做纯粹的调用与结果展示。与相关模式的关系Ambassador 模式与Proxy 模式关系最为密切两者都提供目标对象的替身接口。区别在于 Proxy 通常聚焦于访问控制与懒加载而 Ambassador 是“进程外代理”专门承载日志、监控、重试、安全等网络横切能力且常与客户端同机部署。java-design-patterns 仓库也收录了独立的 proxy 模块读者可以对照两者的实现差异来加深理解。在仓库中运行与验证模块源码位于 ambassador/src/main/java/com/iluwatar/ambassador测试代码位于 ambassador/src/test/java/com/iluwatar/ambassador含AppTest、ClientTest、RemoteServiceTest、ServiceAmbassadorTest四组测试其中RemoteServiceTest利用RandomProvider注入固定随机值以验证阈值与失败分支。构建信息见 ambassador/pom.xml作为仓库 Maven 多模块工程的一部分可使用仓库根目录的 Maven Wrappermvnw对ambassador模块执行测试例如./mvnw -pl ambassador test直接运行App的main方法即可观察到上文所述的成功/重试/失败日志。小结Ambassador 模式解决的是一个非常现实的工程问题远程服务动不了但连接体验必须提升。java-design-patterns 的ambassador模块用不到十个类就完整演示了该模式的骨架——共享接口、单例远程服务、带延迟检测与退避重试的大使服务、以及纯净的客户端。掌握它之后你可以把它作为在遗留系统周边搭建限流、监控、重试、TLS 等能力层时的参考范式也可以据此理解 Kubernetes 生态中各类 Ambassador/Sidecar 网关组件背后的设计思想。赞分享示例工程教程【免费下载链接】java-design-patternsDesign patterns implemented in Java项目地址https://gitcode.com/GitHub_Trending/ja/java-design-patterns点击查看免费下载相关推荐Cherry Studio 数据库测试指南使用 setupTestDatabase 测试主进程 SQLite 数据层Cherry Studio 数据库测试指南使用 setupTestDatabase 测试主进程 SQLite 数据层 Cherry Studio 的持久化层建示例工程教程java-design-patterns 中的 Ambassador大使模式用本地辅助服务化解远程资源调用难题java design patterns 中的 Ambassador大使模式用本地辅助服务化解远程资源调用难题 Ambassador大使模式的核心思想示例工程教程Ambassador模式pybind11客户端代理Ambassador模式pybind11客户端代理 引言跨越语言边界的桥梁 在现代软件开发中C和Python的协同工作已成为常态。C提供高性能计算开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

2026武汉公司采购班车的评分方法

2026武汉公司采购班车的评分方法

采购推荐的武汉企业员工班车租赁公司,判断标准不是公司规模或报价高低,而是能否把线路、车辆、司机、调度和异常处理稳定地交付到员工的日常通勤里。2026年做班车采购,更稳妥的做法是先立一套可核验的标准,再用同一套标准去对照候…

2026/10/2 20:53:16 阅读更多 →
Hudi 表类型选型:性能优化与场景适配指南

Hudi 表类型选型:性能优化与场景适配指南

Hudi 表类型选型:性能优化与场景适配指南 Hudi 表类型概述:Apache Hudi 作为一种数据湖表格格式,提供了两种核心表类型:Copy-on-Write (COW) 和 Merge-on-Read (MOR)。COW 表类型采用写时复制策略,每次更新操作会创建新…

2026/10/2 20:53:16 阅读更多 →
为什么要读《SICP》-- 专栏导引

为什么要读《SICP》-- 专栏导引

自古学习,先了解和接触,产生兴趣,进行练习和付出,收获反馈,提炼总结,输出。 适合哪些读者: 如果刚刚接触编程,那么这本书可能不适合你;不管你现在主要使用的是那一门编…

2026/10/2 20:53:16 阅读更多 →

最新新闻

如何把 Windows 11 任务栏找回经典快速启动工具栏?ExplorerPatcher 8 分钟配置完整指南

如何把 Windows 11 任务栏找回经典快速启动工具栏?ExplorerPatcher 8 分钟配置完整指南

如何把 Windows 11 任务栏找回经典快速启动工具栏?ExplorerPatcher 8 分钟配置完整指南 【免费下载链接】ExplorerPatcher This project aims to enhance the working environment on Windows 项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatcher …

2026/10/2 21:26:36 阅读更多 →
Java 设计模式精讲:基于 Active Object 模式构建高效异步并发系统(附 java-design-patterns 源码剖析)

Java 设计模式精讲:基于 Active Object 模式构建高效异步并发系统(附 java-design-patterns 源码剖析)

示例工程教程 【免费下载链接】java-design-patterns Design patterns implemented in Java 项目地址: https://gitcode.com/GitHub_Trending/ja/java-design-patterns 点击查看 免费下载 导读:本文以开源仓库 java-design-patterns 中的 active-object…

2026/10/2 21:26:36 阅读更多 →
深耕计算机考研,助力码农突围 — 天任考研计算机科学与技术专项集训营正式启航

深耕计算机考研,助力码农突围 — 天任考研计算机科学与技术专项集训营正式启航

计算机科学与技术是近年来考研报考热度最高的专业之一。随着信息技术和人工智能产业快速发展,计算机类研究生就业薪资持续走高,吸引了大量本专业考生和跨专业考生报考。然而,计算机考研竞争异常激烈,408 计算机学科专业基础综合内…

2026/10/2 21:26:36 阅读更多 →
Candle 运行 XLM-RoBERTa 实战:Fill-Mask、Reranker 与文本分类三大任务指南

Candle 运行 XLM-RoBERTa 实战:Fill-Mask、Reranker 与文本分类三大任务指南

人工智能大模型机器学习深度学习本地部署模型推理服务 【免费下载链接】candle Minimalist ML framework for Rust 项目地址: https://gitcode.com/GitHub_Trending/ca/candle 点击查看 免费下载 本文基于 Candle 开源仓库中的 xlm-roberta 示例 与对应源码&#x…

2026/10/2 21:26:36 阅读更多 →
2025五一数学建模竞赛B题实战:矿山数据处理建模全流程与TaoToken辅助代码论文解析

2025五一数学建模竞赛B题实战:矿山数据处理建模全流程与TaoToken辅助代码论文解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 21:26:36 阅读更多 →
全模态数据平台:面向Agent的架构与落地实践

全模态数据平台:面向Agent的架构与落地实践

今年的云栖2026主题是"湖生万物,助力AI",其中被反复讨论的一个核心概念,就是面向Agent的全模态数据平台。做Agent开发的朋友应该都深有体会:模型能力越来越强,可肚子里的"货"却常常不够用。文本、…

2026/10/2 21:25:35 阅读更多 →

日新闻

从零搭建AI工程化:模型之外的完整闭环

从零搭建AI工程化:模型之外的完整闭环

先搞清楚一件事:从零开始做 AI 工程化,难的从来不是调模型、写提示词,而是把一套原型 Demo 变成长得像是“正经系统”的东西。你手里可能已经有了能跑通的代码,也可能刚读完一些概念,但真到了要把它变成可维护、可观测…

2026/10/2 0:00:20 阅读更多 →
大模型训练显存估计与混合精度训练实战指南

大模型训练显存估计与混合精度训练实战指南

1. 大模型训练显存估计与混合精度训练详解显存不够用,几乎是每个做大模型训练的人都会撞上的第一堵墙。你可能也经历过:模型代码写完了,数据管道跑通了,满心欢喜地按下训练启动脚本,结果几秒钟后终端弹出一行红字——C…

2026/10/2 0:00:20 阅读更多 →
小样本学习数据集选型指南:27个真正可用的高质量数据集

小样本学习数据集选型指南:27个真正可用的高质量数据集

1. 小样本学习的“弹药库”:为什么你总在找数据集,却总找不到真正能用的? 小样本、数据集——这两个词最近半年在我处理的200多个AI项目咨询里,出现频率排进前三。不是模型调不好,不是代码写不对,而是卡在…

2026/10/2 0:00:20 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 19:40:48 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/1 19:41:40 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/1 20:05:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 5:26:06 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 6:09:11 阅读更多 →