叁叁肆

这个世界会好吗

453篇博客

快速成长期应用架构实践 (5):架构实践

叁叁肆2018-11-14 18:44

欢迎访问网易云社区,了解更多网易技术产品运营经验。


4.2 架构实践


除了基本的功能需求之外,一个互联网产品往往还有访问性能、高可用、可扩展等需 要,这些统称为非功能需求。一般来说,功能需求往往可以通过开发业务模块来满足,而 非功能需求往往要从系统架构设计出发,从基础上提供支持。


随着用户的增加,系统出现问题的影响也会增大。试想一下,一个小公司的主页,或 者个人开发维护的一个 App 的无法访问,可能不会有多少关注。而支付宝、微信的宕机,则会直接被推到新闻头条(2015 年支付宝光纤被挖路机挖断),并且会给用户带来严重的 影响:鼓足勇气表白却发现信息丢失?掏出手机支付却发生支付失败,关键是还没带现金! 在用户使用高峰时,一次故障就会给产品带来很大的伤害,如果频繁出现故障则基本等同 于死刑判决。 


同样,对一个小产品来说,偶发的延时、卡顿可能并不会有大的影响(可能已经影响 到了用户,只是范围、概率较小)。而对于一个较为成熟的产品,良好的性能则是影响产品 生死存亡的基本问题。试想一下,如果支付宝、微信经常出现卡顿、变慢,甚至在访问高 峰时崩溃,那它们还能支撑起现在的用户规模,甚至成为基础的服务设施吗?可以说,良 好的访问性能,是一个产品从幼稚到成熟所必须解决的问题,也是一个成功产品的必备因 素。实际上,很多有良好创意、商业前景很好的互联网产品,就是因无法满足用户增长带 来的性能压力而夭折。 


随着性能需求的不断增长,所需要考虑的因素越多,出问题的概率也越大。因此,用 户数的不断增长带来的挑战和问题几乎呈几何倍数增加,如果没有良好的设计和规划,随 着产品和业务的不断膨胀,我们往往会陷入“修改→引入新问题→继续调整→引入更多问 题”的泥潭中无法自拔。


在这一阶段,架构设计的重点不再是业务本身功能实现和架构的构建,而是如何通过 优化系统架构,来满足系统的高可用、并行扩展和系统加速等需要。


4.2.1 前端系统扩展 

可扩展性是大规模系统稳定运行的基石。随着互联网用户的不断增加,一个成功产品 的用户量往往是数以亿计,无论多强大的单点都无法满足这种规模的性能需求。因此系统 的扩展是一个成功互联网产品的必然属性,无法进行扩展的产品,注定没有未来。
由于扩展性是一个非常大的范畴,并没有一个四海皆准的手段或者技术来实现,因此 本节主要介绍较为通用的可扩展系统设计,并以网易云为例,来介绍基础设施对可扩展性 的支持。


4.2.2 无状态服务设计 

要实现系统的并行扩展,需要对原有的系统进行服务化拆分。在服务实现时,主要有 两种实现方式,分别是无状态服务和有状态服务。
云原生应用架构实践


无状态服务

指的是服务在处理请求时,不依赖除了请求本身外的其他内容,也不会有除了响应请 求之外的额外操作。如果要实现无状态服务的并行扩展,只需要对服务节点进行并行扩展, 引入负载均衡即可。


有状态服务

指的是服务在处理一个请求时,除了请求自身的信息外,还需要依赖之前的请求处理 结果。
对于有状态服务来说,服务本身的状态也是正确运行的一部分,因此有状态服务相对 难以管理,无法通过简单地增加实例个数来实现并行扩展。


对比

从技术的角度来看,有状态服务和无状态服务只是服务的两种状态,本身并没有优劣 之分。在实际的业务场景下,有状态服务和无状态服务相比,有各自的优势。


有状态服务的特性如下。

数据局部性:数据都在服务内部,不需要依赖外部数据服务强并发,有状态服务 可以把状态信息都放在服务内部,在并发访问时不用考虑冲突等问题,而本地数 据也可以提供更好的存取效率。因此,单个有状态服务可以提供更强的并发处理 能力。 

