-
直连
-
基于 etcd 的服务发现
-
基于 kubernetes endpoints 的服务发现
直连
直连是最简单的方式,当我们的服务足够简单时,比如单机即可承载我们的业务,我们可以直接只用这种方式。
在 rpc
的配置文件里直接指定 endpoints
即可,比如:
Rpc:
Endpoints:
-
192.168.0.111:3456
-
192.168.0.112:3456
zrpc
调用端就会分配负载到这两个节点上,其中一个节点有问题时 zrpc
会自动摘除,等节点恢复时会再次分配负载。
这个方法的缺点是不能动态增加节点,每次新增节点都需要修改调用方配置并重启。
基于 etcd 的服务发现
当我们的服务有一定规模之后,因为一个服务可能会被很多个服务依赖,我们就需要能够动态增减节点,而无需修改很多的调用方配置并重启。
常见的服务发现方案有 etcd
, consul
, nacos
等。
go-zero内置集成了基于 etcd
的服务发现方案,具体使用方法如下:
Rpc:
Etcd:
Hosts:
-
192.168.0.111:2379
-
192.168.0.112:2379
-
192.168.0.113:2379
Key: user.rpc
-
Hosts
是etcd
集群地址 -
Key
是服务注册上去的key
基于 Kubernetes Endpoints 的服务发现
如果我们的服务都是部署在 Kubernetes
集群上的话,Kubernetes
本身是 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 通过自带的 etcd
管理集群状态的,所有的服务都会把自己的节点信息注册到 Endpoints
对象,我们可以直接给 deployment
权限去读取集群的 Endpoints
对象即可获得节点信息。
-
Service B
的每个Pod
启动时,会将自己注册到集群的Endpoints
里 -
Service A
的每个Pod
启动时,可以从集群的Endpoints
里获取Service B
的节点信息 -
当
Service B
的节点发生改变时,Service A
可以通过watch
集群的Endpoints
感知到
在这个机制工作之前,我们需要配置好当前 namespace
内 pod
对集群 Endpoints
访问权限,这里有三个概念:
-
ClusterRole
-
定义集群范围的权限角色,不受
namespace
控制 -
ServiceAccount
-
定义
namespace
范围内的service account
-
ClusterRoleBinding
-
将定义好的
ClusterRole
和不同namespace
的ServiceAccount
进行绑定
具体的 Kubernetes
配置文件可以参考 [这里]((),其中 namespace
按需修改。
注意:当启动时报没有权限获取 Endpoints
时记得检查这些配置有没落实 😃
zrpc
的基于 Kubernetes Endpoints
的服务发现使用方法如下:
Rpc:
Target: k8s://mynamespace/myservice:3456
其中:
-
mynamespace
:被调用的rpc
服务所在的namespace
-
myservice
:被调用的rpc
服务的名字 -
3456
:被调用的rpc
服务的端口
在创建 deployment
配置文件时一定要加上 serviceAccountName
来指定使用哪个 ServiceAccount
,示例如下:
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
注意其中 serviceAccountName
指定该 deployment
创建出来的 pod
用哪个 ServiceAccount
。
server
和 client
都部署到 Kubernetes
集群里之后可以通过以下命令滚动重启所有 server
节点
kubectl rollout restart deploy -n adhoc server-deployment