Shows how to connect Hashicorp's memberlist to Golang's groupcache for dynamic cluster membership.
Memberlist gossip can be encrypted by setting the SecretKey
or Keyring
attributes on cfg
.
Last active
January 26, 2021 03:46
-
-
Save mjpitz/7c1f15f1ee0ef1804b662e91a6e1d042 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"github.com/golang/groupcache" | |
"github.com/hashicorp/memberlist" | |
"log" | |
"net" | |
"net/http" | |
"time" | |
) | |
func main() { | |
mux := http.DefaultServeMux | |
port := "8080" | |
httpAddress := func(ip string) string { | |
return net.JoinHostPort(ip, port) | |
} | |
// sets up UDP/TCP server on 0.0.0.0:7946 | |
cfg := memberlist.DefaultLocalConfig() | |
list, err := memberlist.Create(cfg) | |
if err != nil { | |
log.Fatal("cannot start memberlist servers", err) | |
} | |
// join existing members | |
_, err = list.Join([]string{"discovery.address"}) | |
if err != nil { | |
log.Fatal("cannot join memberlist server", err) | |
} | |
self := httpAddress(list.LocalNode().Addr.String()) | |
opts := &groupcache.HTTPPoolOptions{BasePath: "/_groupcache/"} | |
pool := groupcache.NewHTTPPoolOpts(self, opts) | |
mux.Handle(opts.BasePath, pool) | |
// setup background worker | |
go func() { | |
for { | |
// update groupcache peers based on memberlist every 5 seconds | |
<- time.Tick(5 * time.Second) | |
members := list.Members() | |
peers := make([]string, 0, len(members)) | |
for _, member := range members { | |
peer := httpAddress(member.Addr.String()) | |
if peer != self { | |
peers = append(peers, self) | |
} | |
} | |
pool.Set(peers...) | |
} | |
}() | |
// cache of 64MB | |
group := groupcache.NewGroup("name", 64 << 20, groupcache.GetterFunc( | |
func(ctx context.Context, key string, dest Sink) error { | |
// cache miss | |
// dest.SetString(str) | |
// dest.SetProto(msg) | |
return nil | |
} | |
)) | |
// err := group.Get(ctx, "key", groupcache.StringSink(&str)) | |
// err := group.Get(ctx, "key", groupcache.ProtoSink(msg)) | |
// sets up HTTP server on 0.0.0.0:8080 | |
if err := http.ListenAndServe(httpAddress("0.0.0.0"), mux); err != nil { | |
log.Fatal("cannot start http server", err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment