论软件可靠性设计及其应用
摘要
2023 年 3 月,我所在的公司承接了某智慧加油站平台的建设工作。该项目旨在帮助加油站提升运营效率、降低运营成本和提高销售额。我在该项目中担任系统架构设计师,负责整个项目的架构设计工作。
本文结合我在该项目中的实践,详细论述了软件可靠性设计技术的具体应用。我们主要采用了防卫式程序设计、集群技术和检错技术三种可靠性设计技术。我们采用防卫式程序设计预见潜在错误并提前采取措施,采用集群技术避免单点故障,采用检错技术及时发现故障并报警。通过以上三种技术,我们有效地提升了系统的可靠性。
整个项目历时 10 个月开发完成,并于 2023 年 12 月正式交付并稳定运行至今,各项功能和性能指标均达到了客户要求,得到了客户和各级领导的一致好评。
正文
项目背景
随着国内成品油零售行业竞争日益激烈,某油企为增强市场竞争力,决定建设一个智慧加油站平台,通过引入信息技术来优化运营管理,进一步提升加油站的管理水平和服务质量。我所在的单位成功中标该项目,并于 2023 年 3 月正式启动该项目的建设工作。我被任命为系统架构设计师,负责该项目的系统架构设计工作。
该项目的主要建设内容包括智慧支付、智慧营销、智慧运营等功能子系统。其中智慧支付子系统提供了对多种支付方式的支持,比如现金支付、油卡支付、微信支付、支付宝支付、云闪付支付、车牌付、人脸付、ETC 支付等,以确保顾客下单支付的便利性和安全性;智慧营销子系统支持开展多种形式的营销活动,比如消费返券、趣味抽奖、积分任务、限时秒杀、充值优惠等,以提高顾客复购率;智慧运营子系统涵盖了站务管理、运营数据统计分析等功能,以提高加油站运营效率。
该项目选用 Java 作为主要开发语言,采用基于 Spring Cloud Alibaba 的微服务架构进行构建。我们选择 MySQL 作为数据库,Doris 作为实时数仓,Redis 作为分布式缓存,RocketMQ 作为消息中间件,Flink 作为实时流式计算引擎,并最终在 Kubernetes 集群中部署运行。
可靠性设计的重要性
由于加油站是一个高度运转的环境,任何故障都可能影响加油站的正常运营,因此保障系统的可靠性显得至关重要。软件可靠性是指软件在一定的时间内持续无故障运行的能力,通常使用通常用平均失效等待时间(MTTF)和平均失效间隔时间(MTBF)来衡量。
主流的可靠性设计技术主要有防卫式程序设计、集群技术和检错技术。防卫式程序设计强调在编写代码时采取预防措施,以确保程序在面对意外情况、不合理的输入或错误的使用时,仍能保持稳定运行,避免产生不可预见的行为。集群技术是一种将多台服务器连接在一起,共同工作以实现特定目标的技术。这些节点通过高速网络连接,对外表现为一个单一的系统,共同承担计算任务、数据存储和应用程序的运行。检错技术是指在软件系统出现故障后能够及时发现并告警,提醒相关人员进行处理。检错技术的代价一般低于容错技术和冗余技术。检错技术有一个明显的缺点,那就是发现故障后不能自动修复故障,需要人工进行干预。
在该项目中,为了提高系统的可靠性,我们主要采用了防卫式程序设计、集群技术和检错技术三种可靠性设计技术。下面我将详细介绍这三种可靠性技术在该项目中的具体应用。
防卫式程序设计
我们采用防卫式程序设计来预见错误并提前采取措施来减少这些错误的影响。在智慧营销子系统中,加油站通常会和合作商家联手开展个性化的营销活动,以此提高用户的忠诚度和复购率,一种常见的合作形式是用户在智慧加油站平台中参与营销活动后所获得的奖励需要通过合作商家提供的开放的 API 接口进行兑换。然而,合作商家的系统可能存在不稳定的情况,比如频繁请求响应慢或请求超时等问题。为了避免该系统被这些外部系统拖垮,在智慧营销子系统开发之初,我们就设计了熔断的处理策略。当检测到合作商家的 API 接口在一段时间内频繁出现响应慢或者请求超时等问题,系统会立即停止对合作商家 API 接口的调用,防止问题的进一步扩散。这样可以确保其他子系统的功能不受影响,依然能够正常运行。在熔断期间,系统会持续监测合作商家的系统状态,并定期发起试探性的请求,如果试探请求正常了,则恢复对其接口的正常调用,以恢复奖励兑换等功能。通过熔断措施,我们有效控制了外部系统故障的影响范围,避免了局部的故障逐渐演变为严重的系统事故。
集群技术
我们采用集群技术来避免单点故障。为了简化集群的管理,我们最终将系统部署运行在 Kubernetes 集群上。Kubernetes 可以管理多个工作节点,每个工作节点上可以部署多个服务,此外,还提供自动故障转移和服务自愈的能力。我们将整个系统划分为多个可以独立开发、独立部署的小服务,每个服务开发完成后,我们将其打包成为 Docker 镜像,并编写该服务的 Deployment 描述文件,在这个文件中配置所需的 CPU 资源、内存资源以及期望的服务副本数量等信息。然后通过 kubectl apply 命令将该服务部署到 Kubernetes 中,多个服务实例会被均匀地部署到多个工作节点上。Kubernetes 会定期检查这些服务实例的状态,确保它们按照预设的数量正常运行。如果某个工作节点宕机了,该工作节点上的服务实例会在其他工作节点上重新部署,从而实现了自动故障转移。如果某个服务实例意外停止或崩溃,Kubernetes 将自动创建新的服务实例来确保服务实例数量与预设的数量相符,从而实现了服务自愈。这一过程无需人工干预,有效地保障了系统的稳定性和可靠性。
检错技术
我们采用检错技术确保能够及时发现故障并报警,提醒相关人员进行处理。我们采用了 Prometheus 和 Grafana 搭建了一套实时自动化的监控告警系统,用于监控各个工作节点、服务以及组件的运行状态和关键指标,比如内存使用率、CPU 使用率、磁盘使用率、网络带宽占用、响应时间 TP99、请求错误率等。当检测到异常时,该监控告警系统就会自动触发告警,提醒相关人员处理。提醒的方式主要包括短信和企业微信。通过这种方式,我们可以对系统的健康状况有一个全面的了解,并且可以在问题发生时迅速做出反应。
例如,在一次消费送积分的营销活动中,监控告警系统检测到积分服务的响应时间突然增加,并触发了告警。我们收到告警信息后,通过查看 Grafana 的可视化实时监控图表发现某个工作节点的磁盘使用率达到了 100%,然后我们对该工作节点进行了进一步的排查,发现了问题源头在于该工作节点的磁盘被大量日志文件占满了,这导致积分服务无法正常提供服务。于是我们迅速采取了行动,清理了不必要的日志文件,并优化了日志的存储策略,解决了磁盘空间不足的问题,恢复了积分服务的正常运行。
总结与感悟
通过以上可靠性设计技术的运用,我们有效提高了系统的可靠性,从而确保了业务的连续性。最终,经过 10 个月的研发,该项目于 2023 年 12 月完成并交付上线,至今运行稳定,各项功能和性能指标均达到客户要求,得到了客户和各级领导的一致好评。虽然项目取得了成功,但我们也看到了一些不足之处,其中需求频繁变更导致项目团队经常加班是比较突出的问题。针对这个问题,我们采取了以下两个措施:一是规范需求变更流程,提升变更成本,以避免过度的需求变更;二是通过灵活的配置和架构设计,低成本响应需求变更。
通过该项目的开发,我在系统分析与设计方面积累了不少宝贵的经验,为我后续的工作提供了很大的帮助。这也激励着我不断学习,不断丰富自己的知识体系,为将来能够应对更复杂的工作做好准备。
相关文章:
论软件可靠性设计及其应用
摘要 2023 年 3 月,我所在的公司承接了某智慧加油站平台的建设工作。该项目旨在帮助加油站提升运营效率、降低运营成本和提高销售额。我在该项目中担任系统架构设计师,负责整个项目的架构设计工作。 本文结合我在该项目中的实践,详细论述了…...

