Inter-Microservice Communication with OpenFeign using AWS AppMesh
Tags: java, aws, microservices, openfeign
Published: 2022-10-24 03:31:22

Learn how to use AWS AppMesh to facilitate inter-microservice communication with OpenFeign without using Spring Eureka. Instead, Service Discovery native to AWS will be used.

## 1. Introduction
Microservice architecture is becoming more and more popular nowadays. Thanks to the ever-changing requirements of software development. It allows cross-functional teams to develop, test, and deploy different services, which leads to faster release to the customer.

## 2. Microservice Pattern
One pattern in which a microservice architecture can be applied to a project is business capability. For instance, an e-commerce store can have a catalog service, price service, delivery service, etc. When presenting the catalog or product data to the client, it's usually accompanied by a price. Thus, catalog service must pull the cost from the price service. Or, if you have a backend for front-end service, you call and aggregate the result of catalog and price service data.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jkbd1cltr0ivu5svc69i.png)

## 3. Spring Cloud
It would help to use a framework that offers a toolkit when developing a microservice architecture. Some of the most commonly known are Go, Quarkus, Micronaut, but my personal favorite is Spring Cloud.

Spring Cloud offers:

- Ribbon - load balancing
- Eureka - naming server
- Resilience4j - fault-tolerance
- API Gateway
- OpenFeign - API client
- Distributed-Tracing - Sleuth/Zipkin
[Spring Microservice Architecture](https://www.czetsuyatech.com/2019/06/spring-microservice-architecture.html)

## 4. Service Discovery
Service Discovery is a way for a set of microservices to locate and communicate with each other on a network. It needs a central service where all microservices need to register. The microservices register with their name and network information such as IP. In the Spring Cloud ecosystem, it is the Eureka library that should run on its own service.

This presents a problem since Eureka server is am an essential part of the application. You need to have at least 2 instances to ensure that it's always available. Otherwise, your application will be broken. And extra service means additional maintenance and cost.

## 5. AWS App Mesh
Introducing the AWS AppMesh, built differently but solves the same problem of microservice networking. It gives end-to-end visibility and high availability for your application.

This service is free. You need to pay the underlying compute engine, either EC2 or Fargate.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xamcbvysm13p8ji2cuq9.png)

[AWS AppMesh](https://aws.amazon.com/app-mesh)

## 6. OpenFeign
OpenFeign is a library that allows us to create HTTP clients with an annotated interface. No implementation code is required.

An example OpenFeign client:

```
@FeignClient(name = "applicant-services", url = "${app.ct.client.applicant.url}")
public interface ApplicantProxy {
 
  @GetMapping("/applicants/profiles")
  List<String> getApplicantsByJob();
 
  @GetMapping("/applicants/top")
  List<String> getTopApplicantsByJob();
}
```

If the services are registered in Eureka, we won't need the URL parameter. It should point to the Service discovery endpoint of the service [see 8.4].

## 7. Missing Service Discovery without Eureka?
Fortunately, AWS has a native alternative, Amazon ECS Service Discovery. It uses AWS Cloud Map API actions to manage HTTP and DNS namespaces for your Amazon ECS services.

This service is not free. Pricing computation https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-discovery.html.

## 8. AWS Setup
Since you're here I will assume that you are already familiar with the AWS services.

### 8.1 ECR
Create 2 new repositories:

- applicant-services
- job-services

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h0a5edq87il2piocxgt4.png)

### 8.2 Cloud Map
Add a new namespace: czetsuyatech.lab

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s35en6ejfr7fp5whoshn.png)

### 8.3 App Mesh
Add two virtual nodes:
dev-vn-application-services
dev-vn-job-services

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z5l2gdl7wjvnc5wuzq3n.png)

Add two virtual services:

- dev-vs-application-services
- dev-vs-job-services

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0f34kk3dgofw0wrrq8m2.png)

Add a new App Mesh Lab

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cn9ip8m3bporz0ey7hj6.png)

### 8.4 ECS
Create two task definitions using Fargate. Add the following containers:

- applicant/job services
- aws-xray-daemon
- envoy (we need to define the following container variables)
  - ENVOY_LOG_LEVEL=trace
  - ENABLE_ENVOY_XRAY_TRACING=1
  - XRAY_DAEMON_PORT=2000

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5wtudh53rpued2fi5wmr.png)

Set these environment variables.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/loodt0fqat88w40mnm8d.png)

Don't forget to enable AppMesh.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/whmisfnaycnognz6p47b.png)

Discovery Endpoints:

- applicant-services - http://applicant-services.czetsuyatech.lab:8081
- job-services - not needed

## 9. Service URLs

Applicant Services
- http://localhost:8081/applicants/profiles
- http://localhost:8081/applicants/top

Job Services

- http://localhost:8080/jobs/profiles
- http://localhost:8080/jobs/top

## 10. Source Code

- https://github.com/czetsuya/lab-microservice-spring-aws