新来老大年前开会说:各位同学,公司业务越来越重,未来几年要成倍增长......,我们要梳理出一套新架构,才能更好的支持N万用户.....,以后升职加薪当上....打败..... 
想想还有点小激动呢,于是过年时楼主趁等待相亲妹纸无聊的时候,反思了目前系统现状,构思设计新架构如下。

阅读目录:

  1. 现有系统
  2. 新架构    
    2.1 逻辑架构图 
    2.2 解释说明
  3. 系统实施
    3.1 SOA管理中心
    3.2 发布服务
    3.3 订阅服务
    3.4 采蘑菇示例
  4. 设计目标
    4.1 尽可能少的侵入
    4.2 服务自治&&水平扩展
    4.3 系统升级降级
  5. 常见问题
    5.1 ClientApi VS ServiceApi
    5.2 聚合服务
    5.3 服务分级
  6. 总结心得

现有系统

鄙司业务比较重,系统也有些年头,各研发团队、系统都比较稳定了。所以不差也不太好,总之也能满足现有需求。但近2年O2O,移动互联网等大行其道,老大们也都心动了,开始磨刀霍霍了。而现有系统应对复杂的变化,在一些地方颇显不足:

  • 接口没有统一管理
  • 很多组件无法复用/重复造轮子
  • 模块间职责不清,耦合过深
  • 联调排查问题比较慢
  • 开发前规划不足,形成堆积
  • 缺乏API规范/文档较少

新架构

逻辑架构图:

查看大图

解释说明:

  • A开头:是系统级别,可以独立部署。即可寄宿在IIS/WindowsService等上面。
  • B开头:是模块级别,不可独立部署。相对独立的功能模块,而又不大,所以依附其他系统或者和多个模块组成一个子系统。模块级别在项目中可以分多层,可根据分数升级成子系统(见系统升级降级)。
  • C开头:是组件级别,不可独立部署。大多数是公共性组件,一般是单独类库存在,以DLL提供使用。一些开源组件也归到这里,例:Autofac,FluentData。 需要自搭Nuget服务器,进行统一版本管理。
  • 字母后面的数字:是代表服务的级别,见服务分级。
  • 系统通信: 各系统之间尽量走内网Wcf/Tcp,对外合作单位及各移动端走WebApi/Http。
  • 传输格式: Protobuffer、Json。
  • 数据交换: 优先通过数据服务接口,其次SSIS、Job。
  • 基础平台: 缓存Redis,队列RabbitMq等。依赖抽象,框架可替换。
  • DB 层: 每个子系统拥有自己的子DB,原则上不能跨库读其他的。
  • 高可用 : 子系统自行做负载,服务变更通知使用zookeeper。
  • 单向2级:只能订阅服务,不能发布服务,2级只能订阅2级服务。
  • 定点:某个客户端只能订阅某个服务端提供的服务。

系统实施

SOA管理中心

这是新架构的核心部分,主要功能如下:

  • 提供发布/订阅/ServiceAdapter组件
  • 提供Web管理界面
  • 对服务访问的各种配置
  • 在高峰期对服务限流/报警
  • 服务访问授权、描述

发布服务

各系统通过Web管理页面进行服务配置发布。
也可以通过管理中心提供的组件,进行配置发布:

    protected void Application_Start()
{
ServicePublisher.Pushlish(new ServiceConfig()
{
ServiceName = "获取预订单详情",
Qps = 1000,
Level = 1,
Key = "xxxx-yyyy",
Source = SubscribeSource.All,
ServiceAddress = "/Order/GetDetail",
//其他
});
}
[ServiceFilter]
void GetDetail()
{
}

订阅访问服务

各系统通过管理中心提供的组件,去获取订阅的服务,然后通过适配器去访问接口,服务变更在心跳里面做:

    protected void Application_Start()
{
//获取服务列表
var serviceList = ServiceManager.GetServiceList();
GlobalService.ServiceList=serviceList;
}
void Heartbeat()
{
var serviceList = ServiceManager.GetServiceList();
GlobalService.ServiceList=serviceList;
}
ServiceAdapter.Access(GlobalService.ServiceList[0]);

采蘑菇示例

设计目标

尽可能少的侵入

这点是非常重要的,如果不能很好的重用已有的系统或侵入性太强,势必会导致:

  • 新架构周期过长,长期维护二套结构。这种情况下,成本太高,不好推行下去或者还未推行就被砍了。
  • 开发人员的抵抗,每个猿类内心都有桀骜的脾气、造轮子的天赋、重组世界的梦想...。如果太复杂、约束太强,天知道你们这群猿类会干出什么事情!

基于这种考虑,才采用服务分布式而不是服务集中式。

  • 每个系统在需要时,去订阅服务,然后拉取服务地址/MyNeedServcie.list。
  • 然后通过ServiceAdapter访问服务,ServiceAdapter中会做权限等一些校验。
  • 在服务上增加ServiceFilter,Fileter会做权限校验及服务被调用的信息采集。
  • 然后在管理中心添加服务,文档描述。

