一、什么是分布式系统?
在谈分布式系统架构前,先来搞懂什么是分布式系统。用大白话来解释什么是分布式系统,就是假设原来有一个20多万行代码的系统,现在拆分成20个小系统,每个小系统1万多行代码。原本代码之间都是直接基于spring调用,现在拆开来了,20个小系统部署在不同的机器上,得基于分布式服务框架(比如dubbo)搞一个rpc调用,接口与接口之间通过网络通信来请求和响应。
分布式系统可以大概分成两类。
1、底层的分布式系统。比如hadoop hdfs(分布式存储系统)、hadoop mapreduce,spark(分布式计算系统)、storm(分布式流式计算系统)、elasticsearch(分布式搜索系统)、kafka(分布式发布订阅消息系统)等
2、分布式业务系统。分布式业务系统就是比如说把原来用java开发的一个大块的系统,给拆分成多个子系统,多个子系统之间互相调用,形成一个整体的大系统。比如一个电商系统,一般会拆分成商品中心、购物车、订单中心、促销中心、支付中心、WMS、库存中心、物流中心等,每一个中心会做成独立一个子系统,独立部署,各个子系统之间互相调用,协同,组成一个大型的电商系统。前面大白话来解释什么是分布式系统说的也是分布式业务系统。
二、为什么要做分布式系统架构?(为什么要进行系统拆分?)
背景:在没有走分布式架构之前,公司的各个业务线都是垂直的“烟囱式”的项目,随着互联网的快速发展,公司的业务也在不断的发展,注册用户增加、网站应用的功能、规模不断扩大,特别是移动互联网的发展,APP、微信、自助终端机等访问渠道的增加,各种新业务,新需求不断涌入,系统遇到了各种各样的问题。首先是项目工程无节制的变得臃肿庞大,系统复杂度增加,大几十万行代码,几十个开发人员,service层,dao层代码大量被copy使用,经常各种代码合并冲突问题要处理,非常耗费时间。经常我改动了我的代码,别人调用了我,导致他的代码也出现问题,需要重新测试,麻烦的要死。然后每次发布都是几十万行代码的系统一起发布,大家得一起提心吊胆准备上线,几十万行代码的上线,可能每次上线都要做很多的检查,很多异常问题的处理,简直是又麻烦又痛苦。而且如果我现在有个新业务,打算把相关依赖升级一下,比如升级到最新的spring版本,还不行,因为这可能导致别人的代码报错,不敢随意乱改技术。一个web工程每次启动都至少需要3分钟以上的时间,本地eclipse里面调试一次代码都很痛苦。其次是随着用户访问流量的增加,系统负载压力变大,变得不堪重负,通过增加实例数,增加硬件扩容能够带来的效果已微乎其微,故障频发,效率低下。系统质量也越来越难以保证,测试周期也变得越来越长,无法满足公司业务发展的需要。
总得来说,问题主要体现在以下几个方面:
1、应用代码耦合严重,功能扩展难。
2、新需求开发交互周期长,测试工作量大。
3、新加入的开发同事需要很长时间才能熟悉系统。
4、升级维护也很困难(改动任何一点地方都要升级整个系统)。
5、系统性能提升艰难,可用性低,不稳定。
系统拆分后带来的好处:系统拆分了以后,会感觉整个世界都清爽了。几十万行代码的系统,假设拆分成20个服务,平均每个服务就1-3万行代码,每个服务部署到单独的机器上。20个工程,就用20个git仓库代码,20个开发人员,每个人维护自己的那个服务就可以了,因为是自己独立的代码,跟别人没关系。再也没有代码冲突了,爽。每次就测试我自己的代码就可以了,爽。每次就发布我自己的一个小服务就可以了,爽。技术上想怎么升级就怎么升级,保持接口定义不变,输入输出内容不变就可以了,爽。分布式系统拆分之后,可以大幅度提升复杂系统大型团队的开发效率。
三、系统如何进行拆分?
一般来说,将系统进行拆分,首先需要对系统整体比较熟悉。可以走多轮拆分。第一次拆分,凭经验拍脑袋就可以,就是将以前的各个大的模块拆分开来。比如我们的电商系统可以拆分成订单系统、商品系统、店铺系统、会员系统、促销系统、支付系统等等。后面可能每个系统又变得越来越复杂了,比如说订单系统又可以拆分成购物车系统,库存系统,价格系统,订单管理系统等。总得来说就是基于领域驱动模型的思想以及实战经验总结,大家讨论着来进行拆分,逐步,多轮拆分,小步快跑,最终达到一个比较好的状态。
四、如何走分布式架构?(走分布式架构后会遇到哪些问题(技术挑战)?)
首先就是分布式服务框架的选用。目前国内来讲主流的还是dubbo与spring cloud。spring cloud是最近一两年才流行起来的,在2015年的时候spring cloud还不成熟,业界大量使用的是dubbo,我们自然而然也就选用了dubbo。
使用服务框架主要用来解决什么问题呢?(如果不用dubbo是否可以做分布式架构呢?)不用dubbo等服务框架当然也是可以的,但是这就需要自己处理很多事情了。比如,各个子系统走restful接口调用,那么就是http调用,这个时候比如说传送过去一个对象,就要自己搞成一个json,然后一次调用失败后重试怎么做?一般来说都是集群部署,目标系统有多个实例,那么自己还要写一个负载均衡算法,如何每次随机从多个目标机器中挑选一个来调用?如果目标系统增加部署了实例,服务器故障停用了一个实例,如何动态让调用方感知到呢? 等等很多问题,如果不用服务框架的话,自己这么瞎搞,会遇到各种各样的问题。
不用分布式服务框架会遇到的一些技术问题确定了分布式服务框架的选用之后,其次就是对dubbo框架的主要内容的学习以及其它一些走分布式架构后常见的要解决的问题。
使用dubbo后需要学习的主要内容。
1、dubbo的工作原理?
2、dubbo支持的序列化协议?
3、dubbo的负载均衡和高可用策略?动态代理策略?
4、dubbo的SPI思想?
5、如何基于dubbo进行服务治理、服务降级、失败重试以及超时重试?
6、dubbo服务接口的幂等性如何设计(比如不能重复扣款,不能重复生成订单,不能重复创建卡号)?
7、dubbo服务接口请求的顺序性如何保证?
其它一些走分布式架构后常见的要解决的问题。
1、分布式会话。
2、分布式锁。
3、分布式事务。
4、统一配置中心。
5、高性能、高可用架构:消息队列、缓存、限流、熔断、降级、监控、数据库分库分表等。
对于dubbo框架主要内容的学习以及其它一些走分布式架构后常见的要解决的问题,我准备针对各个知识点分别写一些文章来说明。
网友评论
各个模块之间去通信~ 约定规则~