微服务架构的演变
单体模式下面一个应用通常会有一个app server,这个app server里面会有不同的子模块,每一个模块都写在同一个应用包里面,模块和模块之间的边界有些时候设计的不是特别清晰,特别早期代码混合在一起那么意味着互相的调用。
这种比较重的单体架构还是通过冗余部署和负载均衡来保证应用的高可用。
单体架构不再适合复杂的业务需求,我们会去做一些业务架构的调整,取而代之的是一个一个的子系统,这些子系统有独立的部署文件,有着独立的生命周期。每个子系统高可用的诉求也是不一样的,子系统和子系统通过网络调用来完成整个业务。
原来一个单体系统,单实例单进程这样一个模式就会变为成百上千个子服务形成统一的部署视图。
这个时候再去人肉一个一个的去管控,那么代价会非常的大,出错的机率会非常的高。这样就需要依赖自动化的方式去完成应用的配置和服务发现的能力。
从单块系统到微服务系统的演进
假设说有一个网店,销售有一个销售模块,提供门户卖东西。网店卖的货要有存储,有个仓库管理系统去管理库存。后面还有计费,折扣这些诉求。针对于单体应用就会提供到单体应用的功能里面去。
既然是同一个进程,那么只要告诉我地址我就可以访问到所有的服务。
微服务架构演进
要将单体应用拆分为微服务架构,这样就将一个应用进程里面不同能力拆分为不同的子系统,每个子系统承担自己的职责。
sales既然支撑了前端的业务,那么它的可用性的要求会高,它所支持的并发请求也就会越多,这里就可以去部署更多的实例,提供更多的负载并发的支撑,然后提供更高的可用性。
网络要为每一个系统打通,包括服务和服务之间的调用。为了解决这种复杂的耦合性就可以使用api gateway。集群里面可以有很多很多的服务,这些服务可能通过同一个域名暴露出去,那么就需要一个api网关的,这个网关接受不同的客户诉求,然后经由网关转发到不同的服务。
服务和服务之间的调用就需要有服务发现的机制,那么就需要服务注册中心,每个服务起来之后要将自己注册上去,并且不同的renew去说我活着。他要去注册自己的健康状态,其他人再去做服务调用的时候知道这个服务有哪些真实的服务器跑在后面。
这里面就有服务注册中心,服务中心注册的地址信息是,如果点对点的方式去注册的,那么每一个节点的健康状态它都要实时的去更新。另外一个就是通过集中式的负载均衡或者分布式的负载均衡,那么会将统一入口的虚拟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后面所追求的结果。