AWS ECS ServiceDiscovery SDK

AWS ECS ServiceDiscovery SDK

Table of contents

No heading

No headings in the article.

FieldCircle infrastructure has been deployed using AWS Cloud, back in 2020 when we were ready with our first version and a decision was needed to choose between ECS and Kubernetes, we have decided to go with ECS. It was purely business decision since we had strong hand on AWS services, learning curve was smaller than Kubernetes and FieldCircle has customers lined up for POC.

So far ECS has been working very well for us there hasn’t been any issues in terms of visibility of container orchestration currently FieldCircle have been running more than 25 micro-services and multiple containers for each one of them.

Coming to the topic of micro-service interprocess communication ECS has given 3 different ways to achieve it, for detail please read here.

  • Service Discovery
  • Internal Load Balancer
  • Service Mesh

During the initial version we have focused on deployment using Service Discovery method via service-discovery SDK provided by AWS.

implementation group: 'com.amazonaws', name: 'aws-java-sdk-servicediscovery', version: '1.12.342'

AWS ECS Service Discovery

Scenario: Consider a service “service-a” which has an API which requires some data from “service-b”.

Solution: “service-a” will internally call the api of “service-b” using service discovery mechanism.

Implementation:

  • Discover NameSpace
  • Get all ECS Instances
  • Get all docker containers for specific service
  • Randomly pick any service
@Service  
public class CloudMapServiceLocationResolver implements ServiceLocationResolver {  
    private final Logger logger \= LogManager.getLogger(this.getClass().getName());  

    private static final Random RAND \= new Random(System.currentTimeMillis());  

    @Override  
    public String resolve(String serviceName) {  
        final AWSServiceDiscovery awsServiceDiscovery \= AWSServiceDiscoveryClientBuilder.defaultClient();  
        logger.info("awsServiceDiscovery " + awsServiceDiscovery);  
        final DiscoverInstancesRequest discoverInstancesRequest \= new DiscoverInstancesRequest();  
        discoverInstancesRequest.setNamespaceName(AwsServiceDiscoveryConstants.AWS\_CLOUD\_NAMESPACE);  
        discoverInstancesRequest.setServiceName(serviceName);  
        discoverInstancesRequest.setHealthStatus(HealthStatus.HEALTHY.name());  
        logger.info("discoverInstancesRequest " + discoverInstancesRequest);  

        final DiscoverInstancesResult discoverInstancesResult \= awsServiceDiscovery.discoverInstances(discoverInstancesRequest);  
        logger.info("discoverInstancesResult" + discoverInstancesResult);  
        final List<HttpInstanceSummary> allInstances = discoverInstancesResult.getInstances();  
        final List<String> serviceEndpoints = allInstances.stream()  
                .map(result -> result.getAttributes().get(AwsServiceDiscoveryConstants.AWS\_INSTANCE\_IPV\_4\_ATTRIBUTE) + ":"  
                        + result.getAttributes().get(AwsServiceDiscoveryConstants.AWS\_INSTANCE\_PORT\_ATTRIBUTE))  
                .collect(Collectors.toList());  
        logger.info("Found instances: {}", serviceEndpoints);  

        final HttpInstanceSummary result \= allInstances.get(RAND.nextInt(allInstances.size()));  
        logger.info("result " + result);  
        return result.getAttributes()  
                .get(AwsServiceDiscoveryConstants.AWS\_INSTANCE\_IPV\_4\_ATTRIBUTE) + ":"  
                + result.getAttributes().get(AwsServiceDiscoveryConstants.AWS\_INSTANCE\_PORT\_ATTRIBUTE);  
    }  
}
public interface ServiceLocationResolver {  
    String resolve(String serviceName);  
}
public interface AwsServiceDiscoveryConstants {  
    String AWS\_INSTANCE\_IPV\_4\_ATTRIBUTE \= "AWS\_INSTANCE\_IPV4";  
    String AWS\_INSTANCE\_PORT\_ATTRIBUTE \= "AWS\_INSTANCE\_PORT";  
    String AWS\_CLOUD\_NAMESPACE \= "{WRITE YOUR NAMESPACE HERE}";  
}

Note:: Make sure to print the logs so that it will help you to understand the communication between infrastructure.

I hope above piece of source helps you to write your own integration, for detail implementation checkout the github repo here. Feel free to reach out to me in case of any queries.