In the microservices architecture, each small service is composed of a number of nodes, the addition of nodes to remove the failure to be transparent downstream, it is necessary to introduce a service automatic registration and discovery mechanism, and Consul provides a complete solution, and built-in support for GRPC and HTTP services
Overall architecture
- Service Invocation: Client Direct Connect Server call service
- Service registration: The server registers the service information in the consul
- Service discovery: The client discovers service information from Consul, mainly the address of the service
- Health Check: Consul check the health status of the server
Service Registration
The server registers the service information in the consul, which can be completed when the service is started and service is available.
Complete code reference: https://github.com/hatlonely/...
Config: = API. Defaultconfig () config. Address = r.addressclient, err: = API. Newclient (config) if err! = Nil {panic (err)}agent: = client. Agent () IP: = Localip () Reg: = &api. agentserviceregistration{id:fmt. Sprintf ("%v-%v-%v", R.service, IP, R.port),//Service node name NAME:FMT. Sprintf ("Grpc.health.v1.%v", R.service),//service name Tags:r.tag,//Tag , can be an empty port:r.port,//service port ADDRESS:IP, Service IP Check: &api. agentservicecheck{//Health Check interval:r.interval.string (),//Health check interval//GRPC support, address for performing health check, service will be passed to grpc:fmt in the Health.check function. Sprintf ("%v:%v/%v", IP, R.port, R.service), DEREGISTERCRITICALSERVICEAFTER:R.DEREGISTERCRITICALSERVICEAFTER.S Tring (),//Logoff time, equivalent to expiry time},}if err: = Agent. Serviceregister (REG); Err! = Nil {panic (err)}
Service discovery
The client discovers the service information from the consul, mainly the address of the service
Complete code reference: https://github.com/hatlonely/...
services, metainfo, err := w.client.Health().Service(w.service, "", true, &api.QueryOptions{ WaitIndex: w.lastIndex, // 同步点,这个调用将一直阻塞,直到有新的更新})if err != nil { logrus.Warn("error retrieving instances from Consul: %v", err)}w.lastIndex = metainfo.LastIndexaddrs := map[string]struct{}{}for _, service := range services { addrs[net.JoinHostPort(service.Service.Address, strconv.Itoa(service.Service.Port))] = struct{}{}}
Health Check
Consul check the health status of the server, consul with the google.golang.org/grpc/health/grpc_health_v1.HealthServer
interface, to achieve the GRPC health check support, so we only need to implement this interface, Consul can use this interface for health check
Complete code reference: https://github.com/hatlonely/...
// HealthImpl 健康检查实现type HealthImpl struct{}// Check 实现健康检查接口,这里直接返回健康状态,这里也可以有更复杂的健康检查策略,比如根据服务器负载来返回func (h *HealthImpl) Check(ctx context.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error) { return &grpc_health_v1.HealthCheckResponse{ Status: grpc_health_v1.HealthCheckResponse_SERVING, }, nil}grpc_health_v1.RegisterHealthServer(server, &HealthImpl{})
Reference links
- Complete Engineering Code: https://github.com/hatlonely/...
- Consul Health Check Api:https://www.consul.io/api/age ...
- Consul Service Registration Api:https://www.consul.io/api/age ...
- GRPC Health Check: https://github.com/grpc/grpc/...
Reprint please indicate the source
This article link: http://www.hatlonely.com/2018 ...