Skip to content

ranjanr/ServiceRegistry

Repository files navigation

Service Registry - Distributed System Learning Project

A simple but functional service registry implementation for understanding service discovery in distributed systems.

πŸš€ Quick Start

Prerequisites

Python 3.8 or higher

Installation

  1. Clone the repository:
git clone https://github.com/ranjanr/ServiceRegistry.git
cd ServiceRegistry
  1. Create a virtual environment (Python 3.13+):
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
  1. Install dependencies:
pip install -r requirements.txt

Running the Service Registry

# Make sure virtual environment is activated
source venv/bin/activate

# Start the registry
python3 service_registry_improved.py

You should see:

Service Registry starting on port 5000...
Heartbeat timeout: 30s
Cleanup interval: 10s

πŸ“š What is a Service Registry?

A Service Registry is a database of available service instances in a distributed system. It enables:

  • Service Registration: Services register themselves when they start
  • Service Discovery: Services can find and communicate with each other
  • Health Monitoring: Track which services are alive and healthy
  • Load Balancing: Distribute requests across multiple service instances

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Service A  │────────▢│ Service Registry │◀────────│  Service B  β”‚
β”‚ (Port 8001) β”‚ Registerβ”‚   (Port 5000)    β”‚ Discoverβ”‚ (Port 8002) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚                          β”‚                          β”‚
      └──────── Heartbeat β”€β”€β”€β”€β”€β”€β”€β”˜                          β”‚
                                 └──────── Heartbeat β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Project Files

1. service_registry.py (Original Example)

The basic implementation you provided - simple but functional.

Pros:

  • βœ… Simple and easy to understand
  • βœ… Core functionality works

Cons:

  • ❌ No error handling
  • ❌ No health checks
  • ❌ No way to remove services
  • ❌ Services stay registered forever (even if they crash)

2. service_registry_improved.py (Production-Ready)

Enhanced version with enterprise features.

New Features:

  • βœ… Error Handling: Proper validation and error responses
  • βœ… Health Checks: Heartbeat mechanism to detect dead services
  • βœ… Deregistration: Services can unregister gracefully
  • βœ… Auto Cleanup: Removes stale services automatically
  • βœ… Thread Safety: Uses locks for concurrent access
  • βœ… Detailed Responses: Rich JSON responses with metadata
  • βœ… Service Listing: View all registered services

3. example_service.py

Demo client showing how services interact with the registry.

4. Kubernetes/Minikube Deployment

  • Dockerfile - Container image for the registry
  • k8s/ - Kubernetes manifests for deployment
  • KUBERNETES.md - Complete Kubernetes deployment guide
  • deploy-minikube.sh - Automated deployment script

5. HashiCorp Consul Integration

  • consul_client.py - Consul service discovery client
  • CONSUL.md - Production-grade service registry guide
  • Compare custom implementation with industry-standard Consul

πŸš€ Getting Started

Choose your learning path:

Option 1: Local Development (Recommended for Learning)

Prerequisites

Python 3.8 or higher

Installation

  1. Clone the repository:
git clone https://github.com/ranjanr/ServiceRegistry.git
cd ServiceRegistry
  1. Create a virtual environment:
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
  1. Install dependencies:
pip install -r requirements.txt

Running the Registry

Basic Version:

python3 service_registry.py

Improved Version (Recommended):

python3 service_registry_improved.py

The registry will start on http://localhost:5001

Option 2: Kubernetes/Minikube (Production-like Environment)

Prerequisites

Quick Deploy

# One-command deployment
./deploy-minikube.sh

This will:

  1. Start Minikube (if not running)
  2. Build Docker image
  3. Deploy registry and example services
  4. Show access URLs and test commands

Manual Deploy

# Start Minikube
minikube start

# Build image
eval $(minikube docker-env)
docker build -t service-registry:latest .

# Deploy
kubectl apply -f k8s/registry-deployment.yaml
kubectl apply -f k8s/example-service-deployment.yaml

# Access
minikube ip  # Get IP
curl http://<MINIKUBE_IP>:30001/health

See KUBERNETES.md for complete guide.

Testing with Example Services

Terminal 1: Start the Registry

python service_registry_improved.py

Terminal 2: Start User Service

python example_service.py user-service 8001

Terminal 3: Start Payment Service

python example_service.py payment-service 8002

Terminal 4: Run Discovery Demo

python example_service.py demo

πŸ“‘ API Endpoints

1. Register a Service

POST /register
Content-Type: application/json

{
  "service": "user-service",
  "address": "http://localhost:8001"
}

