一、背景
过去,我们运维着“能做一切”的大型单体应用程序。这是一种将产品推向市场的很好的方式,因为刚开始我们也只需要让我们的第一个应用上线。而且我们总是可以回头再来改进它的。部署一个大应用总是比构建和部署多个小块要容易
。
- 集中式
- 集群
- 分布式
- 分布式和集中式会配合使用。
我们在搭建网站的时候,为了及时响应用户的请求,尤其是高并发请求的时候,我们需要搭建分布式集群来处理请求。我们一个服务器的处理能力是有限的。如果用我们一台设备当作服务器,那么当并发量比较大的时候,同一时间达到上百的访问量。那服务器就宕机了。然后只能重启服务器,当出现高并发访问的时候,就又会宕机。所以我们需要更多的服务器来并行工作,处理用户的请求。那么问题来了,我们服务器运行的时候,怎么分发大量的请求给不同的服务器呢?一般会采用(1apache+nTomcat)或者服务器模式来分发并处理请求。或者采用nginx分发请求。微服务是运行在自己的进程中的可独立部署的服务套件。
他们通常使用 HTTP 资源进行通信,每个服务通常负责整个应用中的某一个单一的领域。 在流行的电子商务目录例子中,你可以有一个商品条目服务,一个审核服务和一个评价服务,每个都只专注一个领域。用这种方法让多语言服务(使用不同语言编写的服务)也成为可能,这样我们就可以让 Java/C++ 服务执行更多的计算密集型工作,让 Rails / Node.js 服务更多来支持前端应用等等。
微服务会成为大规模分布式应用的主流架构。任何复杂的工程问题都会归结为devide and conquer(分而治之),意思就是就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……
直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。微服务本质是对服务的拆分,与工程领域惯用的“分而治之”的思路是一致的。
二、Spring Cloud 与 K8S 对比
两个平台 Spring Cloud 和 Kubernetes 非常不同并且它们之间没有直接的相同特征。
两种架构处理了不同范围的MSA障碍,并且它们从根本上用了不同的方法。Spring Cloud方法是试图解决在JVM中每个MSA挑战,然而Kubernetes方法是试图让问题消失,为开发者在平台层解决
。Spring Cloud在JVM中非常强大,Kubernetes管理那些JVM很强大。同样的,它就像一个自然发展,结合两种工具并且从两个项目中最好的部分受益。可以看到,里面差不多一半关注点是和运维相关的。这么看来,似乎拿spring cloud和kubernetes比较有点不公平,spring cloud只是一个开发框架,对于应用如何部署和调度是无能为力的,而kubernetes是一个运维平台。
也许用spring cloud+cloud foundry去和kubernetes比较才更加合理,但需要注意的是,即使加入了cloud foundry的paas能力,spring cloud仍然是“侵入式”的且语言相关,而kubernetes是“非侵入式”的且语言无关。
三、Spring Cloud vs Istio
这里面哪些内容是我们可以拿掉或者说基于 Service Mesh(以 Istio 为例)能力去做的?分析下来,可以替换的组件包括网关(gateway 或者 Zuul,由Ingress gateway 或者 egress 替换),熔断器(hystrix,由SideCar替换),注册中心(Eureka及Eureka client,由Polit,SideCar 替换),负责均衡(Ribbon,由SideCar 替换),链路跟踪及其客户端(Pinpoint 及 Pinpoint client,由 SideCar 及Mixer替换)
。这是我们在 Spring Cloud 解析中需要完成的目标:即确定需要删除或者替换的支撑模块。
可以说,spring cloud关注的功能是kubernetes的一个子集
。可以看出,两边的解决方案都是比较完整的。kubernetes这边,在Istio还没出来以前,其实只能提供最基础的服务注册、服务发现能力(service只是一个4层的转发代理),istio出来以后,具有了相对完整的微服务能力。而spring cloud这边,除了发布、调度、自愈这些运维平台的功能,其他的功能也支持的比较全面。相对而言,云厂商会更喜欢kubernetes的方案,原因就是三个字:非侵入。平台能力与应用层的解耦,使得云厂商可以非常方便的升级、维护基础设施而不需要去关心应用的情况,这也是我比较看好service mesh这类技术前景的原因。
四、Spring Boot + K8S
如果不用 Spring Cloud,那就是使用 Spring Boot + K8S
这里就需要介绍一个项目,Spring Cloud Kubernetes,作用是把kubernetes中的服务模型映射到Spring Cloud的服务模型中,以使用Spring Cloud的那些原生sdk在kubernetes中实现服务治理
。具体来说,就是把k8s中的services对应到Spring Cloud中的services,k8s中的endpoints对应到Spring Cloud的instances。这样通过标准的Spring Cloud api就可以对接k8的服务治理体系
。老实说,个人认为这个项目的意义并不是很大,毕竟都上k8了,k8本身已经有了比较完善的微服务能力(有注册中心、配置中心、负载均衡能力),应用之间直接可以互相调用,应用完全无感知,你再通过sdk去调用,有点多此一举的感觉。而且现在强调的是语言非侵入,Spring Cloud一个很大的限制是只支持java语言(甚至比较老的j2ee应用都不支持,只支持Spring Boot应用)。所以我个人感觉,这个项目,在具体业务服务层面,使用的范围非常有限。借助于Spring Cloud Kubernetes项目,zuul可以以一种无侵入的方式提供api网关的能力,应用完全不需要做任何改造,并且网关是可插拔的,将来可以用其他网关产品灵活替换,整体耦合程度非常低
。得益于k8的service能力,zuul甚至支持异构应用的接入,这是Spring Cloud体系所不具备的。而本身基于java开发,使得java程序员可以方便的基于zuul开发各种功能复杂的filter,而不需要去学习go或者openresty这样不太熟悉的语言。
https://lupeier.com/post/cloud-native-api-gateway-part-2/
五、Service Mesh的价值
无论是单体应用,还是分布式应用,都可以建立在Service Mesh上,mesh上的sidecar支撑了所有的上层应用,业务开发者无须关心底层构成,可以用Java,也可以用Go等语言完成自己的业务开发
。当微服务架构体系越来越复杂的时候,需要将“业务服务”和“基础设施”解耦,将一个微服务进程一分为二。service mesh 的一个理念就是:将网络路由这一层,和开发应用进行隔离,所以他管理的就是每个节点的sidecar,将限流,日志追踪,异常处理这些,开发无需再关心,全部交由网络路由处理,开发更关注于业务
为什么代理会叫sidecar proxy?
看了上图就容易懂了,biz和proxy相生相伴,就像摩托车(motor)与旁边的车厢(sidecar)。未来,sidecar 和 proxy 就指微服务进程解耦成两个进程之后,提供基础能力的那个代理进程
。Istio 的理论概念是 Service Mesh(服务网络),我们不必纠结于概念实际也是微服务的一种落地形式有点类似上面的SideCar模式,它的主要思想是关注点分离,即不像 SpringCloud 一样交给研发来做,也不集成到 k8s 中产生职责混乱,Istio是通过为服务配 Agent 代理来提供服务发现、负截均衡、限流、链路跟踪、鉴权等微服务治理手段
。Istio 开始就是与 k8s 结合设计的,Istio 结合 k8s 可以牛逼的落地微服务架构。Istio 超越 spring cloud 和 dubbo 等传统开发框架之处, 就在于不仅仅带来了远超这些框架所能提供的功能, 而且也不需要应用程序为此做大量的改动, 开发人员也不必为上面的功能实现进行大量的知识储备。
但结论是不是 Spring Cloud 能做到的,k8s + istio 也能做到?甚至更好?
每个service之间通过sidecar互相访问调用,不再需用有传统的k8s的service层的概念,通过sidecar就可以进行负载均衡,熔断,限流
。而linked istio consul等是service mesh理念的实现