Istio 微服务架构的演变

微服务架构的演变


单体模式下面一个应用通常会有一个app server,这个app server里面会有不同的子模块,每一个模块都写在同一个应用包里面,模块和模块之间的边界有些时候设计的不是特别清晰,特别早期代码混合在一起那么意味着互相的调用。

这种比较重的单体架构还是通过冗余部署和负载均衡来保证应用的高可用。

单体架构不再适合复杂的业务需求,我们会去做一些业务架构的调整,取而代之的是一个一个的子系统,这些子系统有独立的部署文件,有着独立的生命周期。每个子系统高可用的诉求也是不一样的,子系统和子系统通过网络调用来完成整个业务。

原来一个单体系统,单实例单进程这样一个模式就会变为成百上千个子服务形成统一的部署视图。

这个时候再去人肉一个一个的去管控,那么代价会非常的大,出错的机率会非常的高。这样就需要依赖自动化的方式去完成应用的配置和服务发现的能力。

从单块系统到微服务系统的演进


假设说有一个网店,销售有一个销售模块,提供门户卖东西。网店卖的货要有存储,有个仓库管理系统去管理库存,后面还有计费,折扣这些诉求。针对于单体应用就会提供到单体应用的功能里面去。

既然是同一个进程,那么只要告诉我地址我就可以访问到所有的服务。

微服务架构演进

要将单体应用拆分为微服务架构,这样就将一个应用进程里面不同能力拆分为不同的子系统,每个子系统承担自己的职责。

sales既然支撑了前端的业务,那么它的可用性的要求会高,它所支持的并发请求也就会越多,这里就可以去部署更多的实例,提供更多的负载并发的支撑,然后提供更高的可用性。

网络要为每一个系统打通,包括服务和服务之间的调用。为了解决这种复杂的耦合性就可以使用api gateway。集群里面可以有很多很多的服务,这些服务可能通过同一个域名暴露出去,那么就需要一个api网关的,这个网关接受不同的客户诉求,然后经由网关转发到不同的服务

服务和服务之间的调用就需要有服务发现的机制,那么就需要服务注册中心,每个服务起来之后要将自己注册上去,并且不停的renew去说我活着。他要去注册自己的健康状态,其他人再去做服务调用的时候知道这个服务有哪些真实的服务器跑在后面。

