Codebase list golang-github-go-kit-kit / 88bbb61
Updates, cleanup, and replace example Peter Bourgon 7 years ago
4 changed file(s) with 98 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
4848 ctx context.Context
4949 }
5050
51 // ClientOptions defines options for the etcd client.
51 // ClientOptions defines options for the etcd client. All values are optional.
52 // If any duration is not specified, a default of 3 seconds will be used.
5253 type ClientOptions struct {
5354 Cert string
5455 Key string
5859 HeaderTimeoutPerRequest time.Duration
5960 }
6061
61 // NewClient returns an *etcd.Client with a connection to the named machines.
62 // It will return an error if a connection to the cluster cannot be made.
63 // The parameter machines needs to be a full URL with schemas.
64 // e.g. "http://localhost:2379" will work, but "localhost:2379" will not.
62 // NewClient returns Client with a connection to the named machines. It will
63 // return an error if a connection to the cluster cannot be made. The parameter
64 // machines needs to be a full URL with schemas. e.g. "http://localhost:2379"
65 // will work, but "localhost:2379" will not.
6566 func NewClient(ctx context.Context, machines []string, options ClientOptions) (Client, error) {
67 if options.DialTimeout == 0 {
68 options.DialTimeout = 3 * time.Second
69 }
70 if options.DialKeepAlive == 0 {
71 options.DialKeepAlive = 3 * time.Second
72 }
73 if options.HeaderTimeoutPerRequest == 0 {
74 options.HeaderTimeoutPerRequest = 3 * time.Second
75 }
76
6677 transport := etcd.DefaultTransport
6778 if options.Cert != "" && options.Key != "" {
6879 tlsCert, err := tls.LoadX509KeyPair(options.Cert, options.Key)
0 // Package etcd provides a subscriber implementation for etcd.
0 // Package etcd provides a Subscriber and Registrar implementation for etcd. If
1 // you use etcd as your service discovery system, this package will help you
2 // implement the registration and client-side load balancing patterns.
13 package etcd
0 package etcd
1
2 import (
3 "io"
4 "time"
5
6 "golang.org/x/net/context"
7
8 "github.com/go-kit/kit/endpoint"
9 "github.com/go-kit/kit/log"
10 "github.com/go-kit/kit/sd/lb"
11 )
12
13 func Example() {
14 // Let's say this is a service that means to register itself.
15 // First, we will set up some context.
16 var (
17 etcdServer = "http://10.0.0.1:2379" // don't forget schema and port!
18 prefix = "/services/foosvc/" // known at compile time
19 instance = "1.2.3.4:8080" // taken from runtime or platform, somehow
20 key = prefix + instance // should be globally unique
21 value = "http://" + instance // based on our transport
22 ctx = context.Background()
23 )
24
25 // Build the client.
26 client, err := NewClient(ctx, []string{etcdServer}, ClientOptions{})
27 if err != nil {
28 panic(err)
29 }
30
31 // Build the registrar.
32 registrar := NewRegistrar(client, Service{
33 Key: key,
34 Value: value,
35 }, log.NewNopLogger())
36
37 // Register our instance.
38 registrar.Register()
39
40 // At the end of our service lifecycle, for example at the end of func main,
41 // we should make sure to deregister ourselves. This is important! Don't
42 // accidentally skip this step by invoking a log.Fatal or os.Exit in the
43 // interim, which bypasses the defer stack.
44 defer registrar.Deregister()
45
46 // It's likely that we'll also want to connect to other services and call
47 // their methods. We can build a subscriber to listen for changes from etcd
48 // and build endpoints, wrap it with a load-balancer to pick a single
49 // endpoint, and finally wrap it with a retry strategy to get something that
50 // can be used as an endpoint directly.
51 barPrefix := "/services/barsvc"
52 subscriber, err := NewSubscriber(client, barPrefix, barFactory, log.NewNopLogger())
53 if err != nil {
54 panic(err)
55 }
56 balancer := lb.NewRoundRobin(subscriber)
57 retry := lb.Retry(3, 3*time.Second, balancer)
58
59 // And now retry can be used like any other endpoint.
60 req := struct{}{}
61 if _, err = retry(ctx, req); err != nil {
62 panic(err)
63 }
64 }
65
66 func barFactory(string) (endpoint.Endpoint, io.Closer, error) { return endpoint.Nop, nil, nil }
11
22 import (
33 etcd "github.com/coreos/etcd/client"
4
45 "github.com/go-kit/kit/log"
56 )
67
1112 logger log.Logger
1213 }
1314
14 // Service holds the key, value and instance identifying data you
15 // want to publish to etcd.
15 // Service holds the instance identifying data you want to publish to etcd. Key
16 // must be unique, and value is the string returned to subscribers, typically
17 // called the "instance" string in other parts of package sd.
1618 type Service struct {
17 Key string // discovery key, example: /myorganization/myplatform/
18 Value string // service name value, example: addsvc
19 Key string // unique key, e.g. "/service/foobar/1.2.3.4:8080"
20 Value string // returned to subscribers, e.g. "http://1.2.3.4:8080"
1921 DeleteOptions *etcd.DeleteOptions
2022 }
2123
2224 // NewRegistrar returns a etcd Registrar acting on the provided catalog
23 // registration.
25 // registration (service).
2426 func NewRegistrar(client Client, service Service, logger log.Logger) *Registrar {
2527 return &Registrar{
2628 client: client,
2729 service: service,
2830 logger: log.NewContext(logger).With(
31 "key", service.Key,
2932 "value", service.Value,
30 "key", service.Key,
3133 ),
3234 }
3335 }
3436
35 // Register implements sd.Registrar interface.
37 // Register implements the sd.Registrar interface. Call it when you want your
38 // service to be registered in etcd, typically at startup.
3639 func (r *Registrar) Register() {
3740 if err := r.client.Register(r.service); err != nil {
3841 r.logger.Log("err", err)
4144 }
4245 }
4346
44 // Deregister implements sd.Registrar interface.
47 // Deregister implements the sd.Registrar interface. Call it when you want your
48 // service to be deregistered from etcd, typically just prior to shutdown.
4549 func (r *Registrar) Deregister() {
4650 if err := r.client.Deregister(r.service); err != nil {
4751 r.logger.Log("err", err)