Implementing a simple microservices architecture using the Netflix OSS

● AWS Elastic Load Balancer

● AWS Elastic Container Service

● Netflix Eureka

● Netflix Zuul

Architecture diagram

Containerizing the microservices:

The first task in setting up the infrastructure is to get the microservices containerized and running on ECS/ Docker. Assuming the microservices are Java and built as JAR files, a sample Dockerfile would be:

FROM java:8
EXPOSE 8081
ADD <path to sample JAR> Sample-Service-0.0.1.jar
ENTRYPOINT [“java”, “-jar”, “Sample-Service-0.0.1.jar”]

Amazon’s ECS is preferred because we could leverage the service to auto-scale depending on the incoming requests to the microservice.

Alternative to ECS could be Docker Swarm.

Assuming we are load balancing across 2 nodes, we will set up Eureka and Zuul on both nodes. Eureka and Zuul are both SpringBoot applications, whose codebase can be pre-configured and downloaded from Spring Initializer.

Configuring Eureka for High Availability / Peer-Awareness mode:

Copy the Eureka codebase to both nodes. Only configuration changes needed will be done in the /src/main/resources/application.yml file on both nodes.

On node 1, make the following changes in the application.yml:

server:
port: 8761
spring:
application:
name: eureka-server
eureka:
instance:
hostname: eureka-peer1
client:
registerWithEureka: true
fetchRegistry: true
service-url:
defaultZone: http://eureka-peer2:${server.port}/eureka
server:
enableSelfPreservation: true
management:
endpoint:
health:
show-details: ALWAYS
endpoints:
web:
exposure:
include:
- health

On node 2, make the following changes in the application.yml:

server:
port: 8761
spring:
application:
name: eureka-server
eureka:
instance:
hostname: eureka-peer2
client:
registerWithEureka: true
fetchRegistry: true
service-url:
defaultZone: http://eureka-peer1:${server.port}/eureka
server:
enableSelfPreservation: true
management:
endpoint:
health:
show-details: ALWAYS
endpoints:
web:
exposure:
include:
- health

Also, make sure the following dependencies are added in both nodes in the pom.xml file (assuming we’re using Maven):

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

Note: edit /etc/hosts file on both nodes to assign hostnames, so they can be reached from each other. It should be similar to this:

docker run -h eureka-peer1 <other switches if needed> <eureka-image>

Do the same for node 2.

When Eureka server instances boot up they will look for each other. All microservices will register with them automatically, so if one goes down the other server instance will be always there. On both Eureka instances you will be able to see all the registered microservices. Like this you can scale-up and have multiple server instances in a production environment.

Setting up Zuul API Gateway:

Like Eureka, Zuul is also a Springboot application which will act as the API Gateway for all incoming requests. Download and build the codebase from Spring Initializer. Run it as a standalone JAR or as a container on both nodes.

Configuration:

server:
port: 8080
spring:
application:
name: zuul-proxy
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
instance:
preferIpAddress: true
zuul:
routes:
customer-service:
serviceId: <sample-service>
host:
socket-timeout-millis: 30000

Just send request to http://localhost:8080/sample-service/api/sample-api The Zuul proxy will redirect this request to sample-service/api/sample-api and by using the service registry it will resolve the exact path of the sample-service which is : http://localhost:port.

Set up AWS ELB:

Provision an Elastic Load Balancer and configure it to handle incoming requests between the 2 nodes from your AWS account.

DevOps evangelist getting his business degree