Service discovery consumer example

I Introduction to service discovery

In the process of microservice development and deployment, each service runs in an independent process. Services communicate with each other through lightweight communication mechanisms (such as RESTful API). How to manage these services? When a user sends a request, which service should be requested to meet the user's request? At this time, the service discovery function is used Service discovery is equivalent to a registry, which records all service information in the distributed system so that other services can quickly find registered services. Its function is similar to mediation


Process Description:

    1. When each service starts, it will register its own port, address, service name and other information in the service discovery function. Of course, for the stability of the service, a function may open multiple services, as shown in the login function above;

    2. When the client sends a request to service discovery, the service discovery will find the registration information corresponding to the request and return it to the client. The client can access the desired service with the registration information

There are many tools for service discovery, such as zookeeper, etcd, Eureka, consumer, etc. each has its own advantages and disadvantages. You can choose according to your own needs. Here we mainly introduce consumer

II Consumer installation and introduction

  1. install

Download directly from the official website:

Baidu online disk: Extraction code: v09o

  2. Consumer feature

Service Discovery: Consul provides a way to register and discover services through DNS or HTTP interface. Some external services can easily find the services it depends on through Consul
Health Checking: Consul's Client can provide any number of health checks, which can be associated with a given service (whether the webserver returns 200 OK) or with a local node (whether the memory utilization is less than 90%). The operator can use this information to monitor the health of the cluster, and the service discovery component can use this information to route traffic from unhealthy hosts
Key/Value storage: applications can use the Key/Value storage provided by consul according to their own needs. Consul provides a simple and easy-to-use HTTP interface. Combined with other tools, it can realize dynamic configuration, function marking, leader election and other functions
Secure service communication: Consul can generate and distribute TLS certificates for services to establish mutual TLS connections. Intent can be used to define which services are allowed to communicate. Service segmentation can be easily managed, and its purpose is to be changed in real time, rather than using complex network topology and static firewall rules
Multiple data centers: Consul supports multiple data centers out of the box This means that users do not need to worry about establishing additional abstraction layers to expand the business to multiple regions
  3. Consumer common commands

    consul agent

    • -bind= specifies the IP address of the machine where the consumer is located
    • -HTTP port = 8500 # consumer uses the default port for web access Default: 8500
    • -client= specifies which machines can access consumer Specified as: all machines are accessible
    • -config-dir=/etc/consul.d / the configuration path read when actively registering the service, customized
    • -Dat dir = / TMP / consumer / registered service information storage path, customized
    • -dev developer mode, start consumer directly with the default configuration
    • -node=hostname - the name of the service discovery
    • -rejoin # consumer joins the consumer cluster when it starts
    • -server , start the consumer in the form of service, and allow other consumers to connect to this service to form a cluster
    • -ui# you can view the details of service discovery by using the web

III Consumer active registration service

   1. Consumer start

consul agent -dev -server -client= -config-dir=/etc/consul.d/ -data-dir=/tmp/consul/ -node=n1 -ui -bind= 

When the startup is successful, you will see the following information;

==> Starting Consul agent...
           Version: 'v1.5.2'
           Node ID: '6738f862-b9ef-3fc0-115a-a0c9778847b6'
         Node name: 'n1'
        Datacenter: 'dc1' (Segment: '<all>')
            Server: true (Bootstrap: false)
       Client Addr: [] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
      Cluster Addr: (LAN: 8301, WAN: 8302)
           Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false

