轻松构建微服务之服务注册和发现

微信公众号:内核小王子
关注可了解更多关于数据库,JVM内核相关的知识;
若是你有任何疑问也能够加我pigpdong[^1]html

前言

为何须要服务注册中心? 随着服务数量的扩张,咱们须要服务调用方可以自动感知到服务提供方的地址,当咱们对服务提供方进行横向扩展的时候,服务调用方可以自动感知到,这就须要服务提供方可以在启动或者关闭的时候自动向注册中心注册,而服务调用方直接询问注册中心就能够知道具体的服务提供方的地址列表,服务调用方能够本身根据特定的路由算法作负载均衡, 或者服务调用方根本不须要知道服务提供方的具体地址,统一发给一个代理系统,由这个代理系统转发给对应的服务调用方。因此为了支持服务的弹性扩展,咱们须要一个独立系统作服务发现和负载均衡,目前作服务发现有三种代理模式nginx

集中代理模式

集中代理模式通常是在服务调用方和服务提供方之间部署一套独立的代理系统来接收调用方的请求,而后配合域名系统和特定的负载均衡策略以及路由算法,转发到对应的服务提供方,这个代理系统通常由硬件F5设备加7层软件负载nginx配合域名系统来使用,这种模式,有集中治理,运维简单,并且和语言栈无关的优势,可是目前这个代理系统存在单点问题,并且配置比较麻烦,因为服务调用者没有之间调用服务提供方,因此网络上存在多一跳的开销,目前国内主要有携程等公司在使用算法

image

客户端嵌入式代理

目前不少公司用springcloud或者dubbo做为rpc框架的公司多选择这种模式,在客户端嵌入一个程序作服务发现和软件负载均衡,调用方会缓存服务提供方的地址列表,而且本身根据路由算法和负载均衡策略选择服务提供者进行调用,这种模式须要一个第三方的注册中心配合,服务提供者启动的时候将服务注册到注册中心,服务调用方去注册中心获取服务提供者信息,这种模式有无单点问题,性能好的优势,可是因为客户端须要关心负载均衡和维护提供者列表,致使客户端臃肿,目前国内主要有阿里的dubbo和新浪的Motanspring

image

主机独立进程代理

这种模式是前面两种模式的一个折中,将这个代理放到主机的一个独立程序上,全部这个主机上的应用共享这个代理,应用通常部署在docker容器中,主机能够是一个物理机也能够是虚拟机。在这个代理上进行路由和负载均衡,这个模式也须要一个模式二中独立的注册中心来辅助代理程序作服务发现,这种模式兼具上面两种模式的优势,可是运维较复杂,目前国内只有惟品会有这种模式的探索docker

image

servicemesh介绍

边车模式,sidecar,将一个单独的进程用来处理,日志,健康,限流,服务发现等功能,和应用层彻底分离,目前若是咱们大多lib等软件包的形式和应用集成来实现限流和监控,这样增长了应用依赖,每次lIB包升级都须要将应用从新编译发布,而边车模式下咱们能够将逻辑层和控制层分开部署.数据库

边车模式进化后,将这个独立程序集群化,就成了servicemesh,也就是CNCF所推荐的新一代微服务架构,将这个代理程序下沉为一个基础服务,做为平台开放给应用程序编程

image

servicemesh的定义:一做为个轻量级的网络代理专职处理服务和服务间的通信,对应用程序透明,用来分离或者解耦和分布式系统架构中控制层的上的东西.缓存

相似于网络七层模型中的TCP协议,将底层那些难控制的网络通信方面的东西(拥塞控制,丢包重传,流量控制)都处理了,而上层的http协议就只用关心应用层的html格式安全

