Skip to content

Service Discovery

Service discovery in ASAB Maestro is a group of techniques how to find and reach specific service in the cluster network.


Each instance is provided with three identifiers:

  • NODE_ID - identifier of the cluster node
  • SERVICE_ID - name of the service
  • INSTANCE_ID - identifier of the instance

This allows to search the services in various situations by the same names.

NGINX proxy server

nginx:api option in the descriptors creates standardized Nginx configuration.

Example of ASAB Library descriptor:

  type: rc/descriptor
  name: ASAB Library


    - "{{SITE}}/{{INSTANCE_ID}}/conf:/conf:ro"
    - "{{SLOW_STORAGE}}/{{INSTANCE_ID}}:/var/lib/asab-library"

  configname: conf/asab-library.conf
  config: {}

  api: 8893

All instances are supplied with a location inside the Nginx configuration.

location /api/<instance_id> {

Moreover, each service has its location and respective upstreams record. Your request is proxied to a random instance of the service.

location /api/<service_id> {

These locations are accessible in the:

  • HTTPS server behind OAuth2 introspection (when authorization server like SeaCat Auth is installed) to be used mainly by Web UI,
  • and the internal server. This one is accessible from within the cluster, must not be open to the internet and serves for internal communication of backend services.


It is crucial for the HTTPS server functionality and successful authorization to set PUBLIC_URL parameter in the model.

    type: rc/model

        instances: {1: {node: "lmc01"} }
    PUBLIC_URL: ""

Custom /etc/hosts

Each running container is supplied by custom and automatically actualized configuration inside /etc/hosts. IP address of each service or instance is resolved using respective INSTANCE_ID or SERVICE_ID.

Example of /etc/hosts inside the container:

# This file is generated by ASAB Remote Control
::1         localhost ip6-localhost ip6-loopback
fe00::0     ip6-localnet
ff00::0     ip6-mcastprefix
ff02::1     ip6-allnodes
ff02::2     ip6-allrouters

# Nodes     lmc02    lmc03     lmc01

# Instances     zoonavigator-1     mongo-1     mongo-2    mongo-3     seacat-auth-1     nginx-1     asab-config-1     asab-config-2    asab-config-3     asab-governator-1     asab-governator-2    asab-governator-3     asab-library-1     asab-library-2    asab-library-3     asab-remote-control-1     asab-remote-control-2    asab-remote-control-3     zookeeper-1     zookeeper-2    zookeeper-3

# Services     zoonavigator     mongo     mongo    mongo     seacat-auth     nginx     asab-config     asab-config    asab-config     asab-governator     asab-governator    asab-governator     asab-library     asab-library    asab-library     asab-remote-control     asab-remote-control    asab-remote-control     zookeeper     zookeeper    zookeeper

Consensus and data advertised by running ASAB microservices

Each ASAB microservice advertise data about itself to the consensus. This data contain NODE_ID, SERVICE_ID and INSTANCE_ID resolved thanks to the custom /etc/hosts and port. ASAB framework also offers boiler plate code to use aiohttp client requests with only the SERVICE_ID or INSTANCE_ID of the target service. Thus, each ASAB microservice has tools to access any other ASAB microservice in the cluster.

Example of python code within ASAB application using Discovery Service

    async def proxy_to_iris(self, json_data):
        async with self.App.DiscoveryService.session() as session:
                async with session.put("http://asab-iris.service_id.asab/send_mail", json=json_data) as resp:
                    response = await resp.json()
            except asab.api.discovery.NotDiscoveredError:
                raise RuntimeError("ASAB Iris could not be reached.")