In one terminal:
PORT=7777 go run main.go
In a separate terminal:
PORT=7778 JOIN=localhost:7777 go run main.go
Repeat as desired with additional ports, JOIN can point to one or more (comma-separated) existing nodes
| module github.com/tjcelaya/serfin | |
| go 1.13 | |
| require ( | |
| github.com/hashicorp/serf v0.8.5 | |
| github.com/omeid/uconfig v0.0.0-20191124031631-f52a35b0fc4f | |
| ) |
| package main | |
| import ( | |
| "fmt" | |
| "log" | |
| "os" | |
| "os/signal" | |
| "strings" | |
| "github.com/hashicorp/serf/serf" | |
| "github.com/omeid/uconfig" | |
| ) | |
| func main() { | |
| cfg := struct { | |
| // Join is a comma-seperated list of endpoints (host:port) to join. | |
| // First node in a cluster can specify no nodes to join | |
| Join string `env:"JOIN" default:""` | |
| Addr string `env:"ADDR" default:"127.0.0.1"` | |
| Port int `env:"PORT" default:"7777"` | |
| } | |
| if c, err := uconfig.Classic(&cfg, nil); err != nil { | |
| c.Usage() | |
| os.Exit(1) | |
| } | |
| c := serf.DefaultConfig() | |
| c.NodeName = fmt.Sprintf("%s:%d", cfg.Addr, cfg.Port) | |
| c.MemberlistConfig.BindAddr = cfg.Addr | |
| c.MemberlistConfig.BindPort = cfg.Port | |
| s, err := serf.Create(c) | |
| if err != nil { | |
| log.Fatalf("Failed to start serf: %v", err) | |
| } | |
| if cfg.Join == ""; { | |
| log.Printf("No existing nodes to join, we are first in the cluster") | |
| } else { | |
| joining := strings.Split(cfg.Join, ",") | |
| log.Printf("Attempting to join %d existing nodes: %v", len(joining), joining) | |
| if reached, err := s.Join(joining, true); err != nil { | |
| log.Fatalf("Failed to join cluster: %+v", err) | |
| } else { | |
| log.Printf("Joined %v (reached %d)", cfg.Join, reached) | |
| } | |
| } | |
| // block on SIGINT / Ctrl + C | |
| quit := make(chan os.Signal, 1) | |
| signal.Notify(quit, os.Interrupt) | |
| <-quit | |
| if err := s.Leave(); err != nil { | |
| log.Fatalf("Failed to leave gracefully: %v", err) | |
| } | |
| finish := s.ShutdownCh() | |
| if err := s.Shutdown(); err != nil { | |
| log.Fatalf("Failed to shutdown gracefully: %v", err) | |
| } | |
| <-finish | |
| log.Printf("Finished shutdown, goodbye") | |
| } |