电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

软件架构乱弹:问题域及其解决方法


发布日期:2022/2/25
 

什么是架构

和架构相关的几个问题域

架构需要解决的非业务问题域包括如下

A 系统目标系统性能稳定性

B项目目标开发成本质量

C项目过程需求的不确定性和开发过程的团队协作性

不同的问题域解决之道也不相同!而同一问题域的不同层次的要求解决之道也不尽相同

什么是架构

架构到底是啥愚以为下面的这段英文描述的很清楚

Thats like asking what is culture? Culture is the way you do things in a group of people Architecture is the way you do things in a software product You could argue by analogy then that architecture is to a software product as culture is to a team It is how that team has established and chosen its conventions

Which leads us inevitably to the question of goodness? How do you know if an architecture is good? Consider an architecture that isnt built using a strong domain model and instead relies heavily on stored procedures That might be OK or it might not be OK You could have decided that part of your architecture is to use a really strong domain model and not use stored procedures right? So an architecture is some reasonable regularity about the structure of the system the way the team goes about building its software and how the software responds and adapts to its own environment How well the architecture responds and adapts and how well it goes through that construction process is a measure of whether that architecture is any good

The system architecture determines how hard or easy it is to implement a given feature Good architectures are those in which it is considered easy to create the features desired In that the way to judge whether an architecture is good is whether the architecture is good for the purposes to which it is applied

The definition of goodness has to be related to fitness for purpose Is this glove good? I dont know What are you doing with the glove? Are you throwing snowballs cooking barbeques or playing golf? Theres a set of changes that are going to occur to a software system over time Probably the utilitarian or most useful definition of goodness is the answer to this question: are the changes that will keep this system successful in this domain in this product line relatively easy? If they are then its probably a good architecture

架构的背后

为了实现架构的目标涉及到以下三个方面技术组织和过程这里举例说明

) 技术对开发效率和运行性能以及组织和过程的影响

案例A.映射的问题公司产品的一个重要需求是根据客户输入映射到PDF文件上技术上整体实现需要四个步骤在PDF文件上画好所有的数据域通过读入一个XML映射文件获得运行数据并生成FDF合并FDF和PDF生成目标文件后两步工作都由代码自动化了因而实现的主要工作在于前两步

在第一个实现版本里XML映射文件的DTD太简单致使一个xml文件至少在行左右同时xml文件太verbose了这样的结果直接导致运行系统在峰值时由于XML消耗了大量内存G的内存根本吃不消同时对XML解析执行使用了CPU的大量时间导致开发人员需要做大量的工作开发效率降低了通常需要尽一周才能完成一个xml文件员工都不愿意做也导致开发过程的漫长 开发部门对于BA部门和ST部门的要求反应变的缓慢

在第二个版本的实现中重新实现了DTD加入了大量的关键字同时也消除了verbose大量的缩小了XML大小多行减低到多行不仅减低了内存使用提高执行效率也提高了开发效率基本只要一天就可以完成一个映射文件同时对BA部门和ST部门的反应也快了

案例B脚本的问题产品在web层提供了脚本支持出于方便开发的目的但是没有对脚本的环境限制脚本可以做系统程序的大部分工作导致开发人员偷懒在web层混入了大量业务逻辑代码最终造成业务逻辑分散而不可控制

) 组织结构对技术开发效率和应变能力的影响

案例A部门的分工问题开发部门根据不同的职责分成AB和C等数个小组大部分开发中互不相干但也有时候需要跨组的支持比如B要实现某个需求需要A在一定条件在记录一个或多个信息因为每个开发人员各自负责一部分工作导致跨组沟通的困难同时由于整个开发部采取任务绩效有时间压力加上只是一个小的要求于是在A人员的同意下B人员直接在A代码中写入业务逻辑每次都是这样的小改动不断的发展后代码开发变凌乱

案例B开发的历史问题当某个开发人员写下的代码有是问题的接手开发人员由于文档不全以及没有测试用例不愿意承担变化的代价选择小修小补这个小修小补有可能和有问题的代码混杂导致更大的代码

) 过程对开发效率和应变能力以及组织的影响

