网络上已经有很多介绍这方面的文章,可以查看参考或自行Google关键字”服务发现和负载均衡”,但我这里仍然做个Mark,毕竟这是微服务架构中极其重要的内容。
总结来看,客户端如何发现服务端只有两种方式,要么直接把服务端的地址告诉客户端,要么把一个第三方(也就是代理)的地方告诉客户端,然后让客户端去询问这个第三方其所需要的服务端地址在哪里。
直接告诉的方式不用讨论,因为很简单,而利用代理的方式稍显复杂,根据代理所处的不同部署位置而区分出不同的模式。
最经典的模式就是传统集中代理模式(Proxy Model),比如在多个Web服务端之前架设一台Nginx,所有的客户端请求都集中发往Nginx,再由Nginx去做负载均衡把请求分发到不同的服务端,然后将服务响应结果返回给客户端。在这种模式下,一般通过DNS域名或URI目录实现服务发现,需要运维人员手动配置,比如bbs服务:
bbs.example.com 或 www.example.com/bbs
邮件服务:
email.example.com 或 www.example.com/email
等等。
传统集中代理模式在客户端和服务端之间增加了一级节点,因此需要添加额外的资源,对整个服务的请求响应也有一定的性能损耗,另外还需要对代理做高可用处理,否则形成单点故障(万一代理挂了,客户端就没法请求服务端的服务了)。
第二种模式是客户端嵌入式代理(Balancing-aware Client),即代理直接实现在客户端程序里,当客户端要请求服务时,由这个内嵌代理去获取到对应的服务端地址列表(假设有多个的话),然后按照一定的负载均衡算法,从这个服务端地址列表里选择一台服务端进行服务请求。客户端程序里的代理逻辑如何去获取到对应的服务端地址列表呢?一般是通过独立的服务注册中心组件来配合,也就是代理去服务注册中心查询获得。当然,服务端也要在启动时把对应的服务注册到服务注册中心,否则客户端程序里代理查询不到。
在文章http://lenky.info/?p=2844里介绍的示例就是这种模式,看其客户端client.go里的代码:
d := client.NewEtcdV3Discovery(*basePath, "Arith", []string{*etcdAddr}, nil) xclient := client.NewXClient("Arith", client.Failover, client.RoundRobin, d, client.DefaultOption)
可以看到,客户端通过去Etcd这个服务注册中心查询Arith的服务,并且设定了对应的负载均衡算法为RoundRobin。
在这种模式下,客户端直接连接服务端,开销比传统集中代理模式低,但其也不是没有缺点,比如:
i) 客户端与服务注册绑定,要针对服务端用到的每个编程语言和框架,实现客户端的服务发现逻辑,因此开发和维护多版本、多语言的客户端的成本很高。
ii) 一些算法需要客户端和服务端之间维持通信,客户端会变的更加复杂。
第三种模式就是主机独立进程代理(SideCar Model),也就是前两种模式的折中,将负载均衡的逻辑独立出来交给单独的均衡器进程,并且部署在每一台主机上,一个主机上的多个客户端应用程序可以共用这个代理,实现服务发现和负载均衡。这个模式一般也需要独立的服务注册中心组件配合,作用同第二种模式。
在这种模式下,均衡器负责和后端服务保持通信,收集服务的负载和状态信息。 客户端通过均衡器来选择服务列表。相比第一种方案,客户端仍然是直接连接服务端,不会有额外的开销。客户端也不需要为不同语言和不同版本来维护不同的库。
Over~
参考:
1,https://www.sohu.com/a/282554391_100028126
2,https://www.jianshu.com/p/f49c3a29b5dc
3,https://www.jianshu.com/p/4828f90674b3
4,https://ralphbupt.github.io/2017/11/27/etcd%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/
5,https://segmentfault.com/a/1190000014963576
6,https://segmentfault.com/a/1190000011115589
转载请保留地址: http://www.lenky.info/archives/2020/05/2849 或 http://lenky.info/?p=2849
备注:如无特殊说明,文章内容均出自Lenky个人的真实理解而并非存心妄自揣测来故意愚人耳目。由于个人水平有限,虽力求内容正确无误,但仍然难免出错,请勿见怪,如果可以则请留言告之,并欢迎来 信 讨论。另外值得说明的是,Lenky的部分文章以及部分内容参考借鉴了网络上各位网友的热心分享,特别是一些带有完全参考的文章,其后附带的链接内容也许更直接、更丰富,而我只是做了一下归纳&转述,在此也一并表示感谢。关于本站的所有技术文章,欢迎转载,但请遵从 CC创作共享协议 ,而一些私人性质较强的心情随笔,建议不要转载。
法律:根据最新颁布的《信息网络传播权保护条例》,如果您认为本文章的任何内容侵犯了您的权利,请以 Email 或书面等方式告知,本站将及时删除相关内容或链接。