Android中桌面小部件framework层使用到的设计模式
在Android中,桌面小部件(App Widget)的Framework层采用了多种设计模式,以实现模块化、可维护性和高效的交互。 以下是Android桌面小部件Framework层中常用的设计模式及其具体应用: 1. 观察者模式(Observe…...

【JavaEE进阶】HTML
本节⽬标 认识 HTML 的基本结构, 学习常⽤的 HTML 标签. 一 HTML基础 1.什么是HTML HTML(Hyper Text Markup Language), 超⽂本标记语⾔. 超⽂本: ⽐⽂本要强⼤. 通过链接和交互式⽅式来组织和呈现信息的⽂本形式. 不仅仅有⽂本, 还可能包含图⽚, ⾳频, 或者⾃已经审阅过它…...

ElasticSearch 添加IK分词器
ElasticSearch 添加IK分词器 前言一、IK分词器的算法二、Ik分词器的下载安装(Winows 版本)三、Ik分词器的下载安装(Linux 版本)四、验证测试(postman工具)测试 ik_smart 分词算法测试 ik_max_word 分词算法…...

可视化建模与UML《顺序图实验报告》
旷野的规则是永不回头。 一、实验目的: 1、熟悉顺序图的构件事物。 2、熟悉发送者与接受者的关系 3、熟练掌握描绘顺序图 4、加深对顺序图的理解和应用能力 二、实验环境: window7 | 10 | 11 EA15 三、实验内容: 据如下描述绘制顺序图&…...

Mac的极速文件搜索工具,高效管理文件
Mac的资源管理可以说是许多转Mac的朋友用不明白的一点了,访达怎么用,文件怎么找,为什么找不到,非常的头大 All作为Mac上的极速文件搜索管理工具,有效的为文件查找困难的用户解决难题 基于极速搜索引擎,快…...
公开仓库改私有再配置公钥后Git拉取仍需要输入用户名的问题
问题描述:git拉取私有仓库需要输入用户名和密码 我之前写了一个脚本用来定时自动拉取远程仓库更新本地仓库,后来将这个远程仓库改成私有后执行脚本就会需要输入用户名和密码。 [rootLH2020 ~]# ./sync_repo.sh 正在从远程仓库拉取最新更改… Username f…...

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置
工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置...-CSDN博客 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明-CSDN博客 工作…...

window下安装rust 及 vscode配置
安装 安装mingw64 (c语言环境 选择posix-ucrt) ucrt:通用c运行时库配置mingw64/bin的路径到环境变量中在cmd窗口中输入命令 "gcc -v" 4. 下载Rust安装程序 安装 Rust - Rust 程序设计语言 5. 配置rustup和cargo目录 (cargo是包管…...
【数据结构】【线性表】单链表1—概念即创建(附C语言源码)
单链表的定义, 链表用链式存储的方式实现线性表,链表中每个结点元素中需要指向下一个结点的指针(有时候也要指向上一个结点的指针),链表中的每个结点指针只指向下一结点的被叫为单链表。 单链表的创建和初始化 先定…...

centos7的maven配置
首先进入conf配置文件夹下的setting.xml 要改两个地方 第一:设置镜像源 <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>https://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>c…...
day57 图论章节刷题Part08(拓扑排序、dijkstra(朴素版))
拓扑排序-117. 软件构建 思路:拓扑排序是经典的图论问题。给出一个有向图,把有向图转成线性的排序就叫拓扑排序,拓扑排序也要检测有向图是否有环,即存在循环依赖的情况,因为这种情况是不能做线性排序的,所…...

【Steam登录】protobuf协议逆向
https://api.steampowered.com/IAuthenticationService/GetPasswordRSAPublicKey/v1 搜索 input_protobuf_encoded定位 input_protobuf_encoded的值就是 o s r.SerializeBody() o i.iI(s) 精准定位 打上条件断点:t ‘Authentication.GetPasswordRSAPublicKey…...

git 对已提交的说明进行编辑
如果提交代码的时候,对上次提交代码的说明不准确的话,例如 1、可以使用 git log 查看代码提交的记录; 2、使用 git commit --amend 命令对上次提交的说明进行编辑: 当显示上次提交的内容的时候,按下键盘 i 键即可编辑…...
CTF —— 网络安全大赛
前言 💻随着大数据、人工智能的发展,人们步入了新的时代,逐渐走上科技的巅峰。 ⚔科技是一把双刃剑,网络安全不容忽视,人们的隐私在大数据面前暴露无遗,账户被盗、资金损失、网络诈骗、隐私泄露ÿ…...
【大数据测试spark+kafka-详细教程(附带实例)】
大数据测试:Spark Kafka 实时数据处理与窗口计算教程 1. 概述1.1 大数据技术概述1.2 Apache Kafka 与 Spark 的结合 2. 技术原理与流程2.1 Kafka 简介2.2 Spark Streaming 简介2.3 数据流动与处理流程 3. 环境配置3.1 安装依赖项 4. 实例:实时数据处理与…...
如何为 GitHub 和 Gitee 项目配置不同的 Git 用户信息20241105
🎯 如何为 GitHub 和 Gitee 项目配置不同的 Git 用户信息 引言 在多个代码托管平台(如 GitHub 和 Gitee)之间切换时,正确管理用户信息至关重要。频繁使用不同项目时,若用户配置不当,可能会导致意外提交或…...

【Lucene】原理学习路线
基于《Lucene原理与代码分析完整版》,借助chatgpt等大模型,制定了一个系统学习Lucene原理的计划,并将每个阶段的学习内容组织成专栏文章,zero2hero 手搓 Lucene的核心概念和实现细节。 深入的学习和专栏计划,覆盖Lucen…...

Go语言的并发安全与互斥锁
线程通讯 在程序中不可避免的出现并发或者并行,一般来说对于一个程序大多数是遵循开发语言的启动顺序。例如,对于go语言来说,一般入口为main,main中依次导入import导入的包,并按顺序执行init方法,之后在按…...

SpringBoot框架在资产管理中的应用
3系统分析 3.1可行性分析 通过对本企业资产管理系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本企业资产管理系统采用Spring Boot框架,JAVA作…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
书籍“之“字形打印矩阵(8)0609
题目 给定一个矩阵matrix,按照"之"字形的方式打印这个矩阵,例如: 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为:1,…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...