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 toService Registry
called service registrationService A
fromService Registry
findService 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 addressetcd
Key
is the service registeredkey
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
eachPod
starts, it will register itself toEndpoints
of the clusterService A
eachPod
start, from the clusterEndpoints
get inService B
node information- When
Service B
when a node changes,Service A
bywatch
clustersEndpoints
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
- Define cluster-wide permissions and roles, which are not controlled
ServiceAccount
- Define
namespace
range ofservice account
- Define
ClusterRoleBinding
- The defined
ClusterRole
and differentnamespace
ofServiceAccount
bind
- The defined
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 thenamespace
myservice
: The name of therpc
3456
: The port of therpc
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.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。