Microservice

ENGINEER.
I was tasked with leading a project at work that involved a hefty system design, logic flow, and breaking down of tasks. I picked a team of 10 and subdivided them into teams based on respective services giving them a level of flexibility between choosing languages that better suit the scope of work and their skillset. of course, I wouldn't be able to dive into the intricacies, but here is how I was able to simulate each microservice, saving time and money.
Project Structure
project /
|-- go-service /
| |-- main.go
| |-- Dockerfile
|-- node-service /
| |-- index.js
| |-- Dockerfile
|-- docker-compose.yml
1. Define Your Microservices:
Functionality: Decide on the functionalities of each microservice. For example, one could handle user authentication, and another could manage product data.
Programming Language: Choose Go and Node.js for your example.
Database: Specify Postgres as the database for both.
2. Development:
a) Go Microservice:
Start with a Go project template for gRPC.
Implement your desired functionalities with gRPC endpoints for communication.
Connect to the Postgres database using a Go driver like
lib/pq.Build your Go binary using
go build.
package main
import (
"log"
"net"
"google.golang.org/grpc"
"github.com/your_username/your_project/pb"
)
type server struct{}
func (s *server) SayHello(req *pb.HelloRequest, stream pb.Greeter_SayHelloServer) error {
log.Printf("Received: %v", req.Name)
resp := &pb.HelloResponse{Message: "Hello, " + req.Name}
return stream.Send(resp)
}
func main() {
listener, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
srv := grpc.NewServer()
pb.RegisterGreeterServer(srv, &server{})
log.Println("Server is listening on :50051")
if err := srv.Serve(listener); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}
b) Node.js Microservice:
Use a Node.js framework like
grpcormicrofor gRPC development.Implement your functionalities with gRPC endpoints.
Connect to the Postgres database using a Node.js driver like
pg.Build your Node.js application using
npm run buildor similar.
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
const packageDefinition = protoLoader.loadSync('your_proto_file.proto', { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true });
const hello_proto = grpc.loadPackageDefinition(packageDefinition).hello;
const server = new grpc.Server();
server.addService(hello_proto.Greeter.service, {
sayHello: (call, callback) => {
console.log(`Received: ${call.request.name}`);
const message = `Hello, ${call.request.name}`;
callback(null, { message });
},
});
server.bind('0.0.0.0:50052', grpc.ServerCredentials.createInsecure());
console.log('Server running at http://127.0.0.1:50052');
server.start();
c) Shared gRPC Protocol:
Define a shared gRPC protocol file (e.g.,
.proto) specifying messages and services used for communication.Generate Go and Node.js code from the protocol using tools like
protoc-gen-goand@grpc/grpc-js.
d) Postgres Database:
Define your database schema within your chosen microservice projects.
Use tools like
psqlor a database management GUI to create and initialize your database on your development machine.
3. Dockerize Microservices and Database:
a) Dockerfiles:
Create separate Dockerfiles for each microservice, specifying their respective build steps, runtime environments, and dependencies.
Create a Dockerfile for the Postgres database, including initialization scripts and environment variables for connection details.
b) Docker Compose:
Define a
docker-compose.ymlfile to orchestrate multiple services and build them together.Include configurations for ports, environment variables, volumes (for persistent data), and networks for internal communication.
c) Running Locally:
Use
docker-compose upto build and run all services simultaneously.Test your gRPC communication between microservices using client tools like
grpcurl.
4. Deploy to AWS ECR:
a) AWS Account and ECR Setup:
Create an AWS account and set up Elastic Container Registry (ECR).
Create separate repositories in ECR for each microservice and the database image.
b) Docker Push:
Use
docker loginto authenticate with your ECR repository.Use
docker pushto push each built image to its corresponding ECR repository.
c) Docker Compose with AWS ECS:
Update your
docker-compose.ymlto use AWS ECS as the deployment platform.Define tasks and services for each microservice and database, referencing the pushed ECR images.
Use tools like
aws-composeorecs-clito deploy your infrastructure and services to ECS.
d) Accessing Deployed Services:
Once deployed, access your microservices through their exposed ports on the ECS instances.
Use client tools like
grpcurlwith the updated server addresses to test communication.
Additional Notes:
Consider security best practices like IAM roles and secrets management for access control and sensitive information.
Utilize monitoring and logging solutions to track the health and performance of your deployed services.
This guide provides a basic overview. Each step may involve additional configurations and considerations depending on your specific needs and chosen tools.



