「Cloud Design Patterns」Ambassador pattern

780 阅读4分钟

一些总结:

  1. 本质上是一个进程外的代理,只不过和被代理的服务在同一个客户端内。和 Sidecar Pattern 很类似

  2. 用来承接客户端连接相关的通用功能,如监控、日志、路由和安全。通常用在遗留应用和难以修改的应用上,通过集中化地方式(一套代码仓库、一个专门的团队来维护)增强这些目标应用的网络能力

  3. 几种部署模式:

    1. 微服务体系下的 sidecar

    2. 多服务共享体系下的 daemon

    3. 容器化部署模式下的独立 container

  4. 何时使用/不使用

    1. 使用

      1. 需要一套通用化的非功能性能力,比如监控、日志、路由和安全

      2. 通用化的能力需要有专门的团队来维护(符合康威定律)

      3. 需要为遗留系统、难以修改的系统增加以上这些能力

    2. 不使用

      1. 对调用延迟敏感的应用,因为增加了一个 proxy 势必会增加延迟

      2. 没有通用化的需求时。比如只有一个单一语言的应用需要这些功能,那还不如将它们当成一个 package 来开发即可

      3. 无法通用化时。比如以上提到的监控、日志、路由和安全这些功能和业务逻辑关系紧密,不方便抽象或者抽象的代价过大时


Ambassador pattern

Create helper services that send network requests on behalf of a consumer service or application. An ambassador service can be thought of as an out-of-process proxy that is co-located with the client.

This pattern can be useful for offloading common client connectivity tasks such as monitoring, logging, routing, security (such as TLS), and resiliency patterns in a language agnostic way. It is often used with legacy applications, or other applications that are difficult to modify, in order to extend their networking capabilities. It can also enable a specialized team to implement those features.

Context and problem

Resilient cloud-based applications require features such as circuit breaking , routing, metering and monitoring, and the ability to make network-related configuration updates. It may be difficult or impossible to update legacy applications or existing code libraries to add these features, because the code is no longer maintained or can't be easily modified by the development team.

Network calls may also require substantial configuration for connection, authentication, and authorization. If these calls are used across multiple applications, built using multiple languages and frameworks, the calls must be configured for each of these instances. In addition, network and security functionality may need to be managed by a central team within your organization. With a large code base, it can be risky for that team to update application code they aren't familiar with.

Solution

Put client frameworks and libraries into an external process that acts as a proxy between your application and external services. Deploy the proxy on the same host environment as your application to allow control over routing, resiliency, security features, and to avoid any host-related access restrictions. You can also use the ambassador pattern to standardize and extend instrumentation. The proxy can monitor performance metrics such as latency or resource usage, and this monitoring happens in the same host environment as the application.

image

Features that are offloaded to the ambassador can be managed independently of the application. You can update and modify the ambassador without disturbing the application's legacy functionality. It also allows for separate, specialized teams to implement and maintain security, networking, or authentication features that have been moved to the ambassador.

Ambassador services can be deployed as a sidecar to accompany the lifecycle of a consuming application or service. Alternatively, if an ambassador is shared by multiple separate processes on a common host, it can be deployed as a daemon or Windows service. If the consuming service is containerized, the ambassador should be created as a separate container on the same host, with the appropriate links configured for communication.

Issues and considerations

  • The proxy adds some latency overhead. Consider whether a client library, invoked directly by the application, is a better approach.

  • Consider the possible impact of including generalized features in the proxy. For example, the ambassador could handle retries, but that might not be safe unless all operations are idempotent.

  • Consider a mechanism to allow the client to pass some context to the proxy, as well as back to the client. For example, include HTTP request headers to opt out of retry or specify the maximum number of times to retry.

  • Consider how you will package and deploy the proxy.

  • Consider whether to use a single shared instance for all clients or an instance for each client.

When to use this pattern

Use this pattern when you:

  • Need to build a common set of client connectivity features for multiple languages or frameworks.

  • Need to offload cross-cutting client connectivity concerns to infrastructure developers or other more specialized teams.

  • Need to support cloud or cluster connectivity requirements in a legacy application or an application that is difficult to modify.

This pattern may not be suitable:

  • When network request latency is critical. A proxy will introduce some overhead, although minimal, and in some cases this may affect the application.

  • When client connectivity features are consumed by a single language. In that case, a better option might be a client library that is distributed to the development teams as a package.

  • When connectivity features cannot be generalized and require deeper integration with the client application.

Example

The following diagram shows an application making a request to a remote service via an ambassador proxy. The ambassador provides routing, circuit breaking, and logging. It calls the remote service and then returns the response to the client application:

image

REF:learn.microsoft.com/en-us/azure…