好处是:A系统与B系统是直接交互的,服务调用不走中转路由,性能也好。而组件的作用仅是辅助性的约束。

服务自治&&水平扩展

由于侵入性较小,所以各个系统之间的服务变更,维护完全由各自研发团队维护。
本系统之间通讯不走服务,直接内部调用。调用通过ServiceAdapter组件访问,ServiceAdapter包含对进程内、WCF、WebApi等访问的封装,这样便于以后替换成其他服务。 各服务在扩展上不受管理中心节制,自行做负载、增加服务器即可。

系统升级降级

当有个新需要过来时,会根据产品是否需要独立部署,和现有系统耦合性等因素,来评估是模块级还是系统级。
对于旧模块,根据重要程度、访问量等评估出分数。达标的由模块抽离出子系统,单独管理。
同样对于旧系统,不达标的进行降级处理,缩小成模块整合到其他系统里面。

这块其实很重要,如果不对项目做好评估的话,往往会导致一个系统越来越沉重。最后的结果就是维护越来越麻烦,经常出问题。最后逼不得已就推到重来,这个成本就较大些,当然成本的事情老大会考虑更多些。处于这种情况下猿类们会一边吐槽着之前的同类渣渣,一边跃跃欲试准备大展身手,让你们瞧瞧什么叫DDD、TDD、设计模式......。

前提是在需求开发时,按模块进行分小层而不是整个大层,这样方便协作开发和抽取成子系统。

常见问题

ClientApi VS ServiceApi

