子系统拆分的一点总结

公司系统做了一年多,慢慢也有点规模了。从最初只有一个APP + 一个server的模式,到现在有多个子系统,多个客户端。这个过程中,积累了一些想法,本文简单总结一下

系统拆分的好处

基本上,比较小的系统,单进程集中部署就可以了。集中部署不代表一定不好,在系统规模很小的时候,或许是最适合的,因为调用关系简单,开发也比较容易。但是系统慢慢变大了以后,我认为拆分系统,分布式部署就变得更为合理了。

拆分系统至少有这些我体会到的好处:

1、停掉系统的一个部分,只会影响相关业务,不会造成整体业务中断。特别是一个新的模块上线,尚未稳定的时候,可能会有错误挂掉,或者主动重启维护等,如果是集中部署,就会造成整个系统都不可用。但是分布式部署的情况下,只会中断小范围的业务。当然,就算是集中部署,利用集群,分批重启,也可以实现同样的目的

2、对压力大的节点,可以单独部署集群。比如我们的系统,数据同步模块的负载是最高的,那么就可以针对这个子系统单独部署集群,其他负载低的模块,可以部署在一起,或者单独部署,都比较灵活。当然,要实现水平伸缩,对系统设计本身也有要求,比如至少要实现无状态服务等

3、代码分离,便于权限控制。一般来说,集中部署的代码也是在一起的,如果希望负责子系统A的小组,不需要接触到子系统B的代码,那么分成2个代码库就非常容易实现。相反,如果代码都是在一起的,控制就比较困难。因为不能只开放一部分代码给开发人员,这样不利于在本地搭建开发环境

4、按责任田制度,小团队维护特定模块。跟上面一点比较类似,每个小团队的责任边界比较清晰

按业务垂直拆分系统

拆分系统也要根据实际情况,有不同的选择。我们早期的时候是根据业务,垂直拆分子系统,比如划分成微站,数据同步,连锁等。这样做的好处是,每个子系统都是可以独立跑起来的,比如说把微站子系统运行起来,微站的页面就都能访问了,数据也是该系统自己负责读写的。但是缺点也很明显,就是冗余的代码比较多。比如连锁和微站,2个子系统都需要查询企业信息,那么就各自都写了这部分代码,其实接口几乎是一模一样的,存在很大的复用空间。重复行为基本上都是不好的,这个应该说是开发人员的共识

网状结构

后来做了一点调整,基本上子系统还是按照业务拆分的。但是每个子系统都对外提供服务,比如基础数据查询模块,提供了查询企业信息的接口。连锁和微站子系统,自己就不重复查了,而是以HTTP方式,调用基础数据查询模块的这个接口。这种方式的优缺点和上一种方案大致相反。消除了重复代码,但是模块之间存在依赖关系。如果基础数据查询模块不跑起来,那微站模块虽然能跑起来,但是相关的数据就没有了

而且这样调用关系会比较复杂一点,因为本地调用都变成了HTTP接口调用,意味着业务模块,需要知道去哪里调用所需的服务,可能需要配置很多IP地址(如果依赖很多外部服务的话)。并且这个IP地址是经常需要变化的,不同的开发人员,本地的开发环境地址都不一样;开发环境和生产环境的地址也不一样;生产环境的集群配置变化了,也可能造成地址的变化。系统的复杂性变得比较高

星型结构

再后来为了解决这个调用的问题,TOPO演进为星型结构,有一个中心节点。业务模块把所有的内部请求都发到这个中心节点上,由中心节点负责转发到服务提供者上。这样对于业务模块来说,就不需要知道服务提供方的实际地址,只要把所有请求都发到中心节点上就可以了。映射的工作由中心节点来完成,需要类似这样的映射:

service1       192.168.1.110:8080/svc1

service2       192.168.1.110:8080/svc2

service3       192.168.1.111:8080/svc3

……

这个工作,在服务的数量和复杂度不是太高的时候,只需要一个简单的路由就可以了,不需要专门的服务治理方案。比如我们早期采用的就是nginx,把nginx当做内部的服务中心来使用,借助server_name,proxy_pass,up_stream等特性,已经足以满足需求。但是当服务的数量和复杂度达到一个量级,就需要有专门的方案,来处理服务的注册、发布、寻址、负载均衡、队列、失败重试等需求了

时间: 2024-12-27 23:47:54

子系统拆分的一点总结的相关文章

B/S 类项目改善的一些建议

