go use consul to achieve registration service discovery

aims

Since it is learning to use consul to achieve registration service discovery, the goal is to achieve a natural program, through consul, found another program.

To this end I have prepared three machines:

1. The cloud server A (ubuntu): Run consul agent

2. The cloud server B (ubuntu): run a service, and sign up to the consul at the time the service starts

3. The machine (mac): running a program, on the consul through the cloud server A, the server discovery service on the cloud B

Start consul agent

First of all, to start consul agent on a cloud server A.

If the consul is not already installed on your server, you can refer to this ubuntu install consul .

Start consul agent using the following command.

consul agent -dev -client 0.0.0.0

Note, be sure to add -client 0.0.0.0, or other machine is not accessible consul's.

Service Registration

After the consul agent up and running, we can write a simple service program, and then register it to the consul.

Note that the following program uses the api package consul official, and machine if you do not have this package, it would need to install it, you can refer to this go consul installation package ( "github.com/hashicorp/consul/api" ) .

//本段程序参考了https://www.cnblogs.com/hcy-fly/p/10826607.html博客中的内容
package main

import (
	"fmt"
	consulapi "github.com/hashicorp/consul/api"
	"net/http"
)

const (
	consulAddress = "consul agent ip:8500"
	localIp       = "your server ip"
	localPort     = 81
)

func consulRegister()  {
	// 创建连接consul服务配置
	config := consulapi.DefaultConfig()
	config.Address = consulAddress
	client, err := consulapi.NewClient(config)
	if err != nil {
		fmt.Println("consul client error : ", err)
	}

	// 创建注册到consul的服务到
	registration := new(consulapi.AgentServiceRegistration)
	registration.ID = "337"
	registration.Name = "service337"
	registration.Port = localPort
	registration.Tags = []string{"testService"}
	registration.Address = localIp

	// 增加consul健康检查回调函数
	check := new(consulapi.AgentServiceCheck)
	check.HTTP = fmt.Sprintf("http://%s:%d", registration.Address, registration.Port)
	check.Timeout = "5s"
	check.Interval = "5s"
	check.DeregisterCriticalServiceAfter = "30s" // 故障检查失败30s后 consul自动将注册服务删除
	registration.Check = check

	// 注册服务到consul
	err = client.Agent().ServiceRegister(registration)
}

func Handler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("you are visiting health check api"))
}

func main()  {
	consulRegister()
	//定义一个http接口
	http.HandleFunc("/", Handler)
	err := http.ListenAndServe("0.0.0.0:81", nil)
	if err != nil {
		fmt.Println("error: ", err.Error())
	}
}

The top of this program, copy the path to run on any cloud server B can pay attention to the inside of the two server ip change it, here is not to disclose my server ip haha.

After testing the service up and running, enter in the browser of the machine

http://ip:8500/ui/

Open consul ui, you can see, just run up service, it has been registered with the consul friends ~

Click service337, you can see the address of the service:

Here, we have information on the cloud service server B, successfully registered to the consul. 

Do not worry proceeding further, noting that the program was still a health check on the consul. Health Check is a registered service discovery component essential to the function, with health checks, after the service registration, if hung up, consul is to know.

In consul ui interface, click on the 337, you can see the following information:

See output information, it is the content of our output interface functions in the set, which can be seen, consul health check is performed regularly:

curl ip:port/ 

If the result is 200ok, health checks shall be successful.

Here, we must pay attention to is that your services, be sure to handle ip: port / this request , or even if you run a good service, health check is not passed.

Health check three important parameters, that is, three in the program:

check.Timeout = "5s"
check.Interval = "5s"
check.DeregisterCriticalServiceAfter = "30s"

among them:

Interval is the execution time of the health check interval, the program was set up to 5s, which is 5s will perform a health check every consul agent;

Timeout is a health check timeout, the program was set up to 5s, that is, if the consul did not receive a reply for more than 5s health checks, it will appear that the problem service, and set the status of the service is critical;