ClientApi这个在前期用的比较多的办法。优点很明显:简单快捷,从Nuget上安装引用即可。这样后期会问题越来越多。
就拿缓存Redis来说,多个系统都使用客户端直接访问Redis服务器。如果有个系统连接数忘记关闭,就会影响整个大系统,原因就是Client权限过大,客户端是可以对redis服务器直接进行操控。这种情况下redis服务器本身是暴露在外的,哪怕客户端封装的再好也不行,只要研究下通信协议规范,就可以自己写个客户端连(参见:c#实现redis客户端(一))。 这个通信期间无法管控,无法做拦截,同样队列等其他也是同样情况。

ServiceApi:

我们在中间加了一层,在缓存系统里面做管控,同样依赖抽象,Redis可替换。缓存系统以服务的形式发布给其他系统使用。 避免不了的就是性能有损耗,当然这个损耗可以通过一些手段减小。

聚合服务

服务的颗粒度一直是SOA设计的头疼事情。太粗了就很难复用,太细了需要多次往返交互,其性能、事务处理都是个问题。 比如下订单服务,这个过程中包含创建用户资料,生成预订单、支付订单,更新账务关系,更新库存等一系列的操作。这是个粗粒度服务,里面包含若干子系统的提供的细粒度服务。 粗粒度服务下,多个子系统避免不了互相交互,长久下去会让系统过于沉重,变得职责混乱。
服务设计准则就是让服务高内聚,服务之间松耦合、边界清晰。所以我们抽离一个聚合服务系统,它专门负责把各系统提供的细粒度服务进行整合,提供给前端使用。而其他各个系统只做自己职责之内的事情。 在聚合服务系统中,方便我们更合理的把控服务的颗粒度,提高服务复用。

服务分级

多个研发团队协作时,很难每个人都对全部业务熟悉。所以为了避免服务调用混乱,甚至循环依赖调用,增加了对服务的分级。
按图中所示,1级服务不能调2级服务,即低级不能调高级,高级可调低级,同级互相可调。
这个级别针对单个服务而分的。比如有个更新库存服务,它没有外部依赖的服务,只是更新自己的DB,这样我们就可以把它划分为1级服务。 而我们的聚合服务系统中有个下订单粗粒度服务,它内部调用更新库存服务,那么它就是2级服务。很明显这里的1级不应该调用2级,对服务分级也是这个目的。

总结心得

    • 好架构是不断进化来的
    • 尽可能考虑到每个细节
    • 注重整体平衡性,而非局部最优
    • 依赖抽象,而不是具体哪个框架技术
    • 先考虑人、资源,在考虑用哪个技术
    • 跟妹纸相处时不要想程序那点事

http://www.cnblogs.com/mushroom/p/4298461.html

给公司部门设计的SOA架构(转)的更多相关文章

  1. 给公司部门设计的SOA架构

    新来老大年前开会说各位同学,公司业务越来越重,未来几年要成倍增长......,要梳理出一套新架构,才能更好的支持N万用户.....,以后升职加薪当上....打败..... 想想还有点小激动呢,于是过年 ...

  2. 设计的SOA架构

    新来老大年前开会说各位同学,公司业务越来越重,未来几年要成倍增长......,要梳理出一套新架构,才能更好的支持N万用户.....,以后升职加薪当上....打败..... 想想还有点小激动呢,于是过年 ...

  3. SOA架构简介

    一. 什么是SOA 架构 SOA是一种架构模型,它可以根据需求通过网络对松散耦合的粗粒度应用组件进行分布式部署.组合和使用.服务层是SOA的基础,可以直接被应用调用,从而有效控制系统中与软件代理交互的 ...

  4. SOA架构设计经验分享—架构、职责、数据一致性

    阅读目录: 1.背景介绍 2.SOA的架构层次 2.1.应用服务(原子服务) 2.2.组合服务 2.3.业务服务(编排服务) 3.SOA化的重构 3.1.保留服务空间,为了将来服务的组合 4.运用DD ...

  5. SOA架构设计(转发)

    阅读目录: 1.背景介绍 2.SOA的架构层次 2.1.应用服务(原子服务) 2.2.组合服务 2.3.业务服务(编排服务) 3.SOA化的重构 3.1.保留服务空间,为了将来服务的组合 4.运用DD ...

  6. [转]SOA架构设计经验分享—架构、职责、数据一致性

    阅读目录: 1.背景介绍 2.SOA的架构层次 2.1.应用服务(原子服务) 2.2.组合服务 2.3.业务服务(编排服务) 3.SOA化的重构 3.1.保留服务空间,为了将来服务的组合 4.运用DD ...

  7. 【转】SOA架构设计经验分享—架构、职责、数据一致性

      1.背景介绍       最近一段时间都在做系统分析和设计工作,面对的业务是典型的重量级企业应用方向.突然发现很多以往觉得很简单的问题变得没有想象的那么容易,最大的问题就 是职责如何分配.论系统架 ...

  8. SOA架构设计和相关案例分析

    一.SOA概念 1.定义: SOA,是一个组件模型,面向服务的体系架构,它将应用程序的不同服务通过这些服务之间定义良好的接口和契约联系起来,不涉及底层编程接口和通讯模型.服务层是SOA的基础,可以直接 ...

  9. 企业SOA架构设计理论

    SOA简介 SOA(Service-Oriented Architecture,面向服务架构)是一种将信息系统模块化为服务的架构风格.拥有了服务之后,我们就可以迅速地将这些服务按不同方式重新组合,从而 ...

随机推荐

  1. 大白痴学习webmagic

    摘要 webmagic 学习 从头 刚刚开始学,很多东西可能理解错了,还请各位指教 一些基本类: Request:包含要爬行的url和一些附加信息,是Page的一个成员变量 主要成员变量 String ...

  2. cocos2d-x游戏开发系列教程-坦克大战游戏之坦克的显示

    1.先定义坦克的一些属性 class Tank : public CCSprite { public : Tank(); ~Tank(); static Tank* createTankWithTan ...

  3. inner join、left join、right join中where和and的作用

    inner join.left join.right join中where和and的作用 .内连接(自然连接): 只有两个表相匹配的行才能在结果集中出现 2.外连接: 包括  (1)左外连接 (左边的 ...

  4. ARM过程调用标准---APCS简单介绍

    介绍 APCS,ARM 过程调用标准(ARM Procedure Call Standard),提供了紧凑的编写例程的一种机制,定义的例程能够与其它例程交织在一起.最显著的一点是对这些例程来自哪里没有 ...

  5. js数组基础整理

    首页: 主要整理了一下数组中常用的一些基础知识,代码都是自己手敲,有不对的地方希望能指出,目前只有4篇,后续会不断的增加这一板块. 由于少于100字不能发所以把一些最基本的创建数组也写上. // 创建 ...

  6. css盒模型和块级、行内元素深入理解

    盒模型是CSS的核心知识点之一,它指定元素如何显示以及如何相互交互.页面上的每个元素都被看成一个矩形框,这个框由元素的内容.内边距.边框和外边距组成,需要了解的朋友可以深入参考下 一.CSS盒模型 盒 ...

  7. javascript 判断IOS版本号

    先来观察 iOS 的 User-Agent 串: iPhone 4.3.2 系统: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; ...

  8. 九道大型软件公司.net面试题!一定得看(附答案)

    1:a=10,b=15,在不用第三方变量的前提下,把a,b的值互换   2:已知数组int[] max={6,5,2,9,7,4,0};用快速排序算法按降序对其进行排列,并返回数组   3:请简述面向 ...

  9. 暴力拆解CPU

    http://www.ruanyifeng.com/blog/2010/11/cpu_autopsy.htmlhttp://bbs.mydigit.cn/read.php?tid=110272http ...

  10. [置顶] 关于redhat系统yum源的配置1

    安装过Linux软件的用户就知道,有时我们安装一个软件,需要依赖其他软件,所以必需找全所有的软件,这是一个极其麻烦的事情,有没什么方式可以让它自己去找依赖呢? 答案当然是肯定,这就需要我们配置一个神器 ...