【软考论文】论系统可靠性在系统中的实践
本文结合笔者实际经验,以该项目为例,讨论系统可靠性的基本概念,常见的可靠性保障方案,以及在系统可靠性实践中遇到的问题及解决方案。平台的研发耗时8个月,目前系统已经稳定运行了一年的时间,实践证明,这种架构设计有效的降低了系统的维护和开发成本,增强了系统的安全性,提高了系统的稳定性和扩展能力。
摘要
2021年初,我所在的研发部承担了公司自研XXXX管理平台项目的建设,为客户公司提供一站式的股权管理服务。我在该项目中中承担架构设计师的职务,主要负责该项目的系统架构、技术方案评估与实现、项目立项论证等工作。整个平台以多租户的模式,进行统一的管理及日常运营。平台整体逻辑复杂,对系统的高可用和高扩展能力提出了较高的要求。本文结合笔者实际经验,以该项目为例,讨论系统可靠性的基本概念,常见的可靠性保障方案,以及在系统可靠性实践中遇到的问题及解决方案。平台的研发耗时8个月,目前系统已经稳定运行了一年的时间,实践证明,这种架构设计有效的降低了系统的维护和开发成本,增强了系统的安全性,提高了系统的稳定性和扩展能力。
正文
随着国务院发布《关于支持浙江高质量发展建设共同富裕示范区的意见》中提到浙江到2025年和2035年要实现的共同富裕相关目标。越来越多的上市企业选择对员工开展XXXX计划。我所在的某集团公司,为了集团的发展,需要在XXXX这一赛道上保持竞争力,根据这一目标,XXXX管理平台这一项目应运而生。2021年初,我所在的研发部承担了公司自研XXXX管理平台项目的建设,为客户公司提供一站式的股权管理服务。我在该项目中中承担架构设计师的职务,主要负责该项目的系统架构、技术方案评估与实现、项目立项论证等工作。整个平台以为上市公司提供资金管理、财富管理、税务服务等一站式支持,涵盖股权管理、估值管理、多样化激励方案信息化管理、税务与财务咨询服务及系统个性化定制服务等,更高效、更便捷地为企业客户“一篮子”金融解决方案。整个平台涉及证券、税务、银行、电子签署等过个复杂业务逻辑,业务流程复杂、系统可靠性和可扩展性要求较高,响应的范围比较广。
在架构设计之初,笔者就意识到软件的可靠性设计对项目有着重要的影响,软件可靠性是指系统从故障中恢复的能力,可靠性越高的系统,运行更加稳定。然而在软件的世界中,故障无处不在。硬盘可能损坏,网络可能中断,消息可能丢失,内存可能跳变。在基于微服务的分布式软件系统中,各种各样的故障更是会层出不穷。很多时候我们期望能够完美预防所有故障的出现,但事实上这几乎是一个不可能实现的梦想。因此很多企业开始转变思路,从避免故障出现转向使故障出现时对系统不产生影响。现在很多 IT 公司都参考对系统进行故障注入测试,比如虚拟机复位,压力测试等。这些故障注入甚至会在生产环境中进行,因此所有开发人员很清楚他们开发出的应用必须能够应对这些故障,而不是祈祷一切正常。
一般来说,被认可的且具有应用前景的软件可靠性设计技术主要有容错设计、检错设计和降低复杂度设计等技术。其中常用的软件容错技术主要有恢复块设计、N 版本程序设计和冗余设计三种方法。恢复块设计是指选择一组软件操作作为容错设计单元,把普通的程序块变成恢复块。一个恢复块包含有若干个功能相同、设计差异的程序块。其中,一个运行块,多个备份块,构成“动态冗余”,一旦运行块出现故障,检错机制检测到 之后,就使用备用模块进行替换。N 版本程序设计是一种静态故障屏蔽技术。N 版本程序的核心是通过设计出多个模块或不同版本,对于相同初始条件和相同输入的操作结果,实现多数表决,防止其中某一软件模块/版本的故障提供错误的服务,以实现软件容错。这种技术实现成本非常高,往往需要调用不同的人员采用 不同的技术实现相同的功能,一般用在对可靠性要求较高的军事、航天领域。冗余设计是指在一套完整的软件系统之外,启用相同的模块或系统作为备份,在出现故障时可以使用冗余的部分进行替换,从而维持软件系统的正常运行。
笔者带领部门的同事经过一段时间的架构考察和评估,最终决定采用微服务架构建设新系统。采用微服务架构的目的是充分拆分庞大臃肿的系统,以促进软件的敏捷开发和部署。从实践角度来看,微服务的可靠性相较于单体系统更难以处理。这不仅受到服务本身可靠性的影响,还受到网络状况和相关联的微服务运行质量等因素的影响。因此,在设计微服务可靠性时,需要从集群容错、故障隔离和流量控制三方面入手。
集群容错包括路由容错、服务降级和熔断。通过路由容错机制,可以实现微服务的自动容错处理,从而提高系统的整体可靠性。但是直接在代码中引入路由容错,往往需要引入健康检测机制,这无疑会提高代码设计的复杂性。在该项目中,我们使用业内著名的中间件 Consul 对微服务进行治理。通过与 Nginx 相互配合,可以完美实现服务的容错。Consul提供健康检测功能,只要在服务注册的同时,配置相关的检测条件如 HTTP 请求为200,并指定在故障出现多久后自动将服务从注册中心注销。对于那些需要暴露在外网的服务,可以使用 Consul-Template 实例自动监测 Consul 集群的变化。若发现服务实例被注销,则按照事先定义好的 Nginx 配置模板重新生成 nginx.conf 并 reload 本节点的 Nginx,使得失效的服务从 Nginx 中删除,避免开放接口出现故障。对于处于系统内部的微服务,可以直接通过 Consul 提供的服务域名进行互相访问,对删除的服务实例不存在感知。这样一来,代码中也无需添加路由容错逻辑,降低了编码的复杂度。在服务降级方面,为了确保核心服务的稳定性和可用性,特别是在业务高峰期,有时需要暂时关闭一些非核心或次要的业务。例如,在XXXX管理服务中,晚间通常需要处理大量的报表计算工作,为了更有效地利用资源,我们选择在每天晚上12点至次日早晨6点期间,暂停股权管理服务中的大部分服务,仅开放部分数据查询接口供使用,其余资源则全部用于报表生成。这种服务降级策略能够有效保障复杂业务报表的正常生成。在微服务架构中,各个服务之间会通过HTTP 方式彼此进行通信,并等待其响应。然而,由于网络故障或其他原因,这个请求可能会失败或者无法得到及时响应。为了防止因这些异常导致请求方资源耗尽,我使用了开源的 Hytrix 框架来进行熔断配置。通过设定熔断参数,当请求错误率达到一定阈值时,断路器就会进入开启状态,所有新的请求都会被短路。一段时间后,断路器会变为半开状态,如果下一个请求成功了,断路器就会关闭;反之,它会继续保持开启状态。Hytrix 将每个微服务的请求放入线程池中,实现资源隔离。即使某个依赖服务出现问题,也不会影响应用程序的其他部分。因此,我在项目中为关键服务都配置了熔断机制,以防止大规模的超时等待情况发生。
在故障隔离和流量控制方面,我们也做了一些探索。微服务鼓励软件开发者将整个软件解耦为各个功能单一的服务,并且这些服务能够独立部署、升级和扩容。我们使用Docker容器部署微服务,实现了高密度的微服务部署,同时也实现服务之间的资源层隔离。为了更好地管理和保护微服务的稳定性和性能,我们在流量控制方面进行了一些优化。当资源成为瓶颈时,服务框架需要对消费者做限流,启动流控保护机制。流量控制有多种策略,比较常用的有针对访问速率的静态流控和针对资源占用的动态流控等。为了防止开放接口被频繁外部频繁调用,我们通过公司的公共网关针对访问速率的静态流控。静态流控主要针对客户端访问速率进行控制,它通常根据服务质量等级协定 SLA 中约定的 QPS做全局流量控制。一旦设置静态流控阈值为某个 QPS,则无论集群有多少服务实例,它们总的处理速率之和都不能超过这个数值。通过这种静态流控策略,我们可以有效地限制客户端的请求速率,防止因过多请求导致的服务器过载或崩溃。同时,这也有助于保护系统的稳定性和可用性,确保每个服务实例都能够正常地处理请求并提供稳定的响应。除了静态流控外,我们还使用了动态流控来进一步优化流量控制策略。动态流控是根据系统的实际资源占用情况来进行流量调整的策略,可以根据当前的负载情况动态地调整请求速率限制。这种策略可以帮助我们更精确地控制访问速率,适应不同的工作负载和需求变化。
实践证明,关注可靠性以后,架构设计中引入了许多中间件,带来了大量的运维和部署问题,但是对于XXXX管理系统这样的核心系统来说,在可靠性方面的投入是值得的,通过微服务的集群容错、故障容错和流量控制,增强了系统的可靠性,系统上线一年以来运行稳定,没有出现业务中断现象。但是目前在可靠性监控方面没有一套自动化的监控工具,因此笔者团队很难及时发现系统中存在的问题,有时候可能系统出现重大故障才去进行定位排错。因此,在项目二期决定建立一整套的故障监控告警平台,从主机、数据库、服务等三个方面入手,打造一个自动发现及时告警的监控平台,持续提升数据中台的运行质量。
【软考论文】论系统可靠性在系统中的实践