分布式系统实战
导语:记得在自己大学毕业的2006年到之后近五年的工作里,源于工作经历和有限的视野,几乎对"分布式系统"没有任何概念。当然,彼时的互联网/移动互联网还未对我们的生活呈覆盖颠覆之势,很多网络应用采用传统的集中式服务便可应对。但是随着互联网大潮的风起云涌,出现了越来越多的细分大流量网站及应用,网民体量也如滚落雪球一般越来越大,这种情况下分布式的概念几乎在技术圈"家喻户晓",也成了我们追逐的另一颗时代"银弹"。我也不例外,但是只是因为身处于某几乎无互联网氛围的二线城市和保守封闭的技术氛围中,所以对分布式系统的理解、掌握只能是自己一步步学习、实践而来,但是反过来也有了很多踏实的实践体会。
刚才提到分布式系统产生的背景之一就是有了很多大型网站、应用。
这些系统的特点是:高并发、大流量;高可用;海量数据;用户分布广泛,网络情况复杂,安全环境恶劣;需求快速变更,迭代式发展,发布频繁。
这些系统的核心架构要素:性能、可用性、伸缩性、扩展性和安全性。
来看看分布式系统的特点:
异构性:使得用户能在大量异构计算机和网络上访问服务和运行应用程序,比如允许硬件、操作系统、编程语言、开发者等的多样性和差别。
开放性(扩展性):使系统能以不同的方式被扩展和实现,比如通过发布系统的关键接口、基于一致的通信机制和网络协议扩展其他应用。
可伸缩性:在不同的用户规模下通过对资源的调节依然能有效且高效的运转,比如通过纵向的伸缩来加强硬件、通过横向的伸缩来增加服务器等。
并发性:保持用户对共享资源操作的正确性,比如CAP理论中的C(一致性)的要求。
高可用性:通过性能优化、安全性、故障处理提高可用性,比如采用高性能的编程模型,安全的隔离和过滤机制,自动化故障检测、容错、故障修复、冗余等。
分布式系统的优势:
降低不同模块开发团队间的协同成本,业务响应更迅捷。
大大降低系统间的耦合度以及整体复杂度,各个开发团队可专注于各自的业务模块。
避免了个别模块的错误给整体带来的影响。
业务可拆分、可扩展后解放了对单服务资源的依赖。
做到针对性的业务能力扩容,减少不必要的资源浪费。
可见分布式系统为大型网站应用在技术和组织层面都提供了良好的解决和支撑。
分布式系统相关的理论:
CAP理论:一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance 指分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务)其中的两项。
BASE理论:是指基本可用(Basically Avalilable)、柔性状态(Soft State)、最终一致性(Eventual Consistency)。BASE是对CAP理论的延伸,核心思想是即使无法做到强一致性,但应用可以采用适合的方式达到最终一致性。
另外,现在经常有人问起分布式架构理念与之前我们经常说的SOA(面向服务的架构)和现在颇为流行的微服务架构孰优孰劣。我个人认为问优劣是不合理的,首先分布式构架理念在两者中都有体现和应用。而对于作为对比的SOA和微服务,这二者在彼此适配的场景下都可以殊途同归的解决问题,都是好的架构理念。但是确实是也有区别和联系:
SOA的主要特性:
面向服务的分布式计算
服务间松散耦合
支持服务的组装
服务注册和自动发现
以服务契约方式定义服务交互方式
微服务架构的典型特征:
分布式服务组成的系统
按照业务而不是按照技术来划分组织
做有生命的产品而不是项目
智能化服务端点与傻瓜式服务编排
自动化运维
系统容错
服务快速演化
上面主要讲了对分布式系统的概念认识,很多是对书籍和学习的总结。但是做到真正的理解就必须有实战,拿其中一个自己亲自架构编码的即时聊天/用户、设备上线系统的后台架构为例,此架构思路目前已经实践应用在多个百万级别的服务上。其实对于此架构的分布式应用,自己并不是在熟知分布式理论的前提下设计的,而是基于其他理念模型和在具体的业务实践、组织协作过程中演化而来的。
比如分层的架构设计,之前由于主要做网络安全和网络编程工作,TCP/IP协议栈的分层设计深深影响了自己
把网络层、业务逻辑层、数据层分离,网络层支持负载均衡,业务层支持动态扩展,数据层支持分布式存储,各层均支持分布式部署;以下是架构细化图
对不同功能的模块进行进程级的分离,用TCP来进行通讯。这是受"《UNIX编程艺术》第7章--多道程序设计:分离进程为独立的功能"的理念影响,是不是和微服务的理念很像,而且基于TCP通信的方式利于进行分布式部署。Unix最具特点的程序模块化技法就是将大型程序分解成多个协作进程,并专注于考虑这些子进程间的接口和通讯方式;
通用技术模块和业务应用模块分离,比如网关服务、上线服务实现网络接入和协议转发功能不承载业务逻辑,由具体的应用进程处理业务。网关服务就类似于Nginx,用户的请求首先会通过前端接入层(Nginx)分发到后端的应用集群上,另外通过在网关上实现的安全过滤(比如域名IP类、协议秘钥、黑名单)实现接入层限流、安全的主要工作。
无状态的设计,将状态、消息、业务数据类信息分离出业务进程,利用分布式缓存(如redis),数据库(关系型数据库MySQL、非关系型数据库MongoDB)存储进行调用。这样业务进程利于分布式部署,数据服务也支持分布式存储。
服务间利用标准统一的协议进行信息交互,比如采用序列化协议Json和RESTful API设计,我个人比较推崇文本化的协议,容易使人理解也更容易记录、分析、调试。这是深受"《Unix编程艺术》第5章--文本化:好协议产生好实践"理念的影响。相比二进制协议,文本化协议可以带来互用性、透明性、可扩展性。
通过配置文件或者配置服务加载策略,对于很多静态和动态的策略不要写死在程序中,而是通过配置文件或者配置服务加载,这样可以快速部署发布新功能、对服务进行无间断的热启动。这也是"《Unix编程艺术》中分离原则:策略同机制分离,接口同引擎分离"原则的实践。
资料和代码:
《服务端架构中的"网关服务器 》 《IM系统架构设计之浅见 》
DSF(Distributed service framework) :基于C++语言实现的一个简单分布式服务框架示例,包括一个逻辑分发服务实现(网关服务),一个逻辑应用实现(具体应用服务)
highPerformanceNetworkServer :高性能TCP网络服务器程序(上线服务器的雏形)
参考书籍:
《Unix编程艺术》
《企业IT架构转型之道:阿里巴巴中台战略思想与架构实战 》
《大型网站技术架构》
《分布式系统概念与设计》