看懂架构设计中的服务隔离
写在前面的话:我们在做系统架构设计的时候,经常离不开的一个话题就是进行服务的隔离设计。
那什么是「服务隔离」呢?
顾名思义,它是指将系统按照一定的原则划分为若干个服务模块,各个模块之间相对独立,无强依赖。当有故障发生时,能将问题和影响隔离在某个模块内部,而不扩散风险,不波及其它模块,不影响整体的系统服务。
其实隔离设计并非软件行业独创,它是借鉴于造船行业。
行业有一个专业术语叫做「舱壁隔离」。利用舱壁将不同的船舱隔离起来,如果某一个船舱进了水,那么就可以立即封闭舱门,形成舱壁隔离,只损失那一个船舱,其他船舱不受影响,整个船只还是可以正常航行。
一、为什么要做服务隔离设计呢?
我们在做系统设计的时候,必须有一个清楚的认知是:任何软件系统,故障是不可避免的,并且大多数还是不可预测的,因此,我们只能在系统的设计之初就充分的考虑好应对措施,如何在故障发生时,去尽最大可能的止损和减少故障范围。
没有人敢说他的系统是百分百可用,我们能做的就是,使用一切方法去减少故障的影响面,尽可能的去提高系统的整体可用率。
而把系统分离成子服务,将子服务进行一定程度隔离的做法,能保证在有不可预测的故障发生时,缩小故障范围的最佳手段。
二、服务隔离应该怎么做?
那在实际项目中,一般通过什么方法去做服务隔离呢?主要有以下两种:
按服务/功能做隔离
按用户分类隔离
首先说一下按照服务进行隔离的做法。
网上找了一张图,虽然原图的作用不是用来表述这个的,但是也类似,将就看吧。
比如上图里面,微博项目可以把 Feed信息流、用户系统、评论系统 都分拆为独立业务模块,这些模块无论是对外的接口应用、还是到数据库、到底层硬件资源都是完全隔离的。其中任何一个模块的故障,理论上都不会影响到其它模块。
再举个例子,如果我们要设计个电商平台,可以将其中的 用户系统、订单系统、支付系统、仓储系统 都分别进行独立隔离,这样做就是从服务层面实现了故障的隔离效果。
那按照服务隔离有没有弊端呢?有,肯定有。
当我们某个功能操作需要关联多个服务模块或者同时查询所个模块数据的时候,代码写起来就会相对麻烦一些了,其中涉及到多模块调用的性能问题、数据一致性问题、事物问题等。
不同服务模块之间的交互也会比较复杂一些,因为要做服务隔离,避免服务强依赖,所以模块之间的交互调用最好是走异步模式,需要通过异步线程或消息中间件来传递实现。
在进行运营大数据分析的时候,由于数据是散落在不同服务模块的,因此需要做额外的汇聚操作,还得有唯一字段保证数据在不同模块产生的先后顺序。
接下来说一下按用户隔离的做法。
继续网上找图,虽然原图的作用不是用来表述这个的,但是也类似。粉丝又不多,我又懒得画图,将就看吧,多发挥一下想象力,哈哈。
简单一句话解释就是:我们先部署多套一模一样的业务服务,然后将用户根据一定的特征去做分类,让不同分类的用户去访问不同的业务实例,达到分流和隔离的效果。
怎么给用户分类?
可以用按照用户是否VIP、用户等级、用户IP等等,方法很多,要结合自己实际业务的特性来做。
其实这也是一种「多租户架构」,在SaaS服务中用得比较多。
多租户模式有三种形式:
完全的隔离,即服务和数据都是完全独立的。
公共服务、独立数据源,即多个租户是用的同一台服务程序,但是底层的数据源是独立的。
公用服务、公用数据源,即多个租户的服务程序与数据库源都是共享的,不同数据可能会做分区分表来独立。
上述三种方式,从下到上,独立性和安全性越来越高,资源利用率越来越低,根据业务特性去选择,一般选择折中方案。
另外,功能隔离和用户隔离 两种方式并非互斥的,是可以结合在一起使用的。
三、服务隔离的注意事项
我们在做服务隔离的时候,还是有一些原则和事项需要注意的:
不可越界:能在隔离模块内完成的逻辑,就尽量不要跨模块调用,减少依赖。
不可共享:数据和资源能独享的就尽量不要共享,不然很容易造成隔离失效。
考虑效率:设计隔离模块的时候,要根据业务情况而定,充分的考虑到未来的拓补结构,减少调用效率的损失。
考虑颗粒度:隔离模块设计的大小问题,过大和过小都不合适,需充分考虑。
服务的全面监控:既然服务或用户进行隔离了,那么系统的复杂度肯定是比之前要高了,那么针对多服务的全链路监控是必不可少的。
服务隔离的设计模式能降低依赖服务对整个系统的影响,保护有限的资源不被耗尽,提高了整个系统的可用性。本文参考了很多其它资料,属于抛砖引玉,希望大家能一起交流,提出更好的架构设计思路。
欢迎工作一到五年的Java工程师朋友们加入Java架构开发:744677563
本群提供免费的学习指导 架构资料 以及免费的解答
不懂得问题都可以在本群提出来 之后还会有职业生涯规划以及面试指导
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
朱晔的互联网架构实践心得S1E1:Pilot
朱晔的互联网架构实践心得S1E1:Pilot 最近几年写博客确实写得少了,初出茅庐的时候什么都愿意去写,现在写一点东西之前会反复斟酌是否有价值。工作十几年了,做了N多个互联网系统,业务涉及教育、游戏、电商、O2O、P2P,算是各种类型的互联网系统都摸过,多少有一些心得,架构方面的文章网上很多很多,有些是说一些方法论,有些是说一些具体的案例,感觉自己想分享的东西和别人已分享的是有点不同的,还是应该留下点什么。在这里我更多想分享一下搭建一套完整的互联网系统架构方面一些具体的实践心得,大概会从这几个方面来写: 各种废话的闲聊和吐槽 屡试不爽的架构三马车:介绍一个简单实用的可扩展的互联网架构 相辅相成的存储五件套:介绍一下个人比较喜欢的一个存储组合以及适用场景 简单好用的监控六兄弟:介绍监控方面一直在用的一些工具以及强调监控的重要性 不断耕耘的基础中间件:中后期的项目需要有完善的基础中间件,这里进行逐一介绍 给飞机换引擎和安全意识十原则:分享一些对高速发展项目进行重构以及安全方面的一些经验 高并发架构到底是什么:高并发架构优化在优化哪些方面,具体会做一些什么事呢? ……(想到了再补充吧) ...
- 下一篇
动态代理之投鞭断流!看一下MyBatis的底层实现原理!
一日小区漫步,我问朋友:Mybatis中声明一个interface接口,没有编写任何实现类,Mybatis就能返回接口实例,并调用接口方法返回数据库数据,你知道为什么不?朋友很是诧异:是啊,我也很纳闷,我们领导告诉我们按照这个模式编写就好了,我同事也感觉很奇怪,虽然我不知道具体是怎么实现的,但我觉得肯定是……(此处略去若干的漫天猜想),但是也不对啊,难道是……(再次略去若干似懂非懂)。 这激发了我写本篇文章的冲动。 动态代理的功能:通过拦截器方法回调,对目标target方法进行增强。 言外之意就是为了增强目标target方法。上面这句话没错,但也不要认为它就是真理,殊不知,动态代理还有投鞭断流的霸权,连目标target都不要的科幻模式。 注:本文默认认为,读者对动态代理的原理是理解的,如果不明白target的含义,难以看懂本篇文章,建议先理解动态代理。 一、自定义JDK动态代理之投鞭断流实现自动映射器Mapper 首先定义一个pojo 再定义一个接口UserMapper.java 接下来我们看看如何使用动态代理之投鞭断流,实现实例化接口并调用接口方法返回数据的。 自定义一个In...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果