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: https://www.consul.io/downloads
Baidu online disk: https://pan.baidu.com/s/1NLEskDQOtipX5BB9v4HeoA 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=0.0.0.0 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=127.0.0.1 specifies which machines can access consumer Specified as: 0.0.0.0 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=0.0.0.0 -config-dir=/etc/consul.d/ -data-dir=/tmp/consul/ -node=n1 -ui -bind=192.168.79.134
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: [0.0.0.0] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600) Cluster Addr: 192.168.79.134 (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:192.168.79.134:8300}] 2022/03/10 09:52:52 [INFO] raft: Node at 192.168.79.134:8300 [Follower] entering Follower state (Leader: "") 2022/03/10 09:52:52 [INFO] serf: EventMemberJoin: n1.dc1 192.168.79.134 2022/03/10 09:52:52 [INFO] serf: EventMemberJoin: n1 192.168.79.134 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/192.168.79.134:8300) (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 0.0.0.0:8600 (udp) 2022/03/10 09:52:52 [INFO] agent: Started DNS server 0.0.0.0:8600 (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 192.168.79.134, which can be accessed through http://192.168.79.134:8500 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": "http://192.168.79.134:5000 ", # 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“ http://192.168.79.134:5000 "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 0.0.0.0
2.grpc server registration:
func main() { config := api.DefaultConfig() // Initialize consumer configuration config.Address = "192.168.79.134:8500" // 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 { fmt.Println(err) return } // Service registration configuration reg := api.AgentServiceRegistration{ Name: "grpcTest", // Service name Tags: []string{"grpc"}, // label Port: 8080, Address: "192.168.1.51", // Configure health check service Check: &api.AgentServiceCheck{ CheckID: "grpcCheck", Name: "IT", GRPC: "192.168.1.51:8080", // Check with grpc protocol Interval: "5s", Timeout: "1s", }, } err = client.Agent().ServiceRegister(®) // Carry configuration registration service if err != nil { fmt.Println(err) return } ///////////////////////////////////////////////////////////////// // Initialize a grpc object // Registration service // Set listening }
3. grpc client:
func main() { consulConfig := api.DefaultConfig() // Initialize configuration consulConfig.Address = "192.168.79.134:8500" // Specify the consumer address consulClient, err := api.NewClient(consulConfig) // Get the consumer action object if err != nil { fmt.Println("client, api.newclient err:", err) return } // 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 { fmt.Println(err) return } // 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