As more and more of our services, if the service is configured with resilient and elastic, or when the service is not available, we need to keep moving to grasp the number of services that can be used, and can provide a response service sends a request. Then we need to service discovery, when the new service, the service can automatically register with the consul, the client sends a request directly to the consul, get the address and port available services; when the service is not available, the dynamic update consul, remove the service in the list of consul
docker installation consul
- docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul:latest agent -server -bootstrap-expect 2 -ui -bind=0.0.0.0 -client=0.0.0.0
- 8500 http port for http interface and the web ui
- Through communication between the port 8300 server rpc port, the same data center consul server
- 8301 serf lan port, the same data center consul client via the communication port
- 8302 serf wan ports, different data centers consul server through the communication port
- 8600 dns port for service discovery
- -bbostrap-expect 2: a cluster of at least two servers to the cluster leader election
- -ui: run the web console
- -bind: listening network port, 0.0.0.0 represents all Ethernet ports, if you do not specify a default is not 127.0.0.1, and the container can not communicate
- -client: restrict access to certain network ports
- docker run --name consul2 -d -p 8501:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2
- docker run --name consul2 -d -p 8502:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2
consul_server.go
package main import ( "fmt" "log" "net" "net/http" _ "net/http/pprof" consulapi "github.com/hashicorp/consul/api" ) var count int64 // consul 服务端会自己发送请求,来进行健康检查 func consulCheck(w http.ResponseWriter, r *http.Request) { s := "consulCheck" + fmt.Sprint(count) + "remote:" + r.RemoteAddr + " " + r.URL.String() fmt.Println(s) fmt.Fprintln(w, s) count++ } func registerServer() { config := consulapi.DefaultConfig() config.Address = "10.0.0.10:8500" Client, ERR: = consulapi.NewClient (config) IF ! ERR = nil { log.Fatal ( "error Consul Client:" , ERR) } Registration: = new new (consulapi.AgentServiceRegistration ) registration.ID = "serverNode_1" // name of the service node registration.Name = "ServerNode" // service name registration.Port = 9527 // service port registration.Tags = [] {String "V1000"} // Tag, It can be empty registration. Address = localIP() // service the IP checkPort: = 8080 registration.Check = & consulapi.AgentServiceCheck { // health check HTTP: fmt.Sprintf ( "http: // % s:% d% s", registration.Address, checkPort, "/ check" ), Timeout: "3S" , interval: "5S", // health check interval DeregisterCriticalServiceAfter: "30s", // 30-sec after the failure of this check services, write-off time, the expiration time equivalent // GRPC: fmt.Sprintf ( "% v:% v / v%", IP, r.Port, r.Service), // GRPC support, address the implementation of the health check, service will be transmitted health.Check function } ERR = client.Agent().ServiceRegister(registration) if err != nil { log.Fatal("register server error : ", err) } http.HandleFunc("/check", consulCheck) http.ListenAndServe(fmt.Sprintf(":%d", checkPort), nil) } func localIP() string { addrs, err := net.InterfaceAddrs() if err != nil { return "" } for _, address := range addrs { if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { return ipnet.IP.String() } } } return "" } func main() { registerServer() }
consul_client.go
package main import ( "fmt" "net" "strconv" "github.com/Sirupsen/logrus" "github.com/hashicorp/consul/api" ) func main() { var lastIndex uint64 config := api.DefaultConfig() config.Address = "10.0.0.10:8500" //consul server client, err := api.NewClient(config) if err != nil { fmt.Println("api new client is failed, err:", err) return } services, metainfo, err :. = Client.Health () Service ( "ServerNode", "V1000", to true , & api.QueryOptions { WaitIndex: lastIndex, // synchronization point, the call will block until there is a new update }) IF ERR =! {nil logrus.Warn ( "Retrieving instances from Consul error:% V" , ERR) } the lastIndex = metainfo.LastIndex addrs: = Map [String] struct {} {} for _,-Service: = Range Services { fmt.Println ( "service.Service.Address:", service.Service.Address, " service.Service.Port:" , service.Service.Port) addrs[net.JoinHostPort(service.Service.Address, strconv.Itoa(service.Service.Port))] = struct{}{} } }
go run ./consul_server.go
Enter in your browser http: // localhost: 8500 / ui / dc1 / services to see registration
Execution go run consul_client.go to obtain the IP address of the server and registered