8 "github.com/go-kit/kit/endpoint"
9 "github.com/go-kit/kit/log"
10 "github.com/go-kit/kit/sd"
11 "github.com/go-kit/kit/sd/lb"
15 // Let's say this is a service that means to register itself.
16 // First, we will set up some context.
18 etcdServer = "http://10.0.0.1:2379" // don't forget schema and port!
19 prefix = "/services/foosvc/" // known at compile time
20 instance = "1.2.3.4:8080" // taken from runtime or platform, somehow
21 key = prefix + instance // should be globally unique
22 value = "http://" + instance // based on our transport
23 ctx = context.Background()
27 client, err := NewClient(ctx, []string{etcdServer}, ClientOptions{})
32 // Build the registrar.
33 registrar := NewRegistrar(client, Service{
36 }, log.NewNopLogger())
38 // Register our instance.
41 // At the end of our service lifecycle, for example at the end of func main,
42 // we should make sure to deregister ourselves. This is important! Don't
43 // accidentally skip this step by invoking a log.Fatal or os.Exit in the
44 // interim, which bypasses the defer stack.
45 defer registrar.Deregister()
47 // It's likely that we'll also want to connect to other services and call
48 // their methods. We can build an Instancer to listen for changes from etcd,
49 // create Endpointer, wrap it with a load-balancer to pick a single
50 // endpoint, and finally wrap it with a retry strategy to get something that
51 // can be used as an endpoint directly.
52 barPrefix := "/services/barsvc"
53 logger := log.NewNopLogger()
54 instancer, err := NewInstancer(client, barPrefix, logger)
58 endpointer := sd.NewEndpointer(instancer, barFactory, logger)
59 balancer := lb.NewRoundRobin(endpointer)
60 retry := lb.Retry(3, 3*time.Second, balancer)
62 // And now retry can be used like any other endpoint.
64 if _, err = retry(ctx, req); err != nil {
69 func barFactory(string) (endpoint.Endpoint, io.Closer, error) { return endpoint.Nop, nil, nil }