演化路径微信

  • 1.一开始最原始的两台主机之间进程直接通信
  • 2.而后分离出网络层来,服务间的远程通讯经过底层的网络模型
  • 3.因为两边服务因为接收速度不一致,须要在应用层作流控
  • 4.而后流控模块交给网络层去处理,最后TCP演化成为世界上最成功的网络协议
  • 5.类比分布式架构中,咱们在应用层加入了限流,熔断,监控,服务发现等功能
  • 6.而后咱们发现这些控制层的功能均可以标准化,咱们将这些功能分别作成LIB嵌入到应用中,这样谁须要这个功能只要加入这个LIB就行了
  • 7.最后咱们发现这些LIB不能跨编程语言,而后有什么改动就须要从新编译发布服务,不太方便,应该有一个专门的层来干这个,就是sidecar
  • 8.而后sidecar集群就成了Service mesh ,成为了一个基础设施

image

目前开源的servicemesh实现有istio

为何zookeeper不适合作服务发现

  • 首先咱们分析下服务发现是知足cap里面的ap仍是cp

注册中心提供了两个服务,一个是让服务提供方注册,就是写数据,另外一个是让服务调用方查询,就是读数据,当注册中心集群部署后,每一个节点
均可以对外提供读写服务,每一次写请求都会同步到其余节点,这样才能让其余节点提供的读服务正确,若是节点之间的数据复制出现不一致,那么将致使服务调用方获取到的服务提供者列表中要么出现已经下线的节点,要么少提供了一个正常的节点,
提供了下线的节点,服务调用者能够经过重试机制调用其余节点,出现少提供一个正常节点则致使服务提供方的流量不均匀,这些都是能够接受的,况且各个节点最终都会同步成功,也就是数据最终一致性,因此咱们但愿注册中心是高可用的,最好能知足最终一致性,而zookeeper是典型的CP设计,在网络分区状况下不可用,当节点超过半数挂掉不可用,违背了注册中心不能由于自身任何缘由破坏服务自己的可连通性

  • 另外咱们分析下出现网络分区的状况

咱们看下下图zookeeper三机房5节点部署的状况下,若是机房3和机房1机房2网络出现分区成为孤岛,zookeeper和机房3里的其余应用不能和外部通讯,zookeeper因为联系不是leader将不可用,虽然zookeeper整个集群中其余4个节点依然能够对外提供服务,可是zookeeper为了保证在脑裂的状况下数据一致性,机房3的节点5将不能进行读写服务,这个时候机房3内的应用A虽然不能
调用其余机房的服务B可是能够调用机房3内的服务B,可是因为Zookeeper5不能读写,因此机房内也不能读写,这对应用来讲是彻底不能接受的,咱们有时候为了性能考虑还好主动修改路由策略让应用尽可能同机房调用,试想一下若是三个机房都出现网络分区相互成为孤岛,那么整个应用将不可用

[图片上传失败...(image-269105-1558422945065)]

  • zookeeper的写服务并不支持水平扩展

zookeeper须要和全部的服务保持长链接,而随着服务的频繁发布,以及服务的健康检查,会致使zookeeper压力愈来愈大,而zookeeper并不能经过横向扩展节点解决,能够提供的方案是按照业务进行拆分到不一样的zookeeper集群

  • 健康检查

服务提供方是否可用,不能仅仅经过zookeeper的session是否存活判断,TCP活性并不能反映服务的真实健康状态,而须要完整的健康体系,CPU,内存,服务是否可用,数据库是否能联通等

几个注册中心的对比

指标 Consule zookeeper etcd eureka
服务监控检测 服务状态,内存,硬盘 长链接keepalived 链接心跳 须要配置
多数据中心 支持 不支持 不支持 不支持
KV存储 支持 支持 支持 不支持
一致性 gossip paxos raft
CAP CA CP CP AP
使用接口(多语言能力) 支持http和dns 客户端 http/grpc http(sidecar)
watch支持 全量/支持long polling 支持 支持 long polling 支持 long polling/大部分增量
自身监控 metrics metrics metrics
安全 acl /https acl https支持(弱)
spring cloud集成 已支持 已支持 已支持 已支持
相关文章
相关标签/搜索