
Service Discovery
Design and implement registry-based service discovery, health checks, and client-side load balancing for microservices without hardcoded URLs.
Install
npx skills add https://github.com/itallstartedwithaidea/agent-skills --skill service-discoveryWhat is this skill?
- Self-registration, health checking, and client-side discovery as three complementary patterns
- Nacos-inspired dynamic registry as single source of truth for topology
- Supports ephemeral instances, scaling, regional deploys, and failover without static URLs
- Frames zero-downtime deploys and region-aware routing as outcomes of live registry state
Adoption & trust: 1 installs on skills.sh; 18 GitHub stars; 2/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
Recommended Skills
Journey fit
Canonical shelf is Build integrations because the skill teaches how to wire registration and discovery into services as you implement them. Service-to-service lookup and registry clients are integration concerns between deployable units.
Common Questions / FAQ
Is Service Discovery safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Service Discovery
# Service Discovery Part of [Agent Skills™](https://github.com/itallstartedwithaidea/agent-skills) by [googleadsagent.ai™](https://googleadsagent.ai) ## Description Service Discovery implements dynamic service registry, health check monitoring, and intelligent load balancing patterns inspired by Nacos for cloud-native applications. Services register themselves on startup, announce their capabilities and health status, and are discovered by consumers without hardcoded addresses. The registry becomes the single source of truth for the service topology. In microservice and edge-distributed architectures, services are ephemeral. Instances scale up and down, deploy across regions, and fail independently. Hardcoded service URLs create brittle coupling that breaks under any topology change. Service discovery replaces static configuration with a living registry that reflects the actual state of the system at any moment. This skill covers three complementary patterns: self-registration (services announce themselves), health checking (the registry verifies liveness), and client-side discovery (consumers query the registry and select instances). Together, these patterns enable zero-downtime deployments, automatic failover, and region-aware routing without manual configuration changes. ## Use When - Building microservice architectures with dynamic scaling - Implementing health-check-driven load balancing - Replacing hardcoded service URLs with dynamic discovery - Supporting blue-green or canary deployments - Building multi-region applications with region-aware routing - Integrating multiple Workers or services that need to find each other ## How It Works ```mermaid sequenceDiagram participant S as Service Instance participant R as Service Registry participant C as Consumer participant H as Health Checker S->>R: Register(name, address, metadata) R->>R: Store in registry loop Every 10s H->>S: Health check (HTTP/TCP) S->>H: 200 OK / Healthy H->>R: Update health status end C->>R: Discover("payment-service") R->>C: [instance-1:8080, instance-2:8080] C->>C: Select instance (round-robin/weighted) C->>S: Send request to selected instance ``` Services register on startup and deregister on shutdown. The health checker continuously verifies liveness. Consumers query the registry and apply a load-balancing strategy to select an instance. ## Implementation ```typescript interface ServiceInstance { id: string; name: string; address: string; port: number; metadata: Record<string, string>; health: "healthy" | "degraded" | "unhealthy"; lastHeartbeat: number; } class ServiceRegistry { private instances = new Map<string, ServiceInstance[]>(); register(instance: ServiceInstance): void { const existing = this.instances.get(instance.name) ?? []; existing.push({ ...instance, lastHeartbeat: Date.now() }); this.instances.set(instance.name, existing); } deregister(serviceName: string, instanceId: string): void { const existing = this.instances.get(serviceName) ?? []; this.instances.set( serviceName, existing.filter(i => i.id !== instanceId) ); } discover(serviceName: string): ServiceInstance[] { const instances = this.instances.get(serviceName) ?? []; return instances.filter(i => i.health === "healthy"); } heartbeat(serviceName: string, instanceId: string): void { const instances = this.instances.get(serviceName) ?? []; const instance = instances.find(i => i.id === instanceId); if (instance) instance.lastHeartbeat = Date.now(); } pruneStale(maxAgeMs: number = 30_000): void { const cutoff = Date.now() - maxAgeMs; for (const [name, instances] of this.instances) {