架构解耦(转)
1. 小小的IP,大大的耦合,你痛过吗?
如何解除IP耦合?
常见的方法是:使用内网域名替代内网IP,如果没有做这个优化,强烈的建议马上实施,将配置文件中的内网IP全部干掉,全部改为内网域名。
使用内网域名,就不需要上游配合重启了吗?
假设现在不用内网IP,改用内网域名了,一个服务或者数据库的IP变更,只需要一个地方更改,而不是所有上游更改:
-
运维修改内网DNS,将内网域名指向新的IP,如果是短连接调用,未来新的请求流量,自然会切到新的IP上;如果是长连接调用,新的长连接会连到新的IP上,但旧的长连接仍然连接的是旧IP
-
运维统一将旧IP上的连接切断,如无意外,服务或者数据库的连接池都有重连功能,重连后就会自动连到新IP上去
如此这般,只要运维配合就可以完成IP的迁移,对于所有上游的调用方不需要配合修改配置重启。
2. 小小的公共库,大大的耦合,你痛过吗?
如何解除公共库耦合?
方案一:代码拷贝一份
别嘲笑这个方案,谁敢说自己写代码的时候没这么干过?
我们都知道这不是一个好的方案,但不可否认,拷贝之后,代码各自演化,一个地方升级出错,只影响一方,拷贝方只要不动原有代码,至少是不会受影响的。
代码拷贝缺点很多,系统拆分时,万不得已不要使用这个方案。
方案二:垂直拆分,将公共库里业务个性化的代码拆到调用方去,不要放在公共库里
需要把业务个性的代码拆分到各个业务线自己的工程,自己的业务库里去,例如s1.jar / s2.jar / s3.jar,修改各自的代码,至少不会扩大影响范围。
大家为什么都把代码往一个公共库里塞?
很多时候,因为惰性,一点一点的惰性,日积月累,终成大坑。
这个垂直拆分是一个架构重构的过程,需要各业务方配合。
方案三:服务化,将公共库里通用业务代码拆到下层去
完成了第一步,业务个性化的代码提取到业务侧上游。
接下来是第二步,业务通用的代码,下沉抽取一层服务,服务对上游提供RPC接口:
-
每次修改底层接口,需要测试接口的兼容性,保证不影响旧调用方
-
如果是新的业务,则建议新增接口
最终,达到通过服务RPC调用的方式来解除耦合。
个性业务代码上浮,共性业务代码服务化下沉,只是一个很小的优化点,但对于公共库解耦却是非常的有效。
3. CA,给了数据库,给了机器,为啥也扩不了容?
如何解除公共数据库与业务数据库的耦合?
第一步:公共数据访问下沉服务化
第二步:垂直拆分,个性化数据访问上浮
此时各业务有自己的库,公共有公共的库:
-
早期:可以放在一个数据库实例里
-
后期:可以很容易地通过新增数据库实例,把user库或者业务A/B/C的库拆分出来,实现增加机器增加实例就实现扩容
4. 服务化了,没想到耦合更加严重?
1). 讨论技术方案时,不要总以:
“放在你那边做代码少”
“放在你那边做时间短”
作为设计折衷的理由,而要多问:“怎么做合理”
2). 尽量杜绝底层出现switch case(biz_type)走不同分支的代码。
业务代码上浮,通用代码下沉,服务化彻底,只是一个很小的优化点,但对于底层服务解耦却是非常的有效。
5. MQ,互联网架构解耦神器
1). 一个架构常识:当调用方需要关心执行结果,通常使用RPC调用。但如果调用方不关心执行结果,却仍然使用RPC调用,会引发上下游极大的耦合与瓶颈。
2). 如果事件发出方不关心订阅方的执行结果,不能用RPC,应该用MQ。
MQ能够做到上下游物理上和逻辑上都解耦:
-
物理上解耦,增加MQ之后,上游互不知道彼此的存在,不会建立物理连接了,大家都只与MQ建立物理连接
-
逻辑上解耦,事件发布方甚至不用知道哪些下游订阅了这个消息,新增消息的订阅方只需要连接MQ就行了,不需要上游关注
MQ是一个非常常见的物理上解耦、逻辑上也解耦的利器。
关注下游执行执行结果,用RPC;不关注下游执行结果,用MQ,不用RPC;
这只是一个很小的优化点,但对于通知解耦却是非常有效。
6.