Documentation Index Fetch the complete documentation index at: https://mintlify.com/go-kratos/kratos/llms.txt
Use this file to discover all available pages before exploring further.
Kratos provides a flexible service discovery system that supports multiple registries including Consul, etcd, Nacos, and Kubernetes.
Overview
Service discovery in Kratos includes:
Service registration on startup
Automatic deregistration on shutdown
Health checks and heartbeats
Client-side load balancing
Multiple discovery backends
Registry Interface
Kratos defines standard interfaces for service registration and discovery:
package registry
// Registrar is service registrar.
type Registrar interface {
// Register the registration.
Register ( ctx context . Context , service * ServiceInstance ) error
// Deregister the registration.
Deregister ( ctx context . Context , service * ServiceInstance ) error
}
// Discovery is service discovery.
type Discovery interface {
// GetService return the service instances in memory according to the service name.
GetService ( ctx context . Context , serviceName string ) ([] * ServiceInstance , error )
// Watch creates a watcher according to the service name.
Watch ( ctx context . Context , serviceName string ) ( Watcher , error )
}
// ServiceInstance is an instance of a service in a discovery system.
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"`
}
Using Consul
Install the Kratos Consul integration:
go get github.com/go-kratos/kratos/contrib/registry/consul/v2
Set up Consul as your service registry:
package server
import (
" github.com/go-kratos/kratos/contrib/registry/consul/v2 "
" github.com/go-kratos/kratos/v2/registry "
consulAPI " github.com/hashicorp/consul/api "
)
func NewRegistrar ( conf * conf . Registry ) registry . Registrar {
// Create Consul client
c := consulAPI . DefaultConfig ()
c . Address = conf . Consul . Address
c . Scheme = conf . Consul . Scheme
cli , err := consulAPI . NewClient ( c )
if err != nil {
panic ( err )
}
// Create Consul registry
r := consul . New ( cli )
return r
}
Register Service on Startup
Register your service when the application starts:
package main
import (
" github.com/go-kratos/kratos/v2 "
" github.com/go-kratos/kratos/v2/registry "
" github.com/go-kratos/kratos/v2/transport/http "
" github.com/go-kratos/kratos/v2/transport/grpc "
)
func newApp ( logger log . Logger , hs * http . Server , gs * grpc . Server , r registry . Registrar ) * kratos . App {
return kratos . New (
kratos . Name ( "user.service" ),
kratos . Version ( "v1.0.0" ),
kratos . Metadata ( map [ string ] string {
"region" : "us-west" ,
"zone" : "zone-a" ,
}),
kratos . Logger ( logger ),
kratos . Server ( hs , gs ),
kratos . Registrar ( r ),
)
}
Discover and connect to other services:
package data
import (
" context "
" time "
" github.com/go-kratos/kratos/contrib/registry/consul/v2 "
" github.com/go-kratos/kratos/v2/transport/grpc "
consulAPI " github.com/hashicorp/consul/api "
)
func NewOrderServiceClient ( conf * conf . Data ) ( orderv1 . OrderClient , error ) {
// Create Consul client
c := consulAPI . DefaultConfig ()
c . Address = conf . Consul . Address
cli , err := consulAPI . NewClient ( c )
if err != nil {
return nil , err
}
// Create service discovery
r := consul . New ( cli )
// Connect with service discovery
conn , err := grpc . DialInsecure (
context . Background (),
grpc . WithEndpoint ( "discovery:///order.service" ),
grpc . WithDiscovery ( r ),
grpc . WithTimeout ( 5 * time . Second ),
)
if err != nil {
return nil , err
}
return orderv1 . NewOrderClient ( conn ), nil
}
Using Etcd
Install Etcd Client
go get github.com/go-kratos/kratos/contrib/registry/etcd/v2
import (
" github.com/go-kratos/kratos/contrib/registry/etcd/v2 "
clientv3 " go.etcd.io/etcd/client/v3 "
)
func NewRegistrar ( conf * conf . Registry ) registry . Registrar {
// Create etcd client
client , err := clientv3 . New ( clientv3 . Config {
Endpoints : [] string { conf . Etcd . Address },
})
if err != nil {
panic ( err )
}
// Create etcd registry
r := etcd . New ( client )
return r
}
Using Nacos
Install Nacos Client
go get github.com/go-kratos/kratos/contrib/registry/nacos/v2
import (
" github.com/go-kratos/kratos/contrib/registry/nacos/v2 "
" github.com/nacos-group/nacos-sdk-go/clients "
" github.com/nacos-group/nacos-sdk-go/common/constant "
" github.com/nacos-group/nacos-sdk-go/vo "
)
func NewRegistrar ( conf * conf . Registry ) registry . Registrar {
sc := [] constant . ServerConfig {
* constant . NewServerConfig ( conf . Nacos . Address , conf . Nacos . Port ),
}
cc := constant . ClientConfig {
NamespaceId : conf . Nacos . NamespaceId ,
TimeoutMs : 5000 ,
NotLoadCacheAtStart : true ,
}
client , err := clients . NewNamingClient (
vo . NacosClientParam {
ClientConfig : & cc ,
ServerConfigs : sc ,
},
)
if err != nil {
panic ( err )
}
r := nacos . New ( client )
return r
}
Kubernetes Service Discovery
Using Kubernetes DNS
Leverage Kubernetes built-in service discovery:
// Direct service connection via Kubernetes DNS
conn , err := grpc . DialInsecure (
context . Background (),
grpc . WithEndpoint ( "order-service.default.svc.cluster.local:9000" ),
)
Using Kubernetes API
go get github.com/go-kratos/kratos/contrib/registry/kubernetes/v2
import (
" github.com/go-kratos/kratos/contrib/registry/kubernetes/v2 "
" k8s.io/client-go/kubernetes "
" k8s.io/client-go/rest "
)
func NewRegistrar () registry . Registrar {
// Create in-cluster config
config , err := rest . InClusterConfig ()
if err != nil {
panic ( err )
}
// Create clientset
clientset , err := kubernetes . NewForConfig ( config )
if err != nil {
panic ( err )
}
// Create registry
r := kubernetes . NewRegistry ( clientset )
return r
}
Load Balancing
Built-in Load Balancing Strategies
Kratos supports multiple load balancing algorithms:
import (
" github.com/go-kratos/kratos/v2/selector "
" github.com/go-kratos/kratos/v2/selector/wrr "
" github.com/go-kratos/kratos/v2/selector/p2c "
" github.com/go-kratos/kratos/v2/selector/random "
)
// Weighted Round Robin
conn , err := grpc . DialInsecure (
context . Background (),
grpc . WithEndpoint ( "discovery:///order.service" ),
grpc . WithDiscovery ( r ),
grpc . WithSelector ( wrr . NewBuilder ()),
)
// Power of Two Choices (P2C)
conn , err := grpc . DialInsecure (
context . Background (),
grpc . WithEndpoint ( "discovery:///order.service" ),
grpc . WithDiscovery ( r ),
grpc . WithSelector ( p2c . NewBuilder ()),
)
// Random
conn , err := grpc . DialInsecure (
context . Background (),
grpc . WithEndpoint ( "discovery:///order.service" ),
grpc . WithDiscovery ( r ),
grpc . WithSelector ( random . NewBuilder ()),
)
Custom Load Balancing
Implement custom load balancing logic:
type CustomSelector struct {}
func ( s * CustomSelector ) Select ( ctx context . Context , nodes [] selector . Node ) ( selector . Node , selector . DoneFunc , error ) {
// Custom selection logic
node := nodes [ 0 ] // Select first node
done := func ( ctx context . Context , di selector . DoneInfo ) {
// Called after request completes
if di . Err != nil {
// Handle error
}
}
return node , done , nil
}
Include metadata with service registration:
app := kratos . New (
kratos . Name ( "user.service" ),
kratos . Version ( "v1.0.0" ),
kratos . Metadata ( map [ string ] string {
"region" : "us-west-2" ,
"zone" : "zone-a" ,
"environment" : "production" ,
"team" : "platform" ,
}),
kratos . Registrar ( r ),
)
Filter service instances by metadata:
import " github.com/go-kratos/kratos/v2/selector/filter "
// Filter by region
conn , err := grpc . DialInsecure (
context . Background (),
grpc . WithEndpoint ( "discovery:///user.service" ),
grpc . WithDiscovery ( r ),
grpc . WithNodeFilter ( filter . Version ( "v1.0.0" )),
)
Health Checks
HTTP Health Endpoint
Implement health check endpoints:
func NewHTTPServer ( c * conf . Server ) * http . Server {
srv := http . NewServer (
http . Address ( c . HTTP . Addr ),
)
// Health check endpoint
srv . HandleFunc ( "/health" , func ( ctx http . Context ) error {
return ctx . String ( 200 , "OK" )
})
return srv
}
Consul Health Checks
Configure Consul health checks:
import " github.com/go-kratos/kratos/contrib/registry/consul/v2 "
r := consul . New ( cli ,
consul . WithHealthCheck ( true ),
consul . WithHealthCheckInterval ( 10 ), // Check every 10 seconds
)
Best Practices
Service Names Use consistent, descriptive service names across your infrastructure
Health Checks Always implement proper health check endpoints
Graceful Shutdown Deregister services gracefully on shutdown
Metadata Use metadata for routing, versioning, and feature flags
Complete Example
internal/server/registrar.go
package server
import (
" github.com/go-kratos/kratos/contrib/registry/consul/v2 "
" github.com/go-kratos/kratos/v2/registry "
consulAPI " github.com/hashicorp/consul/api "
" yourproject/internal/conf "
)
func NewRegistrar ( c * conf . Registry ) registry . Registrar {
cfg := consulAPI . DefaultConfig ()
cfg . Address = c . Consul . Address
cfg . Scheme = c . Consul . Scheme
cli , err := consulAPI . NewClient ( cfg )
if err != nil {
panic ( err )
}
return consul . New ( cli ,
consul . WithHealthCheck ( true ),
consul . WithHealthCheckInterval ( 10 ),
)
}
func NewDiscovery ( c * conf . Registry ) registry . Discovery {
cfg := consulAPI . DefaultConfig ()
cfg . Address = c . Consul . Address
cfg . Scheme = c . Consul . Scheme
cli , err := consulAPI . NewClient ( cfg )
if err != nil {
panic ( err )
}
return consul . New ( cli )
}
Next Steps
Configuration Configure your registry settings
Deployment Deploy with service discovery enabled