Through the service discovery and registry, it is easy to manage the dynamic service instance information in the system. At the same time, it may also become the bottleneck and failure point of the system. Because the information for invocations between services comes from the service registry and discovery center, invocations between services may not work properly when it is unavailable. Therefore, service discovery and registries tend to be multi-instance deployments, providing high availability and stability.
We will implement service registration and discovery for Golang Web based on Consul. We will first interact with Consul via HTTP in a native way. We will then interact with Consul through the Consul Client interface provided by the Go Kit framework and compare the differences between them.
In the previous article, we learned about the complete ConsulClient architecture of microservices, and we’ll start writing an implementation of the core ConsulClient interface to complete the simple process of registering and discovering services between Consul and microservices.
Service instance interacts with Consul
In this section, we will directly interact with Consul via HTTP to complete service registration and service discovery functions. We first define the service registration service instance structure of diy. InstanceInfo, source located at ch7 – discovery/diy/MyConsulClient. Go. The code looks like this:
// Service instance structure
type InstanceInfo struct {
ID string `json:"ID"` // Service instance ID
Name string `json:"Name"` / / service name
Service string `json:"Service,omitempty"` // The name of the service returned when the service is discovered
Tags []string `json:"Tags,omitempty"` // tag that can be used for service filtering
Address string `json:"Address"` // Service instance HOST
Port int `json:"Port"` // Service instance port
Meta map[string]string `json:"Meta,omitempty"` / / metadata
EnableTagOverride bool `json:"EnableTagOverride"` // Whether to allow label overwriting
Check `json:"Check,omitempty"` // Health check configurations
Weights `json:"Weights,omitempty"` / / weight
}
type Check struct {
DeregisterCriticalServiceAfter string `json:"DeregisterCriticalServiceAfter"` // How long will it take to unregister the service
Args []string `json:"Args,omitempty"` // Request parameters
HTTP string `json:"HTTP"` // Health check address
Interval string `json:"Interval,omitempty"` Consul took the initiative to conduct a health check
TTL string `json:"TTL,omitempty"` // The service instance voluntarily submits a health check
}
type Weights struct {
Passing int `json:"Passing"`
Warning int `json:"Warning"`
}
Copy the code
The service instance information submitted to Consul includes:
- Service instance ID, which uniquely identifies the service instance
- The service name is the service cluster to which the service instance belongs
- Address, Port, service Address and Port for initiating inter-service calls
- Check: Health Check information, including the health Check address and interval.
Consul allows Consul to proactively invoke the health check interface provided by a service instance to maintain heartbeat communication, and a service instance to proactively submit health check data to Consul to maintain heartbeat communication. The Interval and TTL parameters in Check are used to set the Check Interval respectively. Only one of them can be set. Our microservice is proactive and provides a /health interface checked by Consul call.
. Then we define diy ConsulClint the creation of a structure and its function, which is located in ch7 – discovery/diy/MyConsulClient. Go, the code is as follows:
Type ConsulClient struct {Host Port int // Consul Port int // Consul Port} consulPort int) *ConsulClient { return &ConsulClient{ Host: consulHost, Port: consulPort, } }Copy the code
Consul to get a DIY.ConsulClient you need to pass Consul’s exact address, that is, Host and Port.
After we at ch7 – discovery/diy/MyConsulClient. Go down the implementation ch7 – discovery/ConsulClient interface, and the receiver at the specified method diy. ConsulClient, empty method code is as follows:
func (consulClient *ConsulClient) Register(serviceName, instanceId, healthCheckUrl string, instancePort int, meta map[string]string, logger *log.Logger) bool{
return false
}
func (consulClient *ConsulClient) DeRegister(instanceId string, logger *log.Logger) bool {
return false
}
func (consulClient *ConsulClient) DiscoverServices(serviceName string) []interface{} {return nil
}
Copy the code
Service registration and health check
We first implement the function of a service Register, which implements the Register interface and specifies the method receiver as D.I.Y. ConsulClient. Source is located at ch7 – discovery/diy/MyConsulClient. Go, the code is as follows:
func (consulClient *ConsulClient) Register(serviceName, instanceId, healthCheckUrl string, instancePort int, meta map[string]string, logger *log.Logger) bool{
// Obtain the local IP address of the service
instanceHost := ch7_discovery.GetLocalIpAddress()
Encapsulate the metadata of the service instance
instanceInfo := &InstanceInfo{
ID: instanceId,
Name: serviceName,
Address: instanceHost,
Port: instancePort,
Meta: meta,
EnableTagOverride: false,
Check: Check{
DeregisterCriticalServiceAfter: "30s",
HTTP: "http://" + instanceHost + ":" + strconv.Itoa(instancePort) + healthCheckUrl,
Interval: "15s",
},
Weights: Weights{
Passing: 10,
Warning: 1,
},
}
byteData,_ := json.Marshal(instanceInfo)
// 2. Send a service registration request to Consul
req, err := http.NewRequest("PUT"."http://" + consulClient.Host + ":" + strconv.Itoa(consulClient.Port) + "/v1/agent/service/register",
bytes.NewReader(byteData))
if err == nil {
req.Header.Set("Content-Type"."application/json; charset=UTF-8")
client := http.Client{}
resp, err := client.Do(req)
// 3. Check the registration result
iferr ! =nil {
log.Println("Register Service Error!")}else {
resp.Body.Close()
if resp.StatusCode == 200 {
log.Println("Register Service Success!")
return true;
} else {
log.Println("Register Service Error!")}}}return false
}
Copy the code
The Register method performs the following operations:
- The service instance data is encapsulated as InstanceInfo, in which key data such as service instance ID, service name, service address, and service port are set. The health check address is /health and the check interval is 15 seconds. DeregisterCriticalServiceAfter parameter defines the health examination within 30 s failure, the service instance will be Consul active referrals.
- Through HTTP launched an registration request, the Consul will step on encapsulated InstanceInfo submitted to the registry, registered service address for/v1 / agent/service/register.
In the main function, we define that a service starts with a call to consult Client#Register. You can verify service registration and health check by starting the microservice in the CH7-discovery directory by running the following command:
go run main/SayHelloService.go
Copy the code
You can see that the corresponding startup and health check logs are displayed on the command line:
2019/07/08 20:45:21 Register Service Success!
2019/07/08 20:45:22 Health check starts!
Copy the code
Visit http://localhost:8500 on Consul’s homepage and you can see that the SayHello service has been registered with Consul, as shown in the following figure:
Directly click the SayHello service in the page to enter the service cluster page and view the service instance information under the cluster, as shown in the figure:
The figure above shows the key information of the service instance ID, address and port that we registered.
summary
This paper mainly realizes the interaction process between Microservice instance and Consul, service registration and health check. So how to unregister a service once it is registered, and how to let other services find it?
The following articles continue to implement service logout and service discovery.
The full code, from my Github,Github.com/longjoy/mic…
Phase to recommend
- Do you know the game theory developed by Von Neumann, the “father of modern computing”?
- How to learn ETCD? | I’m book
3. Realize Go service registration and discovery by yourself (PART 1)
Read the latest article, pay attention to the public number: AOHO Qiusuo