DeregisterCriticalServiceAfter registration information is deleted time, the program was set to 30s, that is, if the services remain critical state for more than 30s, consul will completely remove the registration information services.

Let's verify, first of all, control + c manually stopped our services, then over 5s observed consul interface found has become such:

You can see, the health check failed.

In a few 30s, then refresh the interface, found into a 404, indicating that the service information has been deleted.

Service Discovery

We then serve on the above cloud server B running up and let it re-registered to the consul, then, we must begin to do service found friends ~

With respect to the service registration, service discovery is simpler, in fact, a simple query directly on the code:

//本段程序参考了https://www.cnblogs.com/hcy-fly/p/10826607.html博客中的内容
package main

import (
	"fmt"
	consulapi "github.com/hashicorp/consul/api"
)

const (
	consulAgentAddress = "your consul agent ip:8500"
)

// 从consul中发现服务
func ConsulFindServer()  {
	// 创建连接consul服务配置
	config := consulapi.DefaultConfig()
	config.Address = consulAgentAddress
	client, err := consulapi.NewClient(config)
	if err != nil {
		fmt.Println("consul client error : ", err)
	}

	// 获取指定service
	service, _, err := client.Agent().Service("337", nil)
	if err == nil{
		fmt.Println(service.Address)
		fmt.Println(service.Port)
	}

    	//只获取健康的service
	//serviceHealthy, _, err := client.Health().Service("service337", "", true, nil)
	//if err == nil{
	//	fmt.Println(serviceHealthy[0].Service.Address)
	//}

}

func main()  {
	ConsulFindServer()
}

Operating results of this program are as follows:

We can see, the success of the program to get the ip and port information services on the cloud server B. Note that the above program in a comment period, which is the interface to another service discovery, the above difference is that this interface can only obtain the status of health services.

Service hung up, the caller how do you know?

Finally, add that, if the service hung up, then the service callers how can we know it?

Here we have to mention the other service governance component of the zookeeper, zookeeper watcher mechanism through the service status change notification directly to subscribers.

Then consul there is no such mechanism? The answer is: not. . .

provided that the consul http interface, http Well, that you can only request, it will not take the initiative to send you something. . . Therefore, it can not support the notification feature friends ~

Consul solution to this problem is offered: long polling.

The so-called long polling, is that after the server receives the request, found no change in the content of the request, it would not be back to you until you change the contents of the request, or a timeout, and then returns the result, thus also achieved, service status change The caller can obtain in a timely manner.

Compared to ordinary rotation, the advantages of long polling is not in service without any change of circumstances has also been returned things, saving network resources.

Long polling drawback is that if the request is received, the requested content has not changed, the connection will hang, which is taking up a connection resources.

But zookeeper watcher mechanism, in fact, should be maintained between the client and zk zk server tcp connection, a connection must have been occupied, so from that point of view, compared with the long poll watcher, not a disadvantage.

For service calls are concerned, whether used consul long polling, or watcher mechanism zookeeper, access to services of the changes in state will be delayed because there zookeeper similar mechanism consul of health, also through server and client Regular communication between the end of the inspection service state, that is, a delay is required because the consul or zookeeper failed health check service after that service hung up. Well this delay, it is hard to avoid, because we can not count on the service hung up when he heard it zookeeper notify the consul or, if the service can know when they will hang, will not hang up. . .

Finally, since the zookeeper mentioned, simply compare:

1. notification mechanism: the above said, my conclusion is that, almost

2. coherency protocol: consul using the raft, zookeeper give paxos use of zab, these two I do not studied, can not comment on what good or bad.

3. Use: consul support http interface using a consul of this blog api package, in fact, became the http package calls function better with some, but zookeeper can only use the client, the client integrated into the program in. From this point of view, consul is easier to use some.

As for the other points, fully understand, and then later add it, ha ha.

Published 39 original articles · won praise 25 · views 120 000 +

Guess you like

Origin blog.csdn.net/u013536232/article/details/104235282