mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-16 06:58:54 +00:00
* Translate: Translate the aggregator-microservices readme to Spanish [Issue #2335 (Task of issue #2277 )] * Translate: Translate the aggregator-microservices readme to Spanish [Issue #2335 (Task of issue #2277 )] * Update README.md * Restored translated YAML Frontmatter keys to right words not translated and minor new changes Minor new changes are at YAML Frontmatter variables values of lines 2 and 3 where have switched the order of translated words to homogeinize the belowing structure of that order like figured at following lines 6,7 and 8 (First english term and then Spanish translation between parenthesis) * Update localization/es/aggregator-microservices/README.md Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com> * Update localization/es/aggregator-microservices/README.md Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com> * Update localization/es/aggregator-microservices/README.md Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com> * Update localization/es/aggregator-microservices/README.md Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com> * Update localization/es/aggregator-microservices/README.md Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com> * Translated ambassador pattern README.md to Spanish(#2453) * Changed Class Diagram image path to absolute way. The original path for Class Diagram image was relative to /ambassador folder (./etc/ambassador.urm.png) when translated at line 173 of translation doesn't show the diagram image so I haved changed it to absolute format (/ambassador/etc/ambassador.urm.png) and now it shows it. Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
---
|
||||
title: Ambassador
|
||||
category: Structural
|
||||
language: es
|
||||
tag:
|
||||
- Decoupling
|
||||
- Cloud distributed
|
||||
---
|
||||
|
||||
## Motivo
|
||||
|
||||
Proporcionar una instancia de servicio auxiliar a un cliente y delegar en ella las funcionalidades comunes de un recurso compartido.
|
||||
|
||||
## Explicación
|
||||
|
||||
Ejemplo real
|
||||
|
||||
> Un servicio remoto tiene muchos clientes accediendo a una función que este servicio proporciona. El servicio es una aplicación heredada y
|
||||
> es imposible actualizarla. Un gran número de solicitudes por parte de los usuarios están causando problemas de conectividad. Nuevas reglas
|
||||
> respecto a la frecuencia de solicitudes deberían implementarse junto con comprobaciones de latencia y registros del lado del cliente.
|
||||
|
||||
En otras palabras
|
||||
|
||||
> Con el patrón Ambassador, podemos implementar una menor frecuencia en solicitudes de clientes junto con comprobaciones de latencia y
|
||||
> registros.
|
||||
|
||||
Según la Documentación de Microsoft
|
||||
|
||||
> Un servicio de Ambassador puede considerarse como un proxy fuera de proceso que coexiste con el cliente.
|
||||
>
|
||||
> Este patrón puede ser útil para la descarga de tareas comunes de conectividad de cliente, como la supervisión, el registro, el enrutamiento,
|
||||
> la seguridad (por ejemplo, TLS) y los patrones de resistencia(*) de una manera independiente del lenguaje. A menudo se utiliza con aplicaciones heredadas,
|
||||
> u otras aplicaciones que son difíciles de modificar, con el fin de ampliar sus capacidades de red. También puede
|
||||
> habilitar un equipo especializado para implementar esas características.
|
||||
|
||||
**Código de ejemplo**
|
||||
|
||||
Con la introducción anterior en mente vamos a imitar su funcionalidad en el siguiente ejemplo. Tenemos una interface implementada
|
||||
por el servicio remoto así como el servicio ambassador:
|
||||
|
||||
```java
|
||||
interface RemoteServiceInterface {
|
||||
long doRemoteFunction(int value) throws Exception;
|
||||
}
|
||||
```
|
||||
|
||||
Un servicio remoto representado como un singleton (Instancia única).
|
||||
|
||||
```java
|
||||
@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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Un servicio ambassador añadiendo funcionalidades adicionales como registros, comprobación de latencia
|
||||
|
||||
```java
|
||||
@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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Un cliente tiene un servicio ambassador local usado para interactuar con el servicio remoto:
|
||||
|
||||
```java
|
||||
@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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A continuación dos clientes usando el servicio.
|
||||
|
||||
```java
|
||||
public class App {
|
||||
public static void main(String[] args) {
|
||||
var host1 = new Client();
|
||||
var host2 = new Client();
|
||||
host1.useService(12);
|
||||
host2.useService(73);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Esta es la salida que obtendremos tras ejecutar el ejemplo:
|
||||
|
||||
```java
|
||||
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
|
||||
```
|
||||
|
||||
## Diagrama de clase
|
||||
|
||||

|
||||
|
||||
## Aplicaciones
|
||||
|
||||
Ambassador es aplicable cuando trabajamos con un servicio remoto heredado que no puede ser modificado o que sería extremamente
|
||||
difícil de modificar. Las características de conectividad pueden implementarse en el cliente sin necesidad de realizar cambios en el servicio
|
||||
remoto.
|
||||
|
||||
* Ambassador proporciona una interface local para un servicio remoto.
|
||||
* Ambassador proporciona registros, interrupción de circuitos, reintentos y seguridad en el cliente.
|
||||
|
||||
## Casos de uso típicos
|
||||
|
||||
* Control de acceso a otro objeto
|
||||
* Implementación de registros o logs
|
||||
* Implementación de interrupciones de circuito
|
||||
* Delegar tareas de servicios remotos
|
||||
* Facilitar la conexión a la red
|
||||
|
||||
## Usos conocidos
|
||||
|
||||
* [Pasarela API Kubernetes-native para microservicios](https://github.com/datawire/ambassador)
|
||||
|
||||
## Patrones relacionados
|
||||
|
||||
* [Proxy](https://java-design-patterns.com/patterns/proxy/)
|
||||
|
||||
## Créditos
|
||||
|
||||
* [Ambassador Pattern (Documentación de Microsoft en inglés)](https://docs.microsoft.com/en-us/azure/architecture/patterns/ambassador)
|
||||
* [Designing Distributed Systems: Patterns and Paradigms for Scalable, Reliable Services](https://www.amazon.com/s?k=designing+distributed+systems&sprefix=designing+distri%2Caps%2C156&linkCode=ll2&tag=javadesignpat-20&linkId=a12581e625462f9038557b01794e5341&language=en_US&ref_=as_li_ss_tl)
|
||||
|
||||
## Notas del traductor
|
||||
(*) La versión original en inglés de la documentación de Microsoft hace referencia al término resiliencia y
|
||||
en su traducción al español lo traduce como resistencia, aunque enlaza al apartado patrones de confiabilidad. Véase:
|
||||
* [Versión de la Documentación para el Patrón Ambassador de Microsoft en español.](https://learn.microsoft.com/es-es/azure/architecture/patterns/ambassador)
|
||||
Reference in New Issue
Block a user