相对于单机系统,分布式系统非常复杂,涉及到非常多的技术,作为一个屌丝,有幸能够在大规模分布式系统下工作,故在此记录一些浅薄认识,作为自己未来学习路线的参考。
一、分布式系统概述
分布式系统往往是把应用拆分成多个应用,每个团队维护一个应用,应用与应用通过远程过程调用或者消息中间件通信。这种系统的优点是能够做到高内聚低耦合,可以支撑业务的快速发展,缺点则是运维成本大大提高了,系统出了问题,需要全链路排查。如图所示,用户使用应用A,应用A首先需要调用应用B,然后调用应用C,其中应用B又要调用应用D和E,其中任何一个应用挂了,都会影响整个系统的链路。以上只是一个很简单的例子,真实的系统之间的依赖关系往往非常复杂。
二 分布式系统下的技术栈
在此主要是挖个坑,后续我会一个一个填的。。。
对于分布式系统中的某个应用来说,它的入口往往有三个:远程过程调用(其他应用来调用我的服务)、消息中间件(我订阅了其他系统的消息,其他系统会给我发消息)、web访问(主要访问页面),它的出口则有很多:远程过程调用(调用其他应用的服务)、消息中间件(我向消息服务器发消息,供其他应用消费)、访问分布式缓存、访问分布式日志、访问数据库,执行调度任务。有了入口和出口,剩下的就是应用的核心部分,包括核心逻辑代码和辅助框架。对于分布式系统来说,有个东西必不可少,那就是配置中心。无论是远程过程调用、消息中间件还是分布式缓存,它们都需要从配置中心获取地址列表。
下面简要概括一下分布式系统涉及的技术:
1、远程服务框架:远程服务框架是分布式系统中不可或缺的,对于远程服务框架来说,关键的几个点是:服务消费者、服务提供者、协议(java序列号、反序列化、hessian协议等等)、网络(NIO、多路复用等等)、地址列表。其中协议的选择、网络的优化以及地址列表的获取是难点。目前业界比较有名的开源框架有:Apache Thrift(跨语言)、Dubbo等等。
2、消息中间件:引入消息中间件是用来降低应用之间的耦合的。对于上游应用来说,它往往会依赖非常多的下游应用,如果全部用同步调用(远程过程调用就是同步调用)的方式,那么上游应用必须等到所有下游应用全部执行成功后,才能返回成功,这种等待往往是不可忍受的。为此,需要将同步异步化,而消息中间件可以实现这种异步化。使用消息中间件后,上游应用只需要向消息服务器发送消息就可以了,它不用等待所有应用执行完,它可以提前返回执行成功,后续,消息服务器会去向这些下游应用发消息,通知它们执行。虽然异步化降低了应用之间的耦合,但也引入了新的问题。比如,下游系统执行的时候挂了,而这时候上游系统其实是返回的成功,这样就导致了状态不一致。要解决这个问题,就需要使用消息中间件本身的重试机制,对于一些系统异常,需要重试直到成功,对于应用本身,又需要对这种重试进行幂等处理,并且使用正向状态机管理整个系统的状态。消息中间件的规范可以参考JMS,业界也有成熟的开源方案,比如ActivityMQ。
3、wrapper层:warpper层主要是上面两个入口的包装层,进行一些异常管理,日志管理和AOP拦截
4、MVC框架:这个不用多说了吧,个人比较喜欢spring MVC,有空可以阅读下源代码
5、分布式缓存:待填坑。。
6、分布式日志:待填坑。。
7、文件存储系统:待填坑。。
8、IOC容器:目前用的最多的是spring容器,对于spring的核心的几个模块,可以参考《spring源码深度解析》
9、ORM框架:ORM最好使用ibatis,不推荐hibernate,因为ibatis可以控制sql,在大数据量读写下,必须对sql进行优化。至于ibatis本身的架构,有空我会单独写文章。
10、调度引擎:用于执行异步的定时任务的引擎,待填坑。。
11、分布式数据访问层:正在学习中。。
12、配置中心:统一的配置管理中心,待填坑。。
13、web容器:tomcat,结合《tomcat源代码分析》和tomcat本身的源代码,应该可以很容易的懂tomcat的架构和实现。
14、业务逻辑层:流程引擎和规则引擎,配合spring来治理极易变动的业务逻辑,后续有空单独写个流程引擎
本文链接: 我对java分布式系统的一点认识 ,转载请注明。