Response:

{
  "status": "registered",
  "message": "Service user-service registered at http://localhost:8001"
}

2. Discover a Service

GET /discover/user-service

Response:

{
  "service": "user-service",
  "instances": [
    {
      "address": "http://localhost:8001",
      "uptime_seconds": 45.2
    }
  ],
  "count": 1
}

3. Send Heartbeat

POST /heartbeat
Content-Type: application/json

{
  "service": "user-service",
  "address": "http://localhost:8001"
}

4. Deregister a Service

POST /deregister
Content-Type: application/json

{
  "service": "user-service",
  "address": "http://localhost:8001"
}

5. List All Services

GET /services

Response:

{
  "services": {
    "user-service": {
      "total_instances": 2,
      "active_instances": 2
    },
    "payment-service": {
      "total_instances": 1,
      "active_instances": 1
    }
  },
  "total_services": 2
}

6. Health Check

GET /health

πŸ” Key Concepts Explained

1. Service Registration

When a service starts, it tells the registry:

  • Who am I? (service name)
  • Where am I? (address/port)
# Service registers itself
requests.post("http://registry:5001/register", json={
    "service": "user-service",
    "address": "http://localhost:8001"
})

2. Service Discovery

When a service needs to call another service:

  • Ask the registry for available instances
  • Get list of addresses
  • Choose one (round-robin, random, etc.)
# Discover payment service
response = requests.get("http://registry:5001/discover/payment-service")
instances = response.json()['instances']
payment_url = instances[0]['address']  # Use first instance

3. Heartbeat Mechanism

Services periodically send "I'm alive" signals:

  • Prevents stale entries
  • Detects crashed services
  • Registry removes services that stop sending heartbeats
# Send heartbeat every 10 seconds
while True:
    requests.post("http://registry:5001/heartbeat", json={
        "service": "user-service",
        "address": "http://localhost:8001"
    })
    time.sleep(10)

4. Graceful Shutdown

When a service stops, it should deregister:

  • Prevents clients from calling dead services
  • Keeps registry clean
# On shutdown
requests.post("http://registry:5001/deregister", json={
    "service": "user-service",
    "address": "http://localhost:8001"
})

🎯 Real-World Use Cases

Netflix Eureka

Netflix uses a similar pattern with their Eureka service registry:

  • Microservices register on startup
  • Other services discover them dynamically
  • Handles thousands of service instances

Kubernetes Service Discovery

Kubernetes has built-in service discovery:

  • Services register via DNS
  • Load balancing across pods
  • Health checks and auto-restart

Consul by HashiCorp

Production-grade service registry with:

  • Health checking
  • Key-value store
  • Multi-datacenter support

πŸ”§ Improvements You Could Add

  1. Persistence: Save registry to disk/database
  2. Load Balancing: Return instances in round-robin order
  3. Service Metadata: Store version, tags, capabilities
  4. Authentication: Secure the registry endpoints
  5. Monitoring: Add metrics and logging
  6. Clustering: Multiple registry instances for high availability
  7. Service Mesh: Integrate with Istio or Linkerd

πŸ§ͺ Testing with cURL

# Register a service
curl -X POST http://localhost:5001/register \
  -H "Content-Type: application/json" \
  -d '{"service": "test-service", "address": "http://localhost:9000"}'

# Discover services
curl http://localhost:5001/discover/test-service

# List all services
curl http://localhost:5001/services

# Send heartbeat
curl -X POST http://localhost:5001/heartbeat \
  -H "Content-Type: application/json" \
  -d '{"service": "test-service", "address": "http://localhost:9000"}'

# Deregister
curl -X POST http://localhost:5001/deregister \
  -H "Content-Type: application/json" \
  -d '{"service": "test-service", "address": "http://localhost:9000"}'

πŸ“Š Comparison: Original vs Improved

Feature Original Improved
Registration βœ… βœ…
Discovery βœ… βœ…
Error Handling ❌ βœ…
Heartbeats ❌ βœ…
Deregistration ❌ βœ…
Auto Cleanup ❌ βœ…
Thread Safety ❌ βœ…
Service Listing ❌ βœ…
Health Endpoint ❌ βœ…
Uptime Tracking ❌ βœ…

πŸŽ“ Learning Resources

πŸ“ License

This is a learning project - feel free to use and modify as needed!

🀝 Contributing

This is an educational project. Feel free to:

  • Add new features
  • Improve documentation
  • Create additional examples
  • Share your learnings!

About

Naming and Service discovery code example for cmpe 273

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors