【Java设计模式】大使模式:简化远程资源管理

【Java设计模式】大使模式:简化远程资源管理

一、概述

在Java开发中,大使模式(Ambassador Pattern)是一种用于简化远程资源管理的设计模式。它通过将一些常见的功能,如监控、日志记录和路由,从共享资源卸载到一个辅助服务实例中,从而提高分布式系统的性能和可维护性。本文将详细介绍大使模式的意图、解释、编程示例、适用场景、优点和权衡、实际应用以及相关设计模式。同时,还将提供示例代码的下载链接,方便读者进行学习和实践。

二、大使设计模式的意图

Java中的大使模式有助于将监控、日志记录和路由等常见功能从共享资源卸载到辅助服务实例中,从而增强分布式系统的性能和可维护性。

三、大使模式的详细解释及实际示例

  1. 实际示例
    • 想象一个繁忙的酒店,客人经常请求餐厅预订、活动门票或交通安排。酒店提供了一位礼宾员,而不是让每位客人单独联系这些服务。礼宾员代表客人处理这些任务,确保预订顺利进行,门票按时预订,交通安排高效。
    • 在这个类比中,客人是客户端服务,外部提供商(餐厅、票务供应商、交通)是远程服务,礼宾员代表大使服务。这种设置允许客人专注于享受他们的住宿,而礼宾员管理外部交互的复杂性,提供无缝和增强的体验。
  2. 通俗解释
    • 通过大使模式,我们可以实现客户端较少频率的轮询,以及延迟检查和日志记录。
  3. Microsoft文档说明
    • 大使服务可以被视为与客户端共置的进程外代理。这种模式对于以语言无关的方式卸载常见的客户端连接任务非常有用,例如监控、日志记录、路由、安全(如TLS)和弹性模式。它通常用于遗留应用程序或其他难以修改的应用程序,以扩展其网络功能。它还可以使专门的团队能够实现这些功能。

四、Java中大使模式的编程示例

在这个Java中的大使模式示例中,我们展示了如何实现延迟检查、日志记录和重试机制来提高系统可靠性。

一个远程服务有许多客户端访问它提供的功能。该服务是一个遗留应用程序,无法进行更新。大量用户的请求导致连接问题。应该实现新的请求频率规则,以及延迟检查和客户端日志记录。

考虑到上述介绍,我们将在这个示例中模拟该功能。我们有一个由远程服务实现的接口以及大使服务。

interface RemoteServiceInterface {
    long doRemoteFunction(int value) throws Exception;
}

一个表示为单例的远程服务。

@Slf4j
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;
    }
}

一个服务大使添加了额外的功能,如日志记录和延迟检查。

@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;
    }
}

一个客户端使用本地服务大使与远程服务进行交互。

@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;
    }
}

这里有两个客户端使用该服务。

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

五、Java中何时使用大使模式

  1. 云原生和微服务架构:大使模式对于Java中的云原生和微服务架构特别有益。它有助于监控、日志记录和保护服务间通信,使其成为分布式系统的理想选择。
  2. 遗留系统集成:通过处理必要但非核心功能,促进与新服务的通信。
  3. 性能增强:可用于缓存结果或压缩数据以提高通信效率。

典型的用例包括:

  1. 控制对另一个对象的访问。
  2. 实现日志记录。
  3. 实现电路中断。
  4. 卸载远程服务任务。
  5. 促进网络连接。

六、大使模式的优点和权衡

  1. 优点
    • 分离关注点:将横切关注点从服务逻辑中卸载,导致更干净、更可维护的代码。
    • 可重用的基础设施逻辑:大使模式允许在多个服务中重用相同的逻辑(例如,日志记录、监控)。
    • 改进的安全性:集中安全功能,如SSL终止或身份验证,降低了配置错误的风险。
    • 灵活性:更容易更新或替换基础设施关注点,而无需修改服务代码。
  2. 权衡
    • 增加复杂性:为架构添加了另一层,这可能会使系统设计和调试复杂化。
    • 潜在的性能开销:额外的网络跳可能会引入延迟和开销,特别是如果未进行优化。
    • 部署开销:需要额外的资源和管理来部署和扩展大使服务。

七、Java中大使模式的实际应用

  1. 服务网格实现:在像Istio或Linkerd这样的服务网格架构中,大使模式通常被用作边车代理来处理服务间通信。这包括服务发现、路由、负载均衡、遥测(指标和跟踪)和安全(认证和授权)等任务。
  2. API网关:API网关可以使用大使模式来封装常见功能,如速率限制、缓存、请求整形和认证。这允许后端服务专注于其核心业务逻辑,而不会被这些横切关注点所困扰。
  3. 日志记录和监控:大使可以聚合来自各种服务的日志和指标,并将它们转发到集中式监控工具,如Prometheus或ELK Stack(Elasticsearch、Logstash、Kibana)。这简化了每个服务的日志记录和监控设置,并提供了系统健康状况的统一视图。
  4. 安全:与安全相关的功能,如SSL/TLS终止、身份验证和加密,可以由大使管理。这确保了跨服务的一致安全实践,并减少了由于配置错误导致安全漏洞的可能性。
  5. 弹性:大使可以实现弹性模式,如断路器、重试和超时。例如,Netflix的Hystrix库可以在大使中使用,以防止微服务生态系统中的级联故障。
  6. 数据库代理:大使可以作为数据库连接的代理,提供连接池、副本的读/写分离和查询缓存等功能。这卸载了应用服务的大量复杂性。
  7. 遗留系统集成:在现代微服务需要与遗留系统通信的场景中,大使可以作为中介,翻译协议、处理必要的转换,并实现现代安全实践,简化集成过程。
  8. 网络优化:对于部署在不同地理位置或云区域的服务,大使可以通过压缩数据、批处理请求或甚至实现智能路由来优化通信,以减少延迟和成本。

八、源码下载

https://download.csdn.net/download/weixin_42545951/89680728

通过本文的介绍,相信大家对Java中的大使模式有了更深入的了解。在实际开发中,合理运用大使模式可以提高系统的性能、可维护性和灵活性,为构建可靠的分布式系统提供有力支持。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值