The Registry API provides interfaces for service registration and discovery, enabling dynamic service-to-service communication.
Interfaces
Registrar
Service registrar interface for registering and deregistering services.
type Registrar interface {
Register(ctx context.Context, service *ServiceInstance) error
Deregister(ctx context.Context, service *ServiceInstance) error
}
Register
func(ctx context.Context, service *ServiceInstance) error
Registers a service instance with the registry
Deregister
func(ctx context.Context, service *ServiceInstance) error
Deregisters a service instance from the registry
Discovery
Service discovery interface for finding services.
type Discovery interface {
GetService(ctx context.Context, serviceName string) ([]*ServiceInstance, error)
Watch(ctx context.Context, serviceName string) (Watcher, error)
}
GetService
func(ctx context.Context, serviceName string) ([]*ServiceInstance, error)
Returns all service instances for the given service name from memory
Watch
func(ctx context.Context, serviceName string) (Watcher, error)
Creates a watcher for monitoring service changes
Watcher
Service watcher interface for monitoring service changes.
type Watcher interface {
Next() ([]*ServiceInstance, error)
Stop() error
}
Next
func() ([]*ServiceInstance, error)
Returns services in two cases:
- The first time watching and the service instance list is not empty
- Any service instance changes are detected
Blocks until a change occurs or context is canceled.
Closes the watcher and releases resources
Types
ServiceInstance
Represents a service instance in the registry.
type ServiceInstance struct {
ID string `json:"id"`
Name string `json:"name"`
Version string `json:"version"`
Metadata map[string]string `json:"metadata"`
Endpoints []string `json:"endpoints"`
}
Unique instance ID as registered
Service name as registered
Version of the compiled service
Key-value pair metadata associated with the service instance
Endpoint addresses of the service instance.
Schema examples:
http://127.0.0.1:8000?isSecure=false
grpc://127.0.0.1:9000?isSecure=false
Methods:
func (i *ServiceInstance) String() string
func (i *ServiceInstance) Equal(o any) bool
Usage Examples
Registering a Service
package main
import (
"context"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/registry"
)
func main() {
// Create registrar (e.g., Consul, Etcd, Nacos)
r := consul.New(consulClient)
app := kratos.New(
kratos.ID("service-001"),
kratos.Name("user-service"),
kratos.Version("v1.0.0"),
kratos.Metadata(map[string]string{
"region": "us-west",
"zone": "zone-a",
}),
kratos.Server(httpSrv, grpcSrv),
kratos.Registrar(r),
)
if err := app.Run(); err != nil {
panic(err)
}
}
Service Discovery
package main
import (
"context"
"fmt"
"github.com/go-kratos/kratos/v2/registry"
)
func discoverService(discovery registry.Discovery, serviceName string) {
ctx := context.Background()
// Get service instances
instances, err := discovery.GetService(ctx, serviceName)
if err != nil {
panic(err)
}
for _, inst := range instances {
fmt.Printf("Found instance: %s\n", inst.ID)
fmt.Printf(" Name: %s\n", inst.Name)
fmt.Printf(" Version: %s\n", inst.Version)
fmt.Printf(" Endpoints: %v\n", inst.Endpoints)
fmt.Printf(" Metadata: %v\n", inst.Metadata)
}
}
Watching Service Changes
func watchService(discovery registry.Discovery, serviceName string) {
ctx := context.Background()
watcher, err := discovery.Watch(ctx, serviceName)
if err != nil {
panic(err)
}
defer watcher.Stop()
for {
instances, err := watcher.Next()
if err != nil {
fmt.Printf("Watch error: %v\n", err)
return
}
fmt.Printf("Service %s updated: %d instances\n", serviceName, len(instances))
for _, inst := range instances {
fmt.Printf(" - %s: %v\n", inst.ID, inst.Endpoints)
}
}
}
Custom Service Instance
func createServiceInstance() *registry.ServiceInstance {
return ®istry.ServiceInstance{
ID: "user-service-001",
Name: "user-service",
Version: "v1.0.0",
Metadata: map[string]string{
"region": "us-west",
"zone": "zone-a",
"weight": "100",
"protocol": "grpc",
"namespace": "production",
},
Endpoints: []string{
"grpc://192.168.1.10:9000?isSecure=false",
"http://192.168.1.10:8000?isSecure=false",
},
}
}
Service Instance Comparison
func compareInstances(inst1, inst2 *registry.ServiceInstance) {
if inst1.Equal(inst2) {
fmt.Println("Instances are equal")
} else {
fmt.Println("Instances differ")
}
// String representation
fmt.Printf("Instance: %s\n", inst1.String()) // Output: user-service-001
}
Integration with gRPC Client
import (
"github.com/go-kratos/kratos/v2/transport/grpc"
"github.com/go-kratos/kratos/v2/registry"
)
func newGRPCClient(discovery registry.Discovery) {
conn, err := grpc.DialInsecure(
context.Background(),
grpc.WithEndpoint("discovery:///user-service"),
grpc.WithDiscovery(discovery),
)
if err != nil {
panic(err)
}
defer conn.Close()
// Use connection
client := pb.NewUserServiceClient(conn)
}
func registerWithHealthCheck(r registry.Registrar) {
instance := ®istry.ServiceInstance{
ID: "service-001",
Name: "user-service",
Version: "v1.0.0",
Metadata: map[string]string{
"health_check_path": "/health",
"health_check_interval": "10s",
"health_check_timeout": "3s",
},
Endpoints: []string{
"http://127.0.0.1:8000",
},
}
ctx := context.Background()
if err := r.Register(ctx, instance); err != nil {
panic(err)
}
}
Registry Implementations
Kratos supports various service registry implementations:
- Consul:
github.com/go-kratos/kratos/contrib/registry/consul/v2
- Etcd:
github.com/go-kratos/kratos/contrib/registry/etcd/v2
- Nacos:
github.com/go-kratos/kratos/contrib/registry/nacos/v2
- Kubernetes:
github.com/go-kratos/kratos/contrib/registry/kubernetes/v2
- Eureka:
github.com/go-kratos/kratos/contrib/registry/eureka/v2
- Zookeeper:
github.com/go-kratos/kratos/contrib/registry/zookeeper/v2
- Polaris:
github.com/go-kratos/kratos/contrib/registry/polaris/v2
Example with Consul:
import (
consulAPI "github.com/hashicorp/consul/api"
"github.com/go-kratos/kratos/contrib/registry/consul/v2"
)
// Create Consul client
config := consulAPI.DefaultConfig()
config.Address = "127.0.0.1:8500"
client, err := consulAPI.NewClient(config)
if err != nil {
panic(err)
}
// Create registry
r := consul.New(client)
// Use with Kratos app
app := kratos.New(
kratos.Name("user-service"),
kratos.Registrar(r),
)