A high-performance CDN edge caching system built with OpenResty (Nginx + Lua), Go backend, and Memcached. This system provides intelligent content caching based on geographic location and device type.
The system consists of three main components:
- OpenResty Proxy - Acts as the edge cache layer with Lua-based intelligent routing
- Go Backend Service - Provides the origin content service
- Memcached - Distributed memory caching system
┌─────────────┐ ┌─────────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │ -> │ OpenResty │ -> │ Go Backend │ │ Memcached │
│ │ │ (Nginx + Lua) │ │ Service │ │ Cache │
└─────────────┘ └─────────────────┘ └──────────────┘ └─────────────┘
│ ^
└──────────────────────────────────────────┘
- Geographic-based caching - Different cache keys for local, European, and global users
- Device-type optimization - Separate caching strategies for mobile, tablet, and desktop
- Intelligent cache miss handling - Automatic backend fallback and cache population
- High performance - Lua-based logic for minimal latency
- Containerized deployment - Easy setup with Docker Compose
- Docker
- Docker Compose
-
Clone the repository
git clone <repository-url> cd layer
-
Start the services
docker-compose up -d
-
Verify the setup
# Check if all services are running docker-compose ps # Test the endpoint curl http://localhost:8082/
- OpenResty Proxy:
8082(external) ->80(internal) - Go Backend Service:
8081 - Memcached:
11211
The system automatically detects user location based on IP address:
- Local:
10.x.x.x,192.168.x.x,172.16.x.xranges - Europe:
185.x.x.xrange - Global: All other IP addresses
Device types are determined from the User-Agent header:
- Mobile: Contains "Mobile" or "Android"
- Tablet: Contains "iPad"
- Desktop: Default for all other user agents
layer/
├── docker-compose.yaml # Container orchestration
├── README.md # Project documentation
├── openresty/ # OpenResty configuration
│ ├── nginx.conf # Nginx configuration
│ └── lua/
│ └── cdn_logic.lua # CDN logic implementation
└── golang_service/ # Backend service
├── Dockerfile # Go service container
├── go.mod # Go dependencies
├── go.sum # Go dependency checksums
└── main.go # Main service implementation
- Request Processing: Client requests are received by OpenResty
- Location & Device Detection: Lua script analyzes IP and User-Agent
- Cache Key Generation: Unique cache key created using URI + location + device type
- Cache Lookup: System checks Memcached for existing content
- Cache Hit: If found, content is served directly with device-specific modifications
- Cache Miss: Request is forwarded to Go backend, response is cached and served
# Test basic endpoint
curl http://localhost:8082/
# Test with different User-Agent (mobile)
curl -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1" http://localhost:8082/
# Test with tablet User-Agent
curl -H "User-Agent: Mozilla/5.0 (iPad; CPU OS 14_0 like Mac OS X) AppleWebKit/605.1.15" http://localhost:8082/# First request (cache miss)
time curl http://localhost:8082/
# Second request (cache hit)
time curl http://localhost:8082/# OpenResty logs
docker logs openresty_proxy
# Go backend logs
docker logs golang_backend
# Memcached logs
docker logs memcached_cacheConnect to Memcached to view cache statistics:
docker exec -it memcached_cache telnet localhost 11211
stats
quitEdit openresty/lua/cdn_logic.lua and restart the OpenResty container:
docker-compose restart openrestyModify golang_service/main.go and rebuild:
docker-compose up --build golang_service- The system currently uses basic IP-based geographic detection
- Consider implementing proper GeoIP databases for production use
- Add authentication and rate limiting for production deployments
- Implement proper error handling and monitoring
- Adjust cache TTL (currently 3600 seconds) in
cdn_logic.lua - Tune Memcached memory allocation in
docker-compose.yaml - Configure OpenResty worker processes based on your hardware
- Implement cache warming strategies for frequently accessed content
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
[Add your license information here]
- Services not starting: Check Docker logs and ensure ports are available
- Cache not working: Verify Memcached connection in OpenResty logs
- Backend unreachable: Check service linking in docker-compose.yaml
# Check if backend is responding
curl http://localhost:8081/
# Check if proxy is working
curl http://localhost:8082/
# Check Memcached connectivity
telnet localhost 11211