What is service registration discovery?

For students engaged in microservices, the concepts of service registration and service discovery should not be too unfamiliar.

Simply put, when service A needs to depend on service B, we need to tell service A where to call service B. This is the problem to be solved by service registration discovery.

  • Service B register itself to Service Registry called service registration
  • Service A from Service Registry find Service B node information called service discovery

Service registration

Service registration is for the server. After the service is started, it needs to be registered. It is divided into several parts:

  • Start registration
  • Timed renewal
  • Withdrawal

Start registration

When a service node gets up, it needs to register itself to Service Registry , so that other nodes can find itself. Registration needs to register itself when the service is started and can accept the request, and the validity period will be set to prevent the process from being accessed even after the process exits abnormally.

Timed renewal

Timed renewal is equivalent to keep alive , and you regularly tell Service Registry you are still there and can continue the service.

Withdrawal

When the process exits, we should take the initiative to revoke the registration information, so that the caller can distribute the request to other nodes in time. At the same time, go-zero uses adaptive load balancing to ensure that the node can be removed in time even if the node exits without actively logging out.

Service discovery

Service discovery is aimed at the caller, and is generally divided into two types of problems:

  • Inventory acquisition
  • Incremental listening

Another common engineering problem is

  • Responding to service discovery failures

When there is a problem with the service discovery service (such as etcd, consul, nacos, etc.), we should not modify the list of endpoints that have been obtained, so as to better ensure that the services that depend on etcd after the downtime can still interact normally.

Inventory acquisition

When Service A starts, you need to get the Service B of existing nodes of Service Registry Service B1 , Service B2 , Service B3 , and then select the appropriate node to send the request according to your own load balancing algorithm.

Incremental listening

The figure has been Service B1 , Service B2 , Service B3 , if this time they started Service B4 , then we need to inform Service A have a new node. As shown in the figure:

Responding to service discovery failures

For the service caller, we will cache a list of available nodes in memory. Whether using etcd , consul or nacos etc., we may face service discovery cluster failure. Take etcd as an example. When we encounter etcd failure, we need to freeze Service B without changing it, and we must not clear it at this time. The node information cannot be obtained once it is cleared. At this time Service B are likely to be normal, and go-zero will automatically isolate and restore the failed node.

The basic principles of service registration and service discovery are roughly the same. Of course, the implementation is still more complicated. Next, let's take a look at what service discovery methods are supported in go-zero

Go-zero's built-in service discovery

go-zero supports three service discovery methods by default:

  • Direct connection
  • Service discovery based on etcd
  • Service discovery based on kubernetes endpoints

Direct connection

Direct connection is the simplest way. When our service is simple enough, for example, a single machine can carry our business, we can just use this way directly.

rpc endpoints directly in the configuration file of 0613e2413222ab, for example:

Rpc:
  Endpoints:
  - 192.168.0.111:3456
  - 192.168.0.112:3456

zrpc caller will distribute the load to these two nodes. When one of the nodes has a problem, zrpc will be automatically removed, and the load will be distributed again when the node is restored.

The disadvantage of this method is that nodes cannot be dynamically added, and each time a new node is added, the caller configuration needs to be modified and restarted.

Service discovery based on etcd

When our service has a certain scale, because a service may be dependent on many services, we need to be able to dynamically increase or decrease nodes without modifying many caller configurations and restarting.

Common service discovery solutions include etcd , consul , nacos etc.

go-zero integrates a etcd . The specific usage method is as follows:

Rpc:
  Etcd:
     Hosts:
     - 192.168.0.111:2379
     - 192.168.0.112:2379
     - 192.168.0.113:2379
     Key: user.rpc
  • Hosts is the cluster address etcd
  • Key is the service registered key

Service discovery based on Kubernetes Endpoints

If our services are deployed on the Kubernetes cluster, Kubernetes itself manages the cluster state through its own etcd , all services will register their node information to the Endpoints object, we can directly give the deployment permission to read the cluster The Endpoints object can obtain node information.

  • Service B each Pod starts, it will register itself to Endpoints of the cluster
  • Service A each Pod start, from the cluster Endpoints get in Service B node information
  • When Service B when a node changes, Service A by watch clusters Endpoints perceived

Before working of this mechanism, we need to configure the current namespace within pod cluster Endpoints access, there are three concepts:

  • ClusterRole

    • Define cluster-wide permissions and roles, which are not controlled namespace
  • ServiceAccount

    • Define namespace range of service account
  • ClusterRoleBinding

    • The defined ClusterRole and different namespace of ServiceAccount bind

For the specific Kubernetes configuration file, please refer to here , where namespace can be modified as required.

Note: Remember to check if these configurations have been implemented when you do not have permission to get Endpoints

zrpc based Kubernetes Endpoints service discovery using the following method:

Rpc:
  Target: k8s://mynamespace/myservice:3456

in:

  • mynamespace : rpc where the namespace
  • myservice : The name of the rpc
  • 3456 : The port of the rpc

When creating the deployment configuration file, you must add serviceAccountName to specify which ServiceAccount to use. An example is as follows:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: alpine-deployment
  labels:
    app: alpine
spec:
  replicas: 1
  selector:
    matchLabels:
      app: alpine
  template:
    metadata:
      labels:
        app: alpine
    spec:
      serviceAccountName: endpoints-reader
      containers:
      - name: alpine
        image: alpine
        command:
        - sleep
        - infinity

Note which serviceAccountName specify the deployment created out of pod with which ServiceAccount .

server and client are deployed to the Kubernetes server nodes can be rolled and restarted by the following command

kubectl rollout restart deploy -n adhoc server-deployment

Use the following command to view the client node log:

kubectl -n adhoc logs -f deploy/client-deployment --all-containers=true

It can be seen that our service discovery mechanism perfectly followed up the server node, and there were no abnormal requests during the service update.

For complete code examples, see https://github.com/zeromicro/zero-examples/tree/main/discovery/k8s

The next article I will explain in go-zero in how to implement based on consul , nacos registration service discovery, so stay tuned!

project address

https://github.com/tal-tech/go-zero

Welcome to use go-zero and star support us!

WeChat Exchange Group

Follow the " Practice " public account and click on the communication group get the community group QR code.


kevinwan
939 声望3.5k 粉丝

go-zero作者