body { border: 1px solid #ddd; outline: 1300px solid #fff; margin: 16px auto; } body .markdown-body { padding: 30px; } @font-face { font-family: fontawesome-mini; src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAzUABAAAAAAFNgAAQAAAAAAAAAAAA

经典分布式系统设计

作者:潘罡 (Van Pan) @ Microsoft 在正式介绍Service Fabric之前,我们认为应该首先介绍分布式系统的经典架构. 理解了分布式系统的演进过程可以极大程度上帮助理解Service Fabric以及Azure服务中所有针对分布式系统的优秀产品. 简单系统模型 在IT时代初期,如果需要自行构建一个系统,需要完成以下工作. 采购服务器 在服务器中安装Web服务器 在服务器中安装数据库 向ISP申请静态IP 向服务器部署静态IP 向服务器中部署网站 向服务器中部署数据库原始数

B/S 类项目改善

B/S 类项目改善的一些建议 要分享的议题 性能提升:在访问量逐渐增大的同时,如何增大单台服务器的 PV2 上限,增加 TPS3 ? RESTful:相较于传统的 SOAP1,RESTful 风格架构有哪些优点?做法有哪些区别? 微服务:随着企业越来越大,系统会越来越大,越来越难维护,如何在保证“稳”的同时,还保证有小企业的“灵活”? 简要的介绍 性能提升 最常用的性能提高方式可以通过使用服务器的集群来解决,简单粗暴的理解就是增加银行柜员的数量.但是,一味的只考虑从服务端提供性能,并不是聪明的做

互联网金融高并发方案

小微金融.场景金融等新兴银行金融业务亟需一种新型的弹性架构来应对高并发.大流量的业务冲击,同时,要满足应用快速版本迭代升级.敏捷运维管理等需求.本文分享了BoCloud博云如何利用互联网应用架构与Docker容器技术帮助银行业应对“互联网+”挑战,建设基于PaaS平台的敏捷IT架构. 移动互联网渠道创新是传统企业无法也不能躲避的业务变革,无论是接入或者自建互联网渠道都需要回答如下问题:现在的IT架构能否应对互联网渠道创新业务的爆炸性冲击?什么样的IT架构才能够解决这个问题并具备应对未来需求的良好

软件架构分解

https://www.ibm.com/developerworks/cn/rational/1312_wanggb_arch/index.html 什么是软件架构 如果期望有一个权威统一的标准定义,那答案是没有,目前存在多种软件架构的定义,可以说百花齐放,百家争鸣.其中 IEEE1471-2000 的定义是这样的:系统的架构是系统组件的基本组织形式,它们之间的关系以及和环境之间的关系,以及指导其设计和演化的原则.该定义中的系统组件可以理解为架构元素,根据涉及到的系统范围和层次,架构元素可以是子

Windows内核

每天我们都在使用Windows系统学习.编程.听音乐.玩游戏,Windows的操作想来是非常熟练了,但是你又对Windows究竟了解多少呢?本系列的目的,就是让你对Windows系统有个更直观.更清楚.更彻底的认识.尽管我们大多数人看不到Windows的源代码,对其内存调度算法这样的最深层次的技术内幕不能明窥,但是我们能够做到比方今知道的很多其它,了解这些之后你会发如今Windows上面开发会轻车熟路,不论什么木马病毒到了你机器上只是仅仅会成为你的试验品. 鉴于Windows 9X内核早已淘汰,

(集成电路卡)ID卡

IC卡(intergrated Circuit Card,集成电路卡),又称为智能卡,智慧卡,微电路卡,微芯片卡 等等. 它是将一个微电子芯片嵌入符合ISO 7816标准的卡基中,做成卡片形状. IC卡与读写器之间的通讯可以是接触式的,也可是是非接触式的. 根据通讯接口把IC卡分成接触式IC卡.非接触式IC卡.双界面卡(同时具备接触式与非接触式通讯接口). IC卡由于其固有的信息安全.便于携带.比较完善的标准化等优点,在身份认证.银行.电信.公共交通.车场管理等领域正得到越来越多的应用,例如二代

《Linux设备驱动开发详解(基于最新4.0内核)》前言

Linux从未停歇脚步.Linus Torvalds,世界上最伟大的程序员之一,Linux内核的创始人,Git的缔造者,仍然在没日没夜的合并补丁,升级内核.做技术,从来没有终南捷径,拼的就是坐冷板凳的傻劲. 这是一个连阅读都被碎片化的时代,在这样一个时代,人们趋向于激进.浮躁.内心的不安宁使我们极难静下心来研究什么.我见过许许多多的Linux工程师,他们的简历书写着"精通"Linux内核,有多年的工作经验,而他们的"精通"却只是把某个寄存器从0改成1,从1改成0的不

Yii2 跨库orm实现

近期在对公司的Yii2项目进行子系统拆分,过度阶段难免会有一些跨库操作,原生语句还好,加下库名前缀就可以了,可是到了orm问题就来了,特别是用到model做查询的时候,现在来记录一下跳过的坑, 像下面是通过Order的Model类的getUser方法去关联user表,如果order在库2,user在库1,就会默认关联库2的user表,然后找不到表 order::find()->alias('o'); $query->innerJoinWith('user'); 有一个简单的处理方法 order