标签:
这里说到的“服务”,本质上来说,就是指“RPC”。单纯的RPC功能实现,其实很简单,无非就是client发起调用,中间某个组件(甚至就是client本身)拦截调用信息,序列化后将信息传输到server端,server端收到调用请求后反序列化,根据请求详细发起实际调用后返回响应传输回给client端。这样的RPC很常见,比如常见的存储过程调用就是一例。但是在一个复杂的业务环境,如何管理和协同这些大量的RPC才是最麻烦的事情。所以,在此谈的“服务化”更多指的是对RPC的管理。
=》数据序列化
为整个环境里的服务采用统一的数据序列化协议,其益处是显而易见的,能大大降低服务提供者和服务调用者之间的沟通成本,同时也可以为服务提供者减少应对不同数据协议需求而带来的代码复杂性。所以,在开始设计一个服务化框架时,第一件重要的事情就是选定一个标准的数据序列化协议。如何选择合适的序列化协议重点需要从扩展性,传输性能以及业界通用性(换句话说就是不同技术/语言的支持程度)三个因素里来协调选择。当前看来,在这三个方面都做的比较好,也是使用最广泛的就是Json和Protobuf了,基于文本的Json在可读性和灵活性上占优,而基于二进制的Protobuf在传输性能生更胜一筹。而如果整个环境开发的技术栈比较统一,比如全是Java/.NET,也可以选择对这一技术更加友好的序列化协议。我比较喜欢Json,因为从面对的业务情况来看,传输性能不是根本矛盾,而灵活性要求较高,同时服务使用者使用的技术也较为多样化。
挑战一:研发成本高
2008年我来北京参与当时华为的一个TOP3的项目,甲方是中国移动。那时公司也刚做Java类的软件,还没有服务框架和中间件,唯一有的是外部的框架。我们要做的是后台消息类系统,前端界面非常少。分工和协同完全靠人工来进行,并且没有考虑交互,当时面临着代码重复率高、需求变更困难和无法满足新业务快速上线和敏捷交付这些难题。
挑战二:运维效率低
对于运维感受比较深的是07年我在东软做一个ERP的系统。主要问题包括:
测试、部署成本高:业务运行在一个进程中,因此系统中任何程序的改变,都需要对整个系统重新测试并部署。
可伸缩性差:水平扩展只能基于整个系统进行扩展,无法针对某一个功能模块按需扩展。
可靠性差:某个应用BUG,例如死循环、OOM等,会导致整个进程宕机,影响其它合设的应用。
代码维护成本高:本地代码在不断的迭代和变更,最后形成了一个个垂直的功能孤岛,只有原来的开发者才理解接口调用关系和功能需求,新加入人员或者团队其它人员很难理解和维护这些代码。
依赖关系无法有效管理:服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
解决对策
要解决上面的问题,我们采用的主要的第一个措施是拆分,包括水平拆分和垂直拆分。拆完以后我们会发现我们按业务的领域形成各种各样的一个独立的集群的中心,一个资源的池子。我们在开发应用的时候都会发现无论需求怎么去变化,其实它容易发生变化就是20%左右的功能,其实最终我们要把变化给隔离出来,控制这个变化。做法就是要抽取和识别我们的核心,我们的公共的要沉淀到下层形成一个公共的独立能力层,然后逐渐形成稳定的一个服务能力中心再下沉。前端包括中间编排层的变化给它抽象出来,做一个消费者去做。这样前后端分离以后,我们就可以有效的去管理。能管控住变化以后的需求变更,包括测试和整个的成本其实都是可以得到一个有效的控制。
传统的SOA概念,指的是不同的应用系统之间相互通过大粒度服务的方式进行集成。而当今的服务化架构已经摆脱了这一概念的束缚,更多讲的是系统内部模块级甚至是功能级的服务化模式。也就是说服务实现的粒度更小了。这当然为应用和服务的实现带来了更强的灵活性,服务交付周期也大大缩短了。但这样的细粒度拆分服务,带来的问题是项功能的实现需要访问的服务数量成倍的增加。如下图所示:一个客户下订单的功能实现需要分别访问:客户信息服务,产品类别服务,库存服务,订单管理服务等。
图1:
这将显著增加功能实现的复杂性。为了解决这一问题,我们只能再次使用那条永远有效的“中间层定律”:任何计算机问题都可以通过中间加一层来解决。我们可以将相应的服务组合成一个新的服务提供出去,比如上面的例子,我们可以按以下方式组合:
图2:
服务提供者会把它的服务注册到注册中心,消费者会去订阅拉取这些消息,然后在本地缓存一个提供者的信息。这样每一次交互的时候,只查本地内存就可以了,不需要强依赖这个注册中心,实际上对服务中心依赖就是一个弱依赖。
在我们实际设计过程中,很希望这个服务框架或者服务化对上层应用的侵入尽可能小,但百分百零侵入是做不到的。通过配置化的方式——即Spring的方式,通过配置和扩展、消费、发布,其实配置本身是一个侵入,是代码的一部分。但是这个有的好处是我们改一个代表总比去编译它强。就是说我们尽量少的开放服务框架的API给上层,而开放的都是一些特性和配置化的方式,或者是用注解也可以。这样的话,未来我们的服务框架无论是底层做什么样的整合和重构,其实我们都不用再担心。
1:微服务架构
第一个重大演进是微服务,谈了两年。我的体会是首先它是一个架构的分隔,一定在可预见的未来不会有标准。根本的就是在演进的过程中,我们会发现服务完了以后还会遇到一些新的挑战,包括要敏捷交付、实现更细化的隔离和交互。如果我们没有一套好的工具和流程,能够把微服务治理好的话,去做微服务的话还是会面临很多问题。包括一些团队的分工,就像亚马逊的团队,构建全栈小分队,实际上就是大概四到五个人的规模。这个人负责他所属的微服务从开发、测试、打包、部署、上线、运行、修复都由这个团队统一负责。跟传统的研发是研发,测试是测试,运维是运维,分工还是有差异的。其实团队能不能去接受,或者团队整个实践的效果,也能决定你整个实施的结果。
所以对微服务我的一个判断就是说水到渠成,如果你的服务化实施了很多年,你已经遇到需要向微服务演进的时候,自然而然就能演进。如果你不具备这样一个基础设施去强推的话,效果肯定会非常差。
2:基于Docker部署微服务
今年很流行一句话,就是说微服务天生是部署在Docker里面。为什么呢?因为拆完这么多东西以后,首先我们一定要考虑部署要快,以前我一次性打包部署,跟我去部署十台虚拟机的速度不一样,所以说它的成本会让应用感觉我没法真正拆开独立部署。有了Docker以后,比如Docker的秒级和创建以及资源的隔离、使用、消费,这些特性都决定了一个微服务或者若干个微服务运行在一个Docker容器里,是非常适合的一种部署策略。
我们看一下Docker的服务特点,除了高密度、快速部署微服务以外,其实还有一个优势,比如说一致的环境、避免对特定云基础设施提供商的依赖,包括对它的依赖性等等的特性,我们都可以享受。
3:云上的微服务
云化以后有一个问题,我原有的微服务包括我原有的服务也会迁移到云上,所以它会享受到另外一个特性,比如说云上的弹性伸缩和资源的灵活快速调度。迁移到云上以后,我的服务本来能够自动发现。有了这个弹性伸缩以后,我结合服务性能的KPI数据加上我的阈值值,我就可以实现自动化的运维,到时候扩容的时候就不需要人工干预,我需要自己做。
还有一个是虚拟机,有了虚拟机以后我们发现对资源的隔离就可以做的更好了,VM可以跨的非常小。这个时候我就可以利用它的故障隔离实现更细力度的隔离。比如说我们以前担心某个微服务,其实做了故障隔离以后,其实还是会宕机,这个时候可以通过VM把它隔离起来,做VM级的故障隔离。有了云以后,提供了很多的特性,如果能和我们已有的服务框架结合起来,会能带来很多的价值,对运维的价值其实就可以帮助我们以前很多手工的运维,就可以通过上云以后的服务实现自动化运维,当然还有很多和云的结合,这是需要缓慢的一个演进过程。
标签:
原文地址:http://blog.csdn.net/u013628152/article/details/51262198