1、应用开发包含哪些核心领域?
2、应用开发之前需要对需求做哪些评审?
3、应用开发中如何进行科学的日志治理?
4、应用开发如何进行配置管理?
5、如何进行变更控制?
6、应用开发如何同架构设计和代码管理串联?
评审目标、评审清单、架构设计、代码管理、日志治理、日志规范、配置规范、变更控制、配置审查
大部分的软件开发最终在工程领域体现出来的是应用开发,涉及到前端应用,后端应用或者无线应用,如何将应用开发的过程抽象出来,盘点出核心环节,才能更好的把控应用开发的节奏,本文列出应用开发的全貌,试图扫除应用开发过程的盲区,以此作为理论基础指导应用开发出健壮高可用的软件系统。
总的来说,需求评审就是一个统一目标,明确需求,确定实现过程的会议。在需求会议上,产品经理需要跟大家明确需要解决的痛点问题,有哪些功能以及对应的计划,然后大家在会议上挑刺,讨论,甚至是撕逼,最终全体成员达成一致意见后开始开干。所以,通常一些项目需求都是要经过几次评审会才能完成的。
在正式的需求审查中,开发团队应引导客户完成系统需求,并解释每个需求的含义。审核小组应检查每个需求的一致性,并应整体检查需求的完整性。审阅者需要做出如下检查:
可验证性所述要求是否可以实际测试?
可理解性系统的最终用户是否正确理解需求?
可追溯性是否明确说明了需求的由来?
可追溯性很重要,因为它可以评估更改对系统其余部分的影响。
适应性需求适应性强吗?
也就是说,可以在不对其他系统需求产生大规模影响的情况下更改需求吗?
评审人员应指出需求中的冲突,矛盾,错误和遗漏,并正式记录在评审报告中。然后由用户,系统使用者和系统开发人员来协商这些已确定问题的解决方案。
每个软件需求是否都有唯一的标识符?
每个软件需求都可以验证吗?(如果可能,是否可正规化,量化)
是否对每个软件要求进行了优先排序?
所有不稳定的软件要求是否都已标明?
软件需求是否完整?(涵盖了所有用户要求,考虑了所有相关的输入情况)
软件要求是否一致?
是否明确指出了软件需求之间的重叠交叉?
是否明确规定了初始系统状态?
软件需求是否表达了逻辑模型, 而不是实现形式?
软件需求是否以结构化的方式表示为抽象层次?
是否足够清楚,逻辑模型的结构
软件要求是否已正式形式化?
是否已证明软件需求的关键属性?
所有形式化的图表材料是否都随附了充足解释性文字?
是否针对项目团队缺乏经验的领域描述了探索性原型?
接口规范,幂等,事务,重试,限流,降级,熔断
系分设计
系分评审
具体参考《分布式架构》
代码管理模块罗列出代码治理的主要框架,具体可以参考《代码三部曲》
问题排查
监控告警
业务分析
环境数据
数据统计
收集法则,不要收集从不计划使用的日志数据
留存法则,只要评估有可能用到, 就尽可能长时间地留存日志数据,如果有法规规定,还应该保留更长的时间
监控法则,记录所能记录的一切数据,但是只在必须响应时发出警报
可用性法则,权衡投产比,日志记录或者监控系统的可用性与业务系统相互匹配,无需过度设计
安全性法则,不要花费比保护关键业务数据更多的精力去保护普通可容忍丢失的日志数据
不断变化法则,日志来源,日志类型和日志消息都在变化,需要定期更新
业务隔离
系统安全
数据敏感
可监控
可排查
业务记录
性能监控
异常统计
摘要日志,报文日志,异常日志,异常统一输出
打印执行时间 统计
业务应用
三方调用
中间件
常用日志包含的必选字段:
日志日期
进程ID
日志时间
日志级别
代码位置
文件名称
签名名称
关键参数
错误编码
唯一标识
会话标识
可选字段:
服务地址
依赖服务
提供服务
关于日志格式的定义,我们应当遵循以下的原则:
明确日志分级,按照不同环境对应配置不同的日志级别
区分日志标签,不同业务类型的日志添加标签字段,用于快速定位日志
按照日期分类,用于日志按日期存储不同文件,也可用于业务上快速定位指定时间的日志文件
标准日志格式,日志应该有相对标准的格式,比如json,序列化,KVP等统一格式
不同业务范畴的日志要有清晰的命名,才可以快速定位日志数据,同时可以支撑日志自动化分析。日志文件主要是命名规则的统一,和文件的分类。
应用日志:
根目录日志文件root.log.xxxx-xx-xx
数据库脚本文件sql.log.xxxx-xx-xx
业务日志文件biz.log.xxxx-xx-xx
注册登录日志文件login.log.xxxx-xx-xx
异常错误日志文件error.log.xxxx-xx-xx
切面日志文件aop.log.xxxx-xx-xx
中间件日志:
垃圾回收日志文件gc.log.xxxx-xx-xx
web容器日志文件tomcat.log.xxxx-xx-xx
负载均衡日志文件nginx.log.xxxx-xx-xx
其他中间件日志xxxxx.log.xxxx-xx-xx
通常的日志目录会分为应用目录,中间件目录,系统目录,具体目录名称可以用正则表达式来定义。
日志级别是我们最熟悉不过的,按照对系统影响的严重程度从高到低排一次如下:
FATAL,导致应用程序终止的严重错误,控制台上立即可见
ERROR,应用程序运行时出现错误或意外情况,控制台上立即可见
WARNING,错误有可能已经发生了,出现警告,控制台上立即可见
INFO,通知用户一个操作或状态发生了变化,控制台上可以不用打印
DEBUG,有关执行系统的详细信息,这些数据仅写入日志文件即可
TRACE 更加详细的信息
开发人员需要使用的信息:DEBUG级等
运维人员需要知道的信息:ERROR级等
系统使用人员需要知道的信息:日志的输出和反馈等
系统审计人员需要知道的信息:关键业务INFO级日志
日志规范首要的当然是引用阿里巴巴的日志规约,加上一些参考规范如下:
应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架(SLF4J、JCL—Jakarta Commons Logging)中的API。
日志文件推荐至少保存15天,因为有些异常具备以“周”为频次发生的特点。
在日志输出时,字符串变量之间的拼接使用占位符的方式。
对于trace/debug/info级别的日志输出,必须进行日志级别的开关判断。
避免重复打印日志,浪费磁盘空间,务必在log4j.xml中设置additivity=false。
生产环境禁止直接使用System.out 或System.err 输出日志或使用e.printStackTrace()打印异常堆栈。
异常信息应该包括两类信息:
案发现场信息和异常堆栈信息。
为了保持一致性,日志声明为类中的第一个字段,第一行的变量位置,日志声明变量名应该全局规范统一,比如使用变量名“log”,使代码更简洁,同时降低开发人员理解代码的时间。
仅将TRACE用于跟踪执行流,跟踪级别的日志记录通常仅应用于跟踪代码的执行流程,用来判断标记程序中的特定位置是否被执行。
通常在开发的早期阶段会跟踪类的多个方法,完成开发后需要适当删除,TRACE语句过多可能会阻碍其他人对代码的阅读和应用的性能。
使用方法名称为所有日志语句添加前缀,日志记录的前缀设置为打印类名称,类名和方法名称之间可以使用固定的符号来约束,比如“>>”。
使用DEBUG向开发人员输出统计报告,dubug功能需要谨慎使用
使用INFO向管理员和用户输出统计报告
将日志存储在数据中心之外,起到灾备作用。
测试采集时间是的时间数量级,低延迟对于实时监控和故障排除很重要。
提取时自动解析日志,在搜索时解析日志的速度较慢,自动化匹配规则比自定义规则节省时间。
日志记录框架是专门用于标准化应用程序日志记录过程的实用程序,进而演化为框架。
框架选型:
考虑框架选型时,我们应当先考虑易用性
另一个关键考虑因素则是考虑性能问题
从代码库清洁度的角度来看,判断日志代码对业务的入侵程度
单元测试编写的便利性
框架对比:
原生API:java.util.logging
第三方:Log4j,Logback,tinylog
抽象层:SLF4J,Apache Logging
阿里巴巴日志服务:Log Service,LogHub
其他技术栈日志框架
日志的采集业界有FaceBook的Scribe、Apache的Chukwa、LinkedIn的Kafka、Cloudera的Flume等;阿里有TT,Tlog,Xflush, logtail等,产品比较丰富的。从采集方式来分, 有推和拉两种方式, 拉的方式以tlog为代表
性能损耗:
日志记录不应过于频繁,应考虑到日志记录到来的系统性能损耗
安全性:
不在日志中记录涉及安全的敏感信息,如在日志中记录用户密码是绝对禁止的
时效性:
应该定期清理没有参考意义的日志,避免日志积累过多占用系统存储空间
使用容错协议,使用TCP或RELP而不是UDP传输日志,这会丢失数据包。
如果发送失败,则自动重试,不可靠的协议可能会意外删除日志。
不要让本地存储耗尽所有的内存或磁盘空间,如果未配置限制或文件淘汰策略,则日志可能会因为空间过大导致服务器崩溃。
防止在发送文件时重传日志,在配置新服务器之前重新定位日志断点,或将守护程序设置为仅发送新日志。
传输前过滤敏感数据,通过不记录敏感数据或在数据离开网络之前对其进行清理来降低暴露程度。
核心机密数据需要加密传输,使用HTTPS或设置TLS证书以确保数据安全。
配置您的代理和防火墙,检查防火墙端口的系统日志,并将流量路由到具有Internet访问权限的服务器。
日志存储介质通常为文本类型或二进制类型,可以分为以下的载体:
系统自带文件系统
分布式文件存储系统如Elasticsearch
关系型数据库如MySQL
非关系型数据库如Mongodb
NOSQL数据库如Hbase
日志查询有赖于清晰的日志路径,合理的日志文件命名,还有核心的日志格式规范,在此基础上才能做到高效的日志检索。通常我们对日志检索分为人工查询和工具自动检索,人工查询根据不同的业务,查询对应的日志文件,通过命令脚本进行查询,而工具自动化检索则可以匹配目标日志关键信息,大大提升检索效率。
脚本查询的工具如下:
cat
more
tail
head
nl
grep
awk
sed
封装脚本的查询工具:
LogViewer
Graylog
Elastic Stack
LOGalyze
Fluentd
中间件日志查询工具:
GCViewer
garbagecat
gchisto
GCLogViewer
HPjmeter
随着云技术的普及,日志分析领域基本也被各大云厂商瓜分,上来上节提到的日志查询工具,现阶段厂商都提供了一站式的日志一条龙解决方案,比如阿里云的SLS或者EKL都是优秀的产品。
通常日志文件都有生命周期,不同业务领域对日志数据的持久化时间也各不一样,所有对不同类型日志指定不同的日志清除策略,对应持久保留的日志可以对接冷备文件系统,如OSS提供的服务。
软件配置管理是软件质量改进的核心环节。它贯穿于整个软件生命周期,主要目标是在减少错误的情况下提高生产率。
根据维基百科的定义,软件配置管理(Software Configuration Management,简称:SCM),又称软件形态管理、或软件建构管理,简称软件形管。界定软件的组成项目,对每个项目变更进行管控(版本控制),并维护不同项目之间的版本关系,以使软件在开发过程中任一时间的内容都可以被追溯,包括某几个具有重要意义的数个组合,例如某一次交付给客户的软件内容。
实施软件配置管理系统的主要原因是:
多人协作开发不断的更新软件的版本
在一个软件项目中可能涉及多个版本,分支,成员,并且团队在不同的空间并发工作,需要统一管理配置
确保系统应能够不同机器和不同操作系统上运行
配置管理流程也有利于节省系统变更所涉及的成本
配置识别:
识别配置、配置项目和基准
配置控管:
导入变更控管流程
配置状态:
记录和呈报与开发过程状态相关的所有必要信息
配置审核:
确保这些配置包含所有预期内容
建构管理:
管理用于建构的流程和工具
流程管理:
确保遵循企业组织的开发流程
环境管理:
管理承载系统的软硬件
团队合作:
促进流程中团队彼此间的交互
缺陷追踪:
确保可溯及每个缺陷的源头
配置标识是确定软件系统范围的一种方法,在此过程包含的步骤如下:
标识配置项,例如源代码模块,测试用例和需求规范。
该过程从基本对象开始,这些基本对象被分组为聚合对象
每个对象都有其自己的功能,这些功能可以标识其名称
所需资源列表,例如文档,文件,工具等。
基准是软件配置项目的正式版本,只能通过正式的变更控制程序进行变更:
促进构建应用程序的各种版本
定义和确定用于管理这些工作产品的各种版本的机制
功能基准对应于已审查的系统要求
基准包括功能、开发和产品基准
基线必须达到可以发布的标准
变更控制是一种过程方法,可确保在配置对象中进行变更时确保质量和一致性。在此步骤中,变更的请求将提交给软件配置管理器
控制临时更改以构建稳定的软件开发环境。
更改已提交到存储库
根据技术规范以及可能带来的副作用来检查该变更请求
管理变更并在软件生命周期中激活配置项
识别所有项目以定义软件配置
监控变更请求的状态
完整列出上一个基准以来的所有变更
允许跟踪到下一个基准的进度
软件配置审核将验证所有软件产品均满足基线需求:
通过检查已遵循定义的流程来进行配置审核
验证是否符合配置控制标准,审核和报告所做的变更
确保在变更过程可追溯
确保对基准所做的变更符合配置状态报告
完整性和一致性验证
Ansible
CFEngine
Chef
Puppet
Salt
应用程序开发是设计,构建和实施软件应用程序的过程。这可以由拥有大型团队从事项目的大型组织来完成,也可以由一个自由开发人员来完成。应用程序开发定义了应用程序的制作过程,通常遵循一种标准方法。如何完成应用程序开发有很多因素。所以必须考虑项目的规模,需求的具体程度,客户要更改多少东西,开发团队的规模,开发团队的经验以及项目的截止日期等因素,本章我们聚焦的是应用开发本身的内容,后续章节我们将介绍构建部署、软件测试、发布管理以及监控告警整个应用开发生命周期的整一套方法论。