[root@master ~]# cd microservic-test/gateway-service/src/main/resources/
[root@master resources]# cat application-fat.yml 
spring:
  cloud:
    gateway:
      discovery:
        locator:
          #开启以服务id去注册中心获取转发地址
          enabled: true
          ##灏..serviceId
          lower-case-service-id: true
      routes:
        - id: product-service
          uri: lb://product-service
          filters:
            - StripPrefix=1
          predicates:
            - Path=/product/**
 
        - id: order-service
          uri: lb://order-service
          filters:
            - StripPrefix=1
          predicates:
            - Path=/order/**
 
        - id: stock-service
          uri: lb://stock-service
          filters:
            - StripPrefix=1
          predicates:
            - Path=/stock/**
 
eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka-0.eureka.ms:8888/eureka,http://eureka-1.eureka.ms:8888/eureka,http://eureka-2.eureka.ms:8888/eureka

这里面就有服务注册中心,服务中心注册的地址信息是,如果点对点的方式去注册的,那么每一个节点的健康状态它都要实时的去更新。另外一个就是通过集中式的负载均衡或者分布式的负载均衡,那么会将统一入口的虚拟IP绑定上去。

典型的微服务业务场景


warehouse和accounting之间可能会有固定的调用关系,现在的系统架构是要面向失败去做设计的,去设计系统的时候要去假定任何的组件都是不可信的,accounting可能出现故障有两种可能,一种是可以返回错误码,一种是可能不响应了,对于不响应的话,那么很多应用在业务代码里面就写好了返回50x回来。如果是假死,那么warehouse是不知道accounting有问题,它会将请求转发到accounting等待其回复,如果应用写的不够好,不够健壮,那么它就会无限等待,但是它会认为accounting是正常的,因为accounting不返回给其任何的错误消息,那么sales就会继续将请求转发过来。

那么就会导致warehouse接收到很多sales海量的请求之后,这些请求没有有效的办法转发到accounting获取到返回值,那么warehouse这边积压的请求就会越来越多,这样使得warehouse也可能会出现故障。 

warehouse出现之后也可能引发类似的问题,那么每个组件都可能会被影响,这样就会导致每个局部的故障扩展到了全局。

很多时候warehouse需要熔断的能力,一个是你返回错误码,要能够正确的处理这个错误码。

还有就是如果你不返回错误码,那么至少要知道有多少个并发请求出去了,要限制对上面的并发请求,如果并发请求很多的时候要去做熔断和服务降级,告诉sales已经发出很多请求了,但是都没有被响应。那么现在没有办法处理更多请求了。

 既然是微服务架构体系,每个服务都有责任将其注册到服务注册中心,每个服务向下调用都是需要负载均衡的能力。

如果提供一个HTTP的服务出去,然后又不去做任何的校验。那么这个服务会被很多恶意或者非恶意的请求影响,这样就无法控制请求的有效性,频度等等。

如果服务提供了删除能力,如果不去做如何的校验鉴权的话,那么这个保护就无从谈起。

整个企业都会有一套认证鉴权的中心服务,每个应用都会接入到这个服务里面,服务和服务之间调用是要基于受信任权限的,我要知道你是谁,你要有这个权限才能够调用我。这里通常就会有auth server。

每个服务都会去和auth server去做连通的,去获取授权凭证的这么一个能力。

更加完整的服务架构


 客户端发起请求,服务器端响应这些请求,服务器端有业务逻辑,有平台能力。

那么完整的一个微服务框架里面融合了业务能力和平台能力这样一个整体。

系统边界


 平台能力和业务能力如何去梳理一下。

业务逻辑有哪些呢?有sales warehouse accounting discount,这些真正和业务相关的逻辑代码。

这些是业务的。

剩下的和认证相关的,熔断相关的,负载均衡相关的,还有协议相关的,这些和业务无关。这些更多的是平台侧的能力。就是业务和业务之间的调用,基于什么协议和什么样的诉求,这些都是平台侧统一拉通的。

这种架构通常分为两种,一种就是java程序员所熟知的spring cloud,这个项目里面整合了netfix,就是网飞这家公司的一些开源软件。这些开源软件有eurka,比如服务注册中心,或者说是ribbon,也就是做客户端负载均衡的。

这些就将很多开源的库,内嵌到了业务代码里面,业务代码在做平台侧能力的时候,那么业务代码和平台能力是需要做深度整合的。其次你要去任何的变更,其实是要去动部署的包的,比如你的服务发现能力,或者负载均衡能力的版本要升级一下,那么就需要对整个的war包去做升级。

这样业务侧和平台就变成了紧耦合的关系。

那么有没有一种更加优雅的方式,更加合理的方式使得业务归业务,平台归平台。能不能简化业务所面对的这些基础平台侧的需求。

将认证,服务发现。熔断的这些能力丢到平台侧,使得业务侧真真正正的只关心业务。这种模式就是服务网格所推荐的能力,也就是istio后面所追求的结果。

2.微服务到服务网格还缺什么?


k8s工作模式

所谓的服务网格就是有一些业务的pod,上端是a服务,下端有b服务。那么a服务到b服务的网络调用,基于service然后通过iptables或者ipvs的转发,你访问service帮你转发到后端的pod里面去。

真实的网络调用就是service a到service b这样的一个直接调用。这是k8s service的原生的实现。

springcloude工作模式

springcloud是如何做到的呢?它其实就是在service b在启动的时候它会将自己的服务注册到eurka里面去,告诉eureak有这三个实例。当a去调用的时候就会去问eureak服务后面有什么实例。

eureak就告诉它有这三个IP,实例a里面就会有ribbon,客户端负载均衡来通过既定的策略从这三个IP里面选择一个然后访问过来。

服务网格工作模式

它在每个应用进程的旁边,跑了一个反向代理的软件,它去解析用户请求,然后根据用户请求里面的包头,比如HTTP的header或者根据你的url,或者根据域名这些信息来将这个请求转到其他的IP上面了。

它是一个proxy是一个代理,它不直接处理请求,它负责转发这个请求,它根据用户请求里面的信息将请求转发到其他地址上面。

这是proxy的一个作用。

sidercar就是在每一个应用进程旁边,就去跑一个代理进程,这个进程就是用来做代理用的,a服务要访问b服务,原来是点对点的访问过去,现在通过某种透明的方式将流量抓到反向代理里面来,在反向代理里面就会按照你要访问b服务,那么sidercar proxy就知道有哪些b服务,它会将请求往对端分发,分发完到对端之后,对端的sidercar proxy同样的会去将流量抓过来,然后在这边做路由判决之后,再将请求给到pod应用这一层。

使用sidecar那么网络调用会多跳了两跳,这样会不会有额外的开销在这里?存在的现实意义是什么呢?

之前在讲容器的时候,通过标准的容器技术,把应用进程管控起来了,所有的资源配额,用量信息都是通过cgroup技术去实现的,那么针对容器平台的监控就变的很简单了,只要去读取cgroup的配置信息,那么就知道pod的资源用量。

有了sidecar之后,所有进来的流量和出去的流量,由点对点的通信变成了sidecar到sidecar之间的通信。那么sidecar和sidecar之间就可以协商做很多事情了。就比如监控,因为入栈和出栈流量都往这走,同时有是一个反向代理,这样就知道出去了多少请求,花了多少时间,目标的IP是什么。

这样就满足了监控的需求。sidecar和sidecar之间去做协商就可以去做所有的提到的服务注册和服务发现的能力。

统一的认证和鉴权的能力,协议升级的能力,熔断的能力,负载均衡的能力。

就是微服务场景下所有需要做的能力都可以由业务代码这一侧转移到sidecar这一侧。

service mesh


service mesh就是在原有的微服务框架下面增加了sidecar的能力,服务和服务之间的网络调用变成了sidecar之间调用,这样就变成了一个服务网格。sidecar和主容器的生命周期是保持一致的。

熔断,限流,故障处理等等,这种失败的控制让我们的应用适应性,健壮性更强的这些能力都可以基于服务网格去处理。

服务发现有更加灵活的路由策略,k8s的service是工作在四层的,当没有使用service mesh的时候,a服务访问b服务通常是给出b服务的服务名,由coredns帮你解析为clusterip,访问这个ip的时候由ipvs将请求dnat到pod的那一端。

负载均衡策略是很受限的,它是依赖于内核能力,内核只能解析到tcp这一层的包头。它只能拿到你的协议是什么,源端口是什么,源IP是什么,目标端口是什么,目标IP是什么。只能拿到这个5元组,只能基于这个5元组去做负载均衡。

所以它的负载均衡能力是很弱的,它不是专门的负载均衡能力。

有了服务网格是用软件去做负载均衡,应用软件是一个一个的反向代理软件,它是专门做负载均衡的,这里就有很多很多的能力,依据用户的header去做负载均衡,更加高级的负载均衡策略,有些支持根据后端真实服务器响应时间来做负载均衡,谁快就给谁,有很多很多高级的能力内核层是做不到的。

sidecar之间的协议升级使得tls证书的管理变成了servicemesh的一个重要能力。

统一的流量监控,看指标也好,看访问日志也好,这些都可以做一些体系支撑。

 

 

微服务的优劣


 为什么有了Spring clouded还要使用istio,Spring clouded是和语言相关的,它是一个比较成熟的微服务框架了,但是它只支持java语言。

如果公司不使用java怎么办?很抱歉市面上没有这种成熟的服务网格框架帮你去承载非java平台上面的熔断,限流这些能力诉求,istio就可以刚好适配这种场景。

istio是平台无关的,不管上面跑的是java还是go c,大家都可以很好的粘合在一起,因为是基于k8s这套实现,提供的底层能力,你上面跑了什么语言和它没有什么关系,它让你自由的选择技术栈,你不用绑死在一个语言上面。

弊端

变的更加复杂了,基于内核的网络流量还得从两次sidecar去绕一圈,这里面会有更加多的实例,有额外的进程,这些进程要做数据包的转发,也会吃资源,对资源也会有压力。

任何sidecar的跳转都是网络的一次跳转,会有网络延迟的增加。

还是得处理复杂的路由配置,复杂性是istio的一个最大问题。

 

服务网格可选方案


 第一个就是istio,其次是linkerd。当时选型毫无条件的站到了istio的后面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值