==> Log data will now stream in as it occurs:

    2022/03/10 09:52:52 [DEBUG] tlsutil: Update with version 1
    2022/03/10 09:52:52 [DEBUG] tlsutil: OutgoingRPCWrapper with version 1
    2022/03/10 09:52:52 [INFO]  raft: Initial configuration (index=1): [{Suffrage:Voter ID:6738f862-b9ef-3fc0-115a-a0c9778847b6 Address:}]
    2022/03/10 09:52:52 [INFO]  raft: Node at [Follower] entering Follower state (Leader: "")
    2022/03/10 09:52:52 [INFO] serf: EventMemberJoin: n1.dc1
    2022/03/10 09:52:52 [INFO] serf: EventMemberJoin: n1
    2022/03/10 09:52:52 [DEBUG] tlsutil: OutgoingTLSConfigForCheck with version 1
    2022/03/10 09:52:52 [INFO] consul: Handled member-join event for server "n1.dc1" in area "wan"
    2022/03/10 09:52:52 [INFO] consul: Adding LAN server n1 (Addr: tcp/ (DC: dc1)
    2022/03/10 09:52:52 [DEBUG] agent/proxy: managed Connect proxy manager started
    2022/03/10 09:52:52 [WARN] agent/proxy: running as root, will not start managed proxies
    2022/03/10 09:52:52 [INFO] agent: Started DNS server (udp)
    2022/03/10 09:52:52 [INFO] agent: Started DNS server (tcp)
    2022/03/10 09:52:52 [INFO] agent: Started HTTP server on [::]:8500 (tcp)
    2022/03/10 09:52:52 [INFO] agent: started state syncer
==> Consul agent running!

My virtual machine ip is, which can be accessed through You can see all the registration information:

   2. Active registration service

Now we need to actively register a service, and the configuration path specified in the startup command in 1 is / etc / consumer D /, so we create a json file in this directory and write the service configuration:

    root@master ~ > cd /etc/consul.d/
    root@master  /etc/consul.d > vim web.josn

    "service": {
        "name": "test",   # Service name
        "tags": ["IT"],     # Labels (multiple can be added)
        "port": 5000,      # port

  3. Save and restart the consumer service


See that a service called test has been registered successfully

  4. health examination

Consumer not only counts the information of all services, but also regularly checks whether the services are healthy to ensure that the services provided to clients are services that can be requested normally There are five ways of consumer health examination:

      • Script: check by external script
      • http: Based on the http request, send heartbeat packets to the service regularly. If there is no normal return, it is judged that the service is unhealthy
      • tcp: a tcp connection is established between the timer and the service. A successful connection indicates that the service is healthy
      • Grpc: Decision Based on grpc protocol
      • docker: used in combination with script to determine the health of the service by judging whether the container is running normally

We use http to judge whether the service registered in 2 is normal, and open the web created in 2 Add check attribute to JSON file:

    "service": {
        "name": "test",
        "tags": ["IT"],
        "port": 5000,
        "check": {
            "id": "mytest",
            "name": "consulTest",   # Name of health examination service
            "http": " ", # service address
            "interval": "5s",   # Request cycle
            "timeout": "1s"     # Timeout duration

  5. Restart the consumer service

     root@master   /etc/consul. D > consumer reload # restart the consumer service


See that there is a red one under the newly registered service Health ×, Because we just registered a service and didn't really start it, we made a request in the consumer“ "I didn't receive a reply, so it is judged that this service is unhealthy. Those interested can start a service to see what changes the consumer has

IV protobuf+grpc+consul

Now we use go language to register a service in combination with protobuf and grpc:

protobuf implements grpc service. Refer to the previous article, and we won't talk about it in detail here: go using grpc communication example

The grpc service has been created through the proto file above, and the server and client have been implemented. The next thing we need to do is to introduce the service discovery function

  1. Start the consumer service:

Here we start directly with the default configuration

Command: consumer agent - dev - client

  2.grpc server registration:

func main() {
	config := api.DefaultConfig()           // Initialize consumer configuration
	config.Address = ""  // Because my consumer service is in the virtual machine and grpc service is in windows, I must formulate the consumer address
	client, err := api.NewClient(config)    // Initialize the consumer and pass in the configuration initialized above
	if err != nil {
        // Service registration configuration
	reg := api.AgentServiceRegistration{
		Name:    "grpcTest",            // Service name
		Tags:    []string{"grpc"},      // label
		Port:    8080,
		Address: "",
                // Configure health check service
		Check: &api.AgentServiceCheck{
			CheckID:  "grpcCheck",
			Name:     "IT",
			GRPC:      "",  // Check with grpc protocol
			Interval: "5s",
			Timeout:  "1s",
	err = client.Agent().ServiceRegister(&reg)   // Carry configuration registration service
	if err != nil {
    // Initialize a grpc object
    // Registration service
    // Set listening  

  3. grpc client:

func main() {
	consulConfig := api.DefaultConfig() // Initialize configuration
	consulConfig.Address = ""  // Specify the consumer address
	consulClient, err := api.NewClient(consulConfig)  // Get the consumer action object
	if err != nil {
		fmt.Println("client, api.newclient err:", err)

	// Get service address
	// Parameter: Service: name of the accessed service; tag: Service tag accessed; passingOnly: whether it is necessary to pass the health examination, usually true; q: Other service information you want to obtain is useless nil
	// Return value: s[]*ServiceEntry: services slice (a function may open multiple services, return the service list, and the client can select the best service through the load balancing algorithm, which is not explained in detail here) 
	// *QueryMeta if there are other information in q the request parameters, you can get it through QueryMeta 
	// Error error message

	services, _, err := consulClient.Health().Service("grpcTest", "grpc", true, nil)
	// Splice the returned service address: Port
	addr := services[0].Service.Address + ":" + strconv.Itoa(services[0].Service.Port)
        // Connect to grpc service, add certificate and use the address returned by consumer
        clientConn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
        // Initialize grpc client
        // Call method

  4. Test:

    • Start grpc server
    • Start grpc client
    • Web view consumer service

Seeing that a service named grpcTest has been registered and green under Health Checks indicates that the service is healthy. The results returned after the client starts up are the same as those returned above. Therefore, there is no big change in the user experience after using the service registration, but there is a big difference in the program implementation


Keywords: Go

Added by dzoddi on Thu, 10 Mar 2022 05:48:18 +0200