请详细论述服务颗粒度
user
服务颗粒度就是指一个服务包含的功能大小。
举个例子，对于电信九七系统中的营业受理来说，提交客户订单就是一个典型的粗粒度的服务，而实现这个提交订单服务的一系列内部操作，比如说创建客户资料，生成客户订单，记录产品属性，更新帐务关系等等就可能成为一系列细粒度的服务。细粒度的服务（fine-grained）提供相对较小的功能单元，或交换少量的数据。完成复杂的业务逻辑往往需要编排大量这种细粒度的服务，通过多次的服务请求交互才能实现。相反，粗粒度的服务（coarse-grained）则是在一个抽象的接口中封装了大块的业务/技术能力，减少服务请求交互的次数，但相应也会带来服务实现的复杂性，交互大量的数据，并因此而不能灵活更改以适应需求的变化。就像任何事物都有两面性一样，服务粒度不能太大或者太小，而应该大小合适。一个良好的SOA架构设计，必须在服务粒度设计上维护一种平衡，以获得成本降低，灵活响应的好处。#### 设计服务颗粒度需要权衡的三个方面

识别并设计一个粒度适中的服务.我们可以主要从以下三个方面权衡考量:
1.重用性
所谓重用性，就是指服务能够应用于不同上下文的能力。重用可以说是SOA的核心思维，通过重用获得降低开发维护成本，缩短应用交付周期，提升质量等种种好处。
与任何基于分解的范例相一致，颗粒度的大小直接影响到服务的可重用性。一个简单的经验法则就是细粒度的服务更容易被重用。换句话说，就是颗粒度越粗，服务越少被重用或者越难以被重用。因为随着颗粒度增加，越来越多的业务规则和上下文信息被嵌入到业务逻辑中，服务逐渐变得具有特定的业务意义。要使用它，我们必须首先了解它到底封装了哪些规则，否则我们无法确信这个服务正是我们所需要的。这并不意味着我们就不要构建粗粒度的服务，事实上粗粒度的服务往往还停留在”business-grained”层面，它让业务用户和IT人员可以直接对话，对业务有直接的意义，应该暴露出来。同时，如果我们仅仅机械地考虑重用性，将导致大量颗粒度很小的功能单元，这将对系统整体性能和容量带来严重的影响。就拿大家常用来描绘SOA的乐高玩具为喻，一个最小尺寸的1x1的乐高积木，带有一个标准的凸起接口，通过它几乎可以与任何其它乐高积木拼装出任意可以想想的物体，其广泛的重用性是不言而喻的。但是当你真正尝试用这种粒度的积木完成一个复杂物体拼装的时候，你可能会感叹：“Oh,MyGod!It’smissionimpossible!”，因为，为此付出的时间和成本的代价几乎是不可接受的。因此，我们在一心希望构建美好的重用世界之前，需要先掂量清楚服务颗粒度的选择。
在这里，我借用关于演讲的一个有名的“迷你裙定律”来尝试表达服务颗粒度的选择上的权衡之道。“mini-skirttheory”告诉我们，一个出色的演讲应该“shortenoughtokeeppeopleinterested,butlongenoughtocovertheimportantpart”。套用在服务颗粒度的选择上，一个设计良好的服务应该“fine-grainedenoughtobereusable,butcoarse-grainedenoughtomakebusinesssense”。
2.灵活性
所谓灵活性，就是能够容易地因情形做出改变的能力。SOA的目标之一就是让IT变得更灵活，能够更快地适应持续变化的业务环境。因此，灵活性作为设计良好的服务的重要考量，理所当然地也是选择服务粒度的重要标准之一。众所周知，细粒度的服务可以更容易地组装，为交付新的业务功能或改变业务流程提供了更多的灵活性。但是，仅仅考虑灵活性将导致大量的细粒度的服务，带来昂贵的开发成本，并使得维护变得困难。因此，在考虑业务流程灵活性的同时，考虑后台服务的良好组织、效率和开发维护成本，对于识别和设计粒度适中的服务是至关重要的。
我们知道，服务识别方法之一就是top-down的一级级流程分解，直到不能或者不需要进一步分解为止，其中识别出来的的业务活动就是候选的业务服务。因此，一个有效的经验法则就是区别对待不同的业务流程，因为并不是每一个业务流程都需要相同的灵活性。如何确定哪些流程需要更多的灵活性，哪些流程不需要，可以参考SAP就企业业务流程的一个观点。SAP将流程划分为核心流程（coreprocess）和支撑流程(contextprocess)。其中，支撑流程是指那些不可或缺的，但又不影响企业差异化的流程，如财会管理流程等，它们关注的是如何提升生产效率，降低生产成本。因此这些流程在分解过程中，一旦识别出自治的（事务一致、上下文独立的）、粗粒度的服务就可以结束，因为它们相对稳定。而核心流程是指企业独特的，差异化的，代表企业竞争力的业务流程，如营销销售流程等。它们需要比支撑流程更细粒度地分解，以获得最大的灵活性，因为它们是时刻变化的。
3.性能
灵活性和效率往往是成对出现的，性能因素自然也是限制服务粒度不能太大或者太小的约束之一。DanFoody曾在他的weblog里建议Webservice的每一个operation执行应该在5ms到5s之间完成，小于5ms或者大于5s就意味着服务粒度要么太小，要么太大。我在这里倒不想评价这个量化的指标有多大指导意义，而是借此希望引起大家的思考，并不是服务粒度越小或者越大，系统性能就会一定越好。
一个服务本身的复杂度以及业务到服务映射的复杂度（即实现一个业务活动所需的服务调用次数）是影响SOA性能的两个主要方面。服务颗粒度越大，意味着包含的功能越多，业务逻辑越复杂，网络延迟就会增加，对客户端响应变慢。而服务颗粒度越小，也就意味着包含的功能越简单，虽然单个服务执行效率很高，但从业务意义上，完成一项业务任务所需的服务调用次数越多，来回请求响应次数增加。一般来说，服务都是远程调用的，这种来回请求响应的次数增加意味着显著的性能开销。因此，为了保证服务的性能可控，一方面需要限制服务包含的功能范围和复杂度，也就是说服务粒度不能太粗；另一方面需要限制服务调用的次数和复杂度，也就是说服务粒度不能太细。我想这才是前面提到的5ms和5s背后真正的原因。很显然，二者的着眼点是背离的，为了符合性能的需求，需要在二者之间折中妥协。
除以上几点之外，还存在其它可能影响服务颗粒度决策的因素，比如服务类别和使用范围等等。如果服务使用的范围有限，如仅仅在Intra-Application范畴，则可以选择相对较细粒度的服务接口，为服务请求者提供更多的灵活性；随着范围扩大，服务大小也应随之扩大，如Multi-Enterprise的范畴，则要求服务尽可能提供粗粒度的、较稳定的接口，保证服务请求者以一致的方式使用系统中所暴露出的服务。最后，需要记住的一点是，服务的颗粒度在其生命周期内不是一成不变的，它是随着业务的调整变化，以及服务的迭代发展过程，不断演化精炼、甚至重构的。
assistant