案例A过程的问题开发部门的上下游部门BA部门和ST部门的合作关系ST部门的绩效考核考核基于发现错误的数量导致ST为了完成任务提出一些非正常性要求PM部门出于部门的方便通常提出一些实现难度比较大要求开发部门本身又存在时间压力导致一些需求的实现本应在低一层的代码中实现的却在高层用蹩足的方式实现

案例B帮助系统的问题帮助系统一开始采用一个个单独分散的静态页面出于性能的考虑和部门负责考虑帮助系统不断改进中过程缺乏组织性文件的命名规则随意存储位置随意造成了管理的混乱直接的后果是页面的入口混乱和各自引用关系混乱

在帮助系统的第二版从静态页面转成动态页面采取统一分类和命名规则并统一了入口同时采取分级管理引用关系适度冗余虽然减低了运行性能但提高了开发效率和可维护性

架构的性能问题解决讨论

性能问题——嗯一个非常神圣而高深的问题的从我刚刚开始工作的时候至今依然是然而我相信一定存在一个基本的思路和方法我以为解决性能问题的工作还是在于分解通过分解来确定问题域

先介绍三个公式性能问题的公式:

总处理单量 = 总处理时间/ 单笔请求处理时间 * 总并发数

这个公式另一个写法为:

总处理时间 = 单笔请求处理时间 * 总处理单量 / 总并发数

不同的写法代表不同个关注点适合不同类型的业务类型 一般说前一种写法代表在线请求的后一种写法代表后台batch

也有客户给明确要求系统要支持xxx并发这个就需要了解客户的这个并发数是如何计算得来需要通过分析客户的业务而通常是根据总处理单量来确定客户实际的并发数

但无论如如何四个变量中总处理单量和总处理时间是先被确定的换句话说需要关注是单笔请求处理时间和并发数也就是降低单笔请求处理时间或者增加并发数

对于单笔请求处理时间其公式为

单笔请求处理时间 = 数据计算时间 + 数据读写时间+其它技术导致时间消耗

很显然降低单笔请求处理时间就需要降低三个因素消耗的时间

降低单笔请求处理时间第一原则是 只计算一次缓存计算结果

降低数据读取时间分三种

Global的系统启动时加载

Long Time 可采用LRU方式cache

Per operation 第一次访问加载operation结束后丢弃

降低数据写入时间

例如文件写入通过buffer一次flush对于SQL采用batch提交(hibernate的做法)

改进计算时间针对不同技术结构采用不同手段

让计算支持并发提高性能例如采用MapReduce的方式

改进算法例如数据库中的SQL改进

减少不必要计算时间

减少其它技术原因导致的消耗

如JVM的GC导致性能消耗等

对于总并发数其公式为总并发数 = 单机服务器并发能力 * 总并发服务器数

那么如何确定那些因素需要调整呢在于两个方面的分解

业务层面

业务层面只是指通过业务行为分析 把性能问题分解为不同的部分每个部分面临性能压力现状和目标最终确定需要优化的问题域

业务层面分解包括个内容: 功能 内容时间和区域最重要的是前三个

以ebay为例 ebay对于前端功能划分划分为多个功能不同的服务器处理不同的功能

内容是指内容热点比如对于search来说就按体育数码音乐等划分不同内容有不同热点数据以及不同搜索关键匹配

时间 时间是一个非常重要的因素在一些特点是时间段呢性能的要求会非常高比如下半夜的访问点击量和白天的就有不同对于一些batch来说 月末或者年末处理的单量就有明显的提高比如分红险的记息平时每天只有而年末会有w单

地点划分不太常见不过也有助于分配计算资源

业务层面的分析不仅是确定问题所在还是确定优化的策略比如有一个batch计算执行时间比较长而通过业务分析发现该计算只针对特定的业务 系统全部有效单量是w单而符合计算要求的只有只要加上一个前置判断就可以免除无谓的计算运行时间减少数个小时(大约秒一单)