实现简单:可以把数据信息都放在本地,因此可以较少考虑多系统协同的问题, 在开发时更为简单。 


无状态服务的特性如下。

易扩展:可以通过加入负载均衡服务,增加实例个数进行简单的并行扩展易管理, 由于不需要上下文信息,因此可以方便地管理,不需要考虑不同服务实例之间的 差异。

易恢复:对于服务异常,不需要额外的状态信息,只需要重新拉起服务即可。而在云计算环境下,可以直接建立新的服务实例,替代异常的服务节点即可。 

总体来看,有状态服务在服务架构较为简单时,有易开发、高并发等优势,而无状态 服务的优势则体现在服务管理、并行扩展方面。随着业务规模的扩大、系统复杂度的增加, 无状态服务的这些优势,会越来越明显。因此,对于一个大型系统而言,我们更推荐无状 态化的服务设计。


2. 实践


下面,我们根据不同的服务类型,来分析如何进行状态分离。


常见的状态信息 

Web 服务:在 Web 服务中,我们往往需要用户状态信息。一个用户的访问过程, 我们称为一个会话(Session),这也是 Web 服务中最为常见的状态信息。

本地数据:在业务运行过程中,会把一些运行状态信息保留到本地内存或者磁 盘中。

网络状态:一些服务在配置时,会直接使用 IP 地址访问,这样在服务访问时就依 赖相应的网络配置。一旦地址改变,就需要修改对应的配置文件。


状态分离 

要把有状态的服务改造成无状态的服务,一般有以下两种做法。


请求附带全部状态信息:这种做法适用于状态信息比较简单的情况(如用户信息, 登录状态等)。优点是实现较为简单,不需要额外设施。缺点是会导致请求内容增 加,因此在状态信息较多时并不适用。

状态分离:即通过将状态信息分离到外部的独立存储系统中(一般是高速缓存数 据库等),来把状态信息从服务中剥离出去。


Web 服务状态分离 

在 Web 服务中,两种状态分离模式都可以实现状态分离。


使用 Cookie:把会话信息保存在加密后的 Cookie 之中,每次请求时解析 Cookie 内容来判断是否登录。这种做法的优点是实现简单,不需要额外的系统支持。缺点是 Cookie 的大小有限制,不能保持较大的状态信息,还会增加每次请求的数据 传输量,同时 Cookie 必须要使用可靠的加密协议进行加密,否则会有被人篡改或 者伪造的风险。因此这种做法一般用来保持用户登录状态。


共享 Session:将 Session 信息保存在外部服务(共享内存、缓存服务、数据库等) 中,在请求到来时再从外部存储服务中获取状态信息。这种做法没有状态信息大 小的限制,也不会增加请求大小。但是需要可靠、高效的外部存储服务来进行支 持。一般来说,可以直接使用云计算服务商提供的缓存服务。


服务器本身状态分离 

对于依赖本地存储的服务,优先做法是把数据保存在公共的第三方存储服务中,根据 内容的不同,可以保存在对象存储服务或者数据库服务中。 


如果很难把数据提取到外部存储上,也不建议使用本地盘保存,而是建议通过挂载云 硬盘的方式来保持本地状态信息。这样在服务异常时可以直接把云硬盘挂载在其他节点上 来实现快速恢复。


对于网络信息,最好的做法是不要通过 IP 地址,而是通过域名来进行访问。这样当节 点异常时,可以直接通过修改域名来实现快速的异常恢复。在网易云基础服务中,我们提供 了基于域名的服务访问机制,直接使用域名来访问内部服务,减少对网络配置的依赖。


文章节选自《云原生应用架构实践》 网易云基础服务架构团队 著 


网易云计算基础服务深度整合了 IaaSPaaS 及容器技术,提供弹性计算、DevOps 工具链及微服务基础设施等服务,帮助企业解决 IT、架构及运维等问题,使企业更聚焦于业务,是新一代的云计算平台。点击可免费试用