Files
KarmaTashiCat 6b0a90ee61 translation: Translate the ambassador readme to Spanish (#2453) (#2456)
* 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>
2023-01-21 11:27:46 +02:00
..

title, category, language, tag
title category language tag
Ambassador Structural es
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:

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

Un servicio remoto representado como un singleton (Instancia única).

@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

@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:

@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.

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:

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

alt text

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

Patrones relacionados

Créditos

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: