服务化了,没想到耦合更加严重?
通过“库”来实现业务,可能会引发业务系统之间耦合,需要通用业务服务化,将通用业务下沉,详见《小小的公共库,大大的耦合,你痛过吗》。
通过“join”来实现业务,可能会导致数据库之间耦合,需要基础数据服务化,实现数据库私有化,解除数据库之间的耦合,详见《小小的数据库,大大的耦合,你通过吗》。
但如果服务化不合理,将部分个性化业务下沉到了底层,耦合与瓶颈会更加严重。
场景还原
业务1,业务2,业务3,因为join导致数据库实例耦合在了一起。
为了实现通用数据库table-user的解耦,实施了服务化,将通用user数据的访问抽象出了服务。
由于服务化不合理,会有很少很少的个性化业务逻辑,实现在底层的服务中,典型的伪代码是:
switch(biz_type){
case(1) : exec_logic1();
case(2) : exec_logic2();
case(3) : exec_logic3();
default : exec_default();
}
为什么会引发耦合呢?
不妨设,业务1来了一个新的个性化需求,这个需求本来实现在业务1自己的代码里是合理的,但工程师S想到,底层的通用服务里也有业务1的一小撮个性化代码,评估后,发现实现在底层新的需求改动的代码最小,时间最短,于是来找底层服务的负责人工程师B。
- 业务1工程师S:“有个小需求,帮个忙呗”
- 底层工程师B:“个性化实现在底层不合理”
- 业务1工程师S:“反正都有switch case的代码了,再改一点也不麻烦,在我这边实现特别复杂,要xxoo这么搞”
- 底层工程师B:“确实很复杂,那我来吧”
- …
遗留了不合理的代码,就会有第一次妥协,妥协了业务1,就会妥协业务2,随着时间的推移,底层服务越来越复杂:
- 业务1,业务2,业务3的个性化代码越来越多
- 业务1,业务2,业务3的需求越来越多提给底层工程师
- 底层工程师慢慢成了项目瓶颈,业务1,业务2,业务3的项目逐步delay,但逐步都怪到了底层工程师的头上
直到有一天,底层服务出了一个小bug,影响了业务1,业务2,业务3,历史总是惊人的相似:
- 业务1的大boss在群里首先发飙:“技术都干啥了,怎么系统挂了”
- 业务1的工程师S一脸无辜:“底层系统改造,工程师S的bug”
额,然而,这个理由,好像在大boss那解释不通…
- 底层服务工程师B一脸委屈:“...”。明明需求是业务方的,为什么修改代码的是我底层呢,业务代码出了问题,为什么责怪的是我底层呢,每每心中骂娘,系统中很可能就存在耦合。
如何解耦呢?
业务代码上浮,通用代码下沉,服务化彻底。
解决方案并不复杂,分层架构中,每一层都有自己的职责,每一层都应该守住自己的底线。
启示
一、讨论技术方案时,不要总以:
“放在你那边做代码少”
“放在你那边做时间短”
作为设计折衷的理由,而要多问:
“怎么做合理”
二、尽量杜绝底层出现switch case(biz_type)走不同分支的代码。
业务代码上浮,通用代码下沉,服务化彻底,只是一个很小的优化点,但对于底层服务解耦却是非常的有效。
- WCF中关于可靠会话的BUG!!
- [WCF安全系列]谈谈WCF的客户端认证[Windows认证]
- ls命令实现分析
- [WCF安全系列]谈谈WCF的客户端认证[X.509证书认证]
- Openstack Trove概要
- [WCF安全系列]实例演示:TLS/SSL在WCF中的应用[SSL over TCP]
- [WCF安全系列]谈谈WCF的客户端认证[用户名/密码认证]
- [WCF安全系列]绑定、安全模式与客户端凭证类型:BasicHttpBinding
- [WCF安全系列]服务凭证(Service Credential)与服务身份(Service Identity)
- 如何正确的对安卓手机进行数据恢复?
- [WCF安全系列]绑定、安全模式与客户端凭证类型:WSHttpBinding与WSDualHttpBinding
- Python中list的遍历
- Python中的参数传递与解析
- [WCF安全系列]实例演示:TLS/SSL在WCF中的应用[HTTPS]
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python爬虫练手,一个简单的Python资讯采集案例
- 直播带货软件开发过程中,如何实现图片上传
- 太实用了!自己动手写软件——邮件用户名密码验证
- 太实用了!自己动手写软件——SSH、FTP和SQL server的密码破解
- Kaggle Tweet Sentiment Extraction 第七名复盘
- 【翻译】.NET 5中的性能改进
- 腾讯云实时语音识别-iOS SDK
- JointPoint用法及与ProceedingJoinPoint 的关系
- Spring中的异步请求、异步调用及demo测试
- 以太坊交易签名解析源码解读
- 比较NaN和数字
- GO 的方法集
- 轻松应对并发问题,简易的火车票售票系统,第一步 —业务分析
- 【Spark Operator】核数设置Cores/Cores Limit/Cores Request,你搞清楚没有?
- 【Ceph RGW】radosgw_usage_exporter监控用户使用量