技术层面

系统建立时技术结构通常一个系统结构如下:接入网络Web服务器应用服务器以及数据库服务器

在这样结构下要小心的分析和验证系统性能的瓶颈需要优化Web服务器或者提高数据库并发能力等等这部分网上的资料非常多

架构的开发成本以及品质问题解决讨论

架构一个重大关注点在于控制开发成本这点很重要因为通常讲维护成本是开发成本的降低开发成本核心在于提高效率这也意味着提高了开发对需求的响应时间而时间对公司来说是重要的

提高开发效率和品质的基本手段是分解——即充分的分离系统中不同的关注点好处不用说了可以并发的工作每个人面对的问题都简单而容易操作而与分解对应的集成只有提供了好的集成能力分解才成为现实而只有分解了才能清晰的提供业务更多适应性

分解和集成的手段分为编程语言和技术框架两个层面所谓语言就是强框架而框架就是弱语言

现代面向对象的语言提供如下能力抽象和派生能力以及接口隔离能力实际提供两种分解和集成能力

把逻辑分解在两个层次中而通过继承的方式把两个部分集成在一起

把逻辑的外观和实现分解在两个地方而通过接口实现的方式把两部分集成在一起

另一种语言AspectJ或者C#语言之后提供的特性把流程逻辑分解在不同的地方而通过签名匹配利用代码生成的方式来把几部分集成在一起

然而语言提供的集成能力毕竟底层而且有限扩展起来也格外小心因而技术框架提供另外的集成能力就格外重要

对象关联关系的分解和集成如Spring提供容器管理能力

模块间关联关系的分解和集成如OSGiESB等

不同系统的类型分解和集成如Spring利用动态代理提供的Exporter模式

流程逻辑的分解和集成如Spring Web Flow以及jBPM

讨论完手段现在要转身看看我们面临的问题域了问题域可分解为两种类型业务上和技术上(又见分解分而治之真是老祖宗传下的灵丹妙药啊)

业务上问题域分解为逻辑的纵向抽象层次以及逻辑的横向模块分解和集成

技术上问题域分解为纵向的技术主题以及横向的技术职责的分解和集成

所以通常而言领域模型设计中模块分解抽象分层和职责分层都是重要手段问题域为流程业务实体和计算(包括规则)

对象的抽象分解和集成

对象的依赖分解和集成(模块内和模块外)

流程的分解和集成(页面流工作流以及计算流程)

进程边界用户请求重定向以及业务数据持久化等

BTW通常语言做为架构的基础引入和更换是有巨大风险的而通过提供强大的框架能力框架尽可能多的完成技术问题并通过元数据模式以及约定降低业务和框架的耦合避免因为框架升级带来不必要的成本

从技术手段上提高开发效率的另外两个手段是代码生成和类库引用但代码生成和类库引用都只解决了逻辑的分解能力没有提供集成能力所以一般情况下需要提供框架集成尤其代码生成需要在系统的最外层避免集成带来的问题

对于开发团队来说额外面临一个问题组织内部的学习成本问题

需要保持分解以及集成能力本身的简约性

这个……其实是一个culture问题不再罗唆!

采用模式和约定是减少学习成本的另一种手段ROR的兴起就是最好的例证

总结一下解决架构面临开发成本问题需要如下几个方面

问题域

分解与分层

架构与类库SpringHibernate起支撑性作用

模式和技巧

领域模型

方法论

开发方法OO(设计模式)FP(函数式编程)

设计方法Domain Model Prototype和业务行为的分析模式

架构面临的品质问题则通过自动化测试代码检测工具来完成

必须大量应用自动化测试减少人工硬调试的复杂性重复性和不确定性

自动化测试包括单元测试和集成测试无论是单元测试还是集成测试对面临需要脱离隔离依赖关系并保证开发的并行性

上一篇:学生管理系统:公用模块编写[2]

下一篇:连锁中心配送系统:用户信息的添加[1]