SaaS RES营销管理系统架构设计_第1页
SaaS RES营销管理系统架构设计_第2页
SaaS RES营销管理系统架构设计_第3页
SaaS RES营销管理系统架构设计_第4页
SaaS RES营销管理系统架构设计_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

SaaS RES营销管理系统 SaaS RES 系统架构 设计 目 录 1 项目背景 . 1 2 关键需求 . 1 2.1 关键功能需求 . 1 2.2 关键非功能性需求 . 2 2.3 关键商业需求 . 3 2.4 关键约束 . 3 2.5 名词解释 . 3 3 参考资料 . 4 4 系统功能分析 . 4 4.1 SaaS 模式下功能分析 . 4 4.2 业务功能划分 . 6 4.3 子系统划分 . 6 5 架构设计 . 6 5.1 架构分析 . 6 5.1.1 业务实体的增、删、改及一些复杂的业务处理功能 . 6 5.1.2 对象的查询业务、报表业务 . 11 5.1.3 创建订单 典型的高并发资源争用业务 . 14 5.1.4 数据权限控制 . 15 5.1.5 支持多租户的数据结构 . 18 5.1.6 基于单域名的租户访问方式 . 18 5.1.7 租户带宽上的限制 . 19 5.1.8 租户存储数据分离和受限动态路由 . 21 5.1.9 租户敏感数据加密 . 22 5.1.10 可配置性 产品模块可配置 . 23 5.1.11 BOSS 运营系统与 RES 业务系统的消息交互 . 23 5.1.12 整合第三方系统 企业级服务总线( ESB) . 26 5.1.13 动静分离 . 27 5.1.14 伸缩性 . 27 5.1.15 安全性 应用安全 . 32 5.1.16 安全性 数据安全 . 33 5.1.17 安全性 网络安全 . 33 5.1.18 监控 服务器监控 . 34 5.1.19 监控 网络监控 . 34 5.1.20 监控 数据库监控 . 34 5.1.21 数据存储 . 34 5.1.22 物理空间扩展 . 35 5.1.23 系统升级 . 35 5.2 逻辑架构 . 36 5.2.1 制作平台和试用平台 . 36 5.2.2 总体架构图 . 36 5.2.3 最小架构图 . 41 5.2.4 技术架构 . 42 5.2.5 功能模块 . 42 5.2.6 模块架构详解 . 47 5.3 物理架构 . 47 5.3.1 总体架构网络拓扑图(使用存储设备) . 48 5.3.2 最小架构网络拓扑图(不使用存储设备) . 48 5.3.3 各层次对硬件的要求 . 50 5.3.4 虚拟化 . 52 5.3.5 模块部署图 . 52 5.3.6 硬件设备 . 53 5.4 数据架构 . 53 5.5 开发架构 . 54 5.5.1 Bundle 划分规则 . 54 5.5.2 项目工程划分规则及项目目录结构 . 55 5.5.3 部署目录结构 . 56 5.5.4 开发技术框架使用规则 . 57 5.6 运行架构 . 57 5.6.1 登录和访问流程 . 57 5.6.2 与 BOSS 运营系统有关帐户信息的交互流程 . 60 5.6.3 与 BOSS 运营系统有关产品模块信息的交互流程 . 60 5.6.4 与 BOSS 运营系统有关系统消息的交互流程 . 60 6 架构验证 . 60 6.1.1 性能 . 60 6.1.2 安全性 . 60 6.1.3 可扩展性 . 60 6.1.4 可运维性 . 61 7 风险评估 . 62 7.1 数据库无法支撑大量租户风险( IO 瓶颈) . 62 7.2 高峰期的访问风险 . 62 1 项目背景 SaaS 源于一种简单的思想:软件即服务!随着一大批 的公司, 如国外的 Salesforce 在这个领域取得的辉煌成绩, SaaS 已经彻底改变了人们对软件的观念,使用软件的人从产品消费者转换成服务消费者,而开发软件的人从产品提供者转变为服务提供者。 为了顺应当今 IT 企业级应用的发展趋势和满足公司战略发展的需要,本 架构文档 旨在描述 在 SaaS 这种 商业模式下,如何搭建 适合目前公司现状的 企业信息化 系统 。 对于 SaaS 商业模式,简要描述如下: SaaS 模式无论是对于用户,还是对于软件开发商都有 着巨大的优势。 从用户方面来看:用户可以只花少量的资金就可以使用一款软件了,并可以很直观的评估软件是否满足要求或者是否适合公司的管理模式,大大降低了软件产品的资金投入以及风险。另外,用户不需要维护软件、以及硬件本身,可以按照自己的需要定制,按需使用。大大降低了成本。最后,由于软件是托管 在运营商,往往有更好的服务保障和防毒措施,用户可以放心的把这一部分 的开支节省下来,去投入到更重要的地方。 从软件商来看: SaaS 模式大大节省了销售的成本,软件商可以把重点资源放在市场推广方面,销售反而是顺理成章的事情。另外 SaaS 也为软件商节省了维护成本,以往的维护都是一对一的,甚至要到客户现场。这种模式势必导致成本剧增,而 SaaS 却能保证软件对客户的服务响应快捷和高效。最重要的是 SaaS 给软件商提供了稳健的经营模式,有利于企业不为销售和各种售后服务疲于奔命,而可以将更多精力放到产品的研发和推广上去,不断提高客户服务质量和系统维护水平。 SaaS RES 就是 SaaS 商业模式 下 的房地产营销管理系统。 主要为各个房地产商提供低成本的、按需购买功能的营销解决方案。 2 关键需求 2.1 关键功能需求 与 SaaS BOSS 运营支撑系统进行交互 : SaaS BOSS 系统主要对整个 RES 业务系统的正常运营起到 管理和 支撑作用。比如创建租户第一人,配置租户可使用的产品模块,各种系统通知消息 ,状态查询 等等。 业务实体的的增、删、改及一些复杂的业务处理功能:对于 SAAS RES 系统来说,业务实体的增、删、改是最常见的操作,它们属于业务实体的维护操作,在系统的产品管理、客户管理、销售管理、服务管理和财务管理模块都普遍存在,这些操作都包括一些数据校验,业务约束等处理逻辑,除了业务实体的增、删、改等数据维护操作外,一些复杂的业务处 理功能也具有相当的典型性,这些复杂的业务 处理通常涉及多个业务实体的状态变化以及它们之间的业务约束,而且这些业务逻辑很大机会随着业务的发展而变化,因此,如何通过合理的设计来保证以一个清晰的结构来表达这种业务模型,并能够让模型有足够的灵活性来应付将来可能发生的业务变化显得非常的关键,在架构分析中,将会以“客户下订单(即创建订单)”作为用例进行分析。 业务数据的查询业务、报表业务:对业务数据的查询操作是贯穿整个系统所有模块的业务,而报表业务也是数据查询的一种特殊例子,它们都属于系统中非常典型的功能需求。 创建订单 典型的高并发资源争用业务:这种业务对 数据在处理过程中的排他性有非常严格的要求,即业务数据在某个事务处理过程中,绝对不能受到其他事务处理的干扰,“创建订单”用例就是这一关键功能需求的典型用例,在架构分析中将会对如何保证这种事务排他性进行详细分析。 数据权限控制:数据权限控制是系统的一个典型的功能,客户管理、销售管理、服务管理、财务管理和报表等模块中都有数据权限控制的需求,数据权限控制的意思是:不同角色可以拥有同一个系统功能的使用权限,但不同角色对于同一系统功能,其可操作的数据是有可能不同的,目前系统定义了三个数据权限级别: 1)全部:对应功能权 限能操作所有相关数据; 2)本人管辖的员工负责的数据:对应功能权限只能操作当前用户拥有的数据,以及当前用户所在部门(包括下级部门)的所有员工所拥有的数据; 3)本人负责的数据:对应功能权限只能操作当前用户拥有的数据。 需要整合第三方系统提供附加值,包括用“在线客服”为租户在线的、及时的支持服务;用“ SMS”为租户提供短信服务;用“ EMail” 为租户提供发送业务邮件和邮件提醒服务。 2.2 关键 非功能性需求 租户及用户数量:最大租户数为 500。每个租户最大的用户数 100,所有租户平均用户数50。平均在线人数约为: 12500 人。 并发数: 5% * 平均在线人数 = 625 次 每秒 性能:系统及时提供相应服务的能力。包括较高的吞吐量、快速的平均响应时间、持续高速的系统处理能力。大部分操作的响应时间控制在 3 秒以内。 安全性:系统为合法的租户及用户提供服务,阻止非授权租户及用户使用系统。如用户验证安全性,用户数据安全性等。 持续可用性:系统长时间无故障运行能力,一年内无故障率达到 99.9%(年累计停止服务 时间不超过 8 小时 45 分钟) 易用性:系统必须易于使用。系统在升级过程中,降低或避免老客户的适应难度。 可伸缩性:当用户数和 数据量增加时,系统维持高服务质量的能力。如当业务量增大时 (比如用户操作频繁或者增加了租户) ,可以通过增加服务器来提高性能,无需对系统进行编程级修改,也不会对最终用户的使用产生影响。 健壮性(容错性):系统发生以下情况仍然能够正常运行:用户进行了非法操作;部分软硬件系统发生了故障;其它非正常情况。 隔离性:减少租户与租户之间的相互影响,租户之间的数据必须良好隔离。 可扩展性:根据 SaaS 产品发展需要,系统要较容易的适应新需求或需求变化。 可移植性:根据租户数量或服务水平,可容易的从 一个运行环境转移到另一个不同 的运行环境。 (数据库的迁移需要暂时服务,其他的升级基本上 对用户 是透明的) 可维护性: SaaS 系统是由多角色人员一起来运营的。系统的安装、部署、扩展、升级、新租户的加入必须容易,减少出差错。系统运行的监控必须准确、及时。对故障的处理必须简单快速。 租户端带宽有限:一个租户通常有多个用户使用系统,而访问系统时通常是共享带宽,比如 ADSL(处于成本考虑,可能采用上行 512K,下行 2M)。 2.3 关键 商业需求 系统 1.0 版本的规划最大租户数是 500 系统必须在 2009 年 11 初月交付 该产品能方便 IDC 运营管理 系统支持多 租户,按租户合同,进行灵活的模块配置,不同租户可以购买不同的业务模块 2.4 关键 约束 使用 Apache 作 Web Http Server 使用 OSGi 作应用所在环境(容器选用 jetty 或者 tomcat,待测) 使用 MySQL5.1.3 作为数据库 2.5 名词解释 “租户”:指购买 SaaS 应用的客户,比如 某个开发商购买了 RES,那么这个开发商就是“租户”。 “租户管理员”: 由 SaaS 服务提供商的运营人员使用。 指 SaaS 服务提供商内部,负责管理“租户”的管理员,该管理员的职责一般是根据合同来添加租户,添加租户的“ 租户第一人 ”, 修改租 户信息,修改租户各种配置信息等。 该角色的工作,在运营中一般由“实施工程师”来完成。 “ 租户第一人 ”: 由租户自己使用。这个“ 租户第一人 ”是由“租户管理员”分配的,租户可以使用这个“ 租户第一人 ”给自己的系统添加用户。 “用户”和“账户”在本文的描述中都是只用户用来登陆系统的用户名。 3 参考资料 SaaS 模式系统参考架构设计 .doc 作者:陈操 MSYQL 数据库备份与恢复及 SaaS 下的备份策略 .doc作者:莫荣广 4 系统功能分析 4.1 SaaS 模式下功能分析 从系统使用者的角度,整个系统的功能模块划分如下: S A A S 房 地 产 营 销 管 理 系 统 1 . 0客 户 管 理客 户 跟 进 管 理客 户 信 息 管 理产 品 管 理开 发 商 及 项 目 资 料 管 理普 通 房 源 管 理服 务 管 理售 后 服 务 管 理系 统 设 置 管 理用 户 管 理( 组 织 架 构 、 员 工 、 用 户管 理 )日 志 管 理权 限 管 理系 统 参 数 管 理报 表 管 理房 源 统 计 报 表 客 户 统 计 报 表销 售 统 计 报 表 系 统 交 互 接 口B O S S 系 统 交 互 接 口短 信 接 口邮 件 接 口 财 务 管 理诚 意 金 管 理 订 单 款 项 管 理收 据 管 理 欠 款 管 理财 务 对 帐 银 行 帐 号 管 理销 售 管 理优 惠 管 理 定 价 管 理销 控 管 理 订 单 管 理活 动 管 理( 认 筹 活 动 、 开 盘 活 动 )销 售 工 具产 品 基 础 资 料 管 理租 户 信 息 管 理图表 5.1.1-1 SaaS RES 1.0功能模块划分图 系统 1.0 版本的产品只有普通房源,还不包括车位、花园、学籍等房地产附带产品的管理 销售管理模块和财务管理模块是系统的核心业务模块 系统支持多租户共同使用,但租户的管理、租期管理等不属于本系统的职责,由 BOSS 系统负责,系统与 BOSS 系统进行交互,获取 BOSS 系统提供的租户相关信息和租户启用、 停用通知等信息 4.2 业务 功能划分 4.3 子系统划分 下面站在系统构建者的角度出发,按业务处理、报表统计和基础支持三个类别把系统进行子系统划分: S A A S 房 地 产 营 销 管 理 系 统 1 . 0产品管理子系统前 台 业 务 系 统后 台 支 撑 系 统客户管理子系统销售管理子系统服务管理子系统财务管理子系统报表管理子系统参数设置子系统用户管理子系统权限管理子系统日志管理子系统租户信息管理子系统图表 5.1.1-1 SaaS RES 1.0子系统划分图 租户信息管理子系统主要包括 BOSS 系统发送过来的租户相关信息,如租期到期提醒信息,租户通知信息的管理 用户管理子系统包括了用户的身份认证,用户管理和员工、组织架构的管理 。 5 架构设计 SaaS 模式的架构设计和普通系统的架构设计有所不同, SaaS 除了要满足用户各种个性化要求以外,应用服务器和数据库服务器要满足成千上万的请求,因此,对系统可用性、伸缩性、扩展性以及性能提出了更高的要求。 本次参考架构设计的总体原则就是:分割和缓存 。 5.1 架构分析 下面主要综合之前的功能性和非功能性的要求,来对系统的整个架构进行分析。 5.1.1 业务实体的增、删、改及一些复杂的业务处理功能 分析: 对于 SaaS 房地产营销管理系统 1.0(后面统一简称为 SaaS RES 1.0)来说,对业务实体 的增、删、改、操作是最常见的基础功能,这些操作 都有一个共同的特征 改变系统中的业务实体的状态(或数据),因此,这里选择基础房间的增、删、改这一典型的功能需求进行分析,以阐述对于这类对业务实体状态产生改变的操作的设计决策。 决策: 系统使用最常见的层式架构进行设计,按逻辑被划分为:展示层、应用服务层、领域层和数据访问层,下图展示了系统各逻辑层之间的关系: 展 示 层 ( W e b 层 ) 应 用 服 务 层 领 域 层数 据 访 问 层( O R M )D O R e p o s i t o r yD OD OD OD OD OD OS e r v i c eS e r v i c eS e r v i c eA c t i o nA c t i o nA c t i o nD O R p s t I m p lD O R p s t I m p lD O R p s t I m p l图表 5.1.1-1 增、删、改操作设计决策图(充血模型) 展示层:负责为用户提供用户界面,接收用户的输入参数,提交给应用服务层执行相应业务操作,并接收应用服务层的返回结果展示给用户,其直接依赖于应用服务层。 应用服务层:向外提供业务功能服务,它只负责系统应用级别的逻辑如事务控制、权限控制、日志处理等,以及少量的跨领域对象的业务逻辑,它通过领域层的领域对象仓库获取相关的领域对象,然后调用领域对象的方法完成相应的业务,再把业务结果封装到数据传输对象( DTO)中返回给展示层,这里的 DTO 是作为展示层与应用服务层的数据载体,它负有装载请求数据和结果数据的职责。 领域层: 包含业务领域内的一系列相关领域对象及其仓库接口,领域对象封装其领域内的业务逻辑,领域对象通过其仓库获取和持久化。 数据访问层( ORM):提供领域对象的持久化实现,它的作用是把领域对象的具体持久化实现细节封装起来,并利用 ORM 工具把数据库中的数据转换为领域对象。该层只提供持久化实现,持久化操作的接口由领域层定义,因此,该层依赖于领域层提供相关领域对象的数据结构和持久化操作接口。 下面分别以系统中四个典型的功能用例来分别对业务实体的增、删、改以及涉及复杂业务规则的业务操作进行详细分析: 用例 1:创建个人客户信息 业务实体的创建操作 创建个人客户信息有如下的业务约束: 客户的姓名、性别、联系电话、客户类型、是否重点客户的标识这些属性都不能为空; 客户的姓名和联系电话组成了客户身份的唯一标识。 领域驱动设计,或者说面向对象设计的最重要规则是:把不同的职责合理的划分到不同的对象中,根据这一规则,我们对上述的业务约束进行分析: 客户属性是否必填,属于客户实体自身的业务完整性约束,因此,这部分职责应该交给客户实体本身负责; 客户的姓名和联系电话是客户身份的唯一标识,这意味着系统不能存在两个具有相同姓名和联系电话的客户,这 就需要在创建客户的时候进行检查,而这部分工作,对于客户实体来说,它并不了解其他客户实体的信息,因此,应该交由其上层,客户管理应用服务负责。 根据上面的分 析,我们已经可以清晰的划分职责,然后得出如下的创建个人客户的时序 图: 5.1.1-2 创建个人客户信息时序图 用例 2:修改个人客户信息 业务实体的修改操作 修改个人客户信息有如下业务约束: 修改个人客户信息用例包含了创建个人客户信息的所有业务约束; 当系统设置了需要 开启客户信息修改审核功能时,如果修改了个人客户信息中的核心信息,并且修改个人客户信息的系统用户不具有审核功能权限,则修改后的个人客户信息不能直接更新,而是要把修改信息提交审核,审核通过后,才能更新对应的个人客户信息。 根据上述的业务约束进行分析,系统是否开启客户信息修改审核功能,很明显不属于个人客户实体的职责,因此它应该由应用服务层负责,同时,由于客户管理应用服务的职责是对客户信息进行管理,而客户信息修改审核功能的设置是由系统参数设置模块负责,所以,这项职责应该由系统 参数设置应用服务提供,而判断是否修改了客 户核心信息,很明显属于个人客户的职责。最后,根据当前系统用户是否具有审核功能权限,这部分职责应该由客户管理应用服务负责,由于权限判断是由通用权限组件提供的功能权限判断器来提供,前者会把任务委托给后者。经过上述分析,得出下述的时序图: 5.1.1-3 修改领域对象时序图 用例 3:把个人客户信息放入回收站 业务实体的删除操作 把个人客户信息放入回收站有如下的业务约束: 参加过认筹登记的客户不能放入回收站; 交过钱(存在 财务付款记录)的客户不能放入回收站; 下过订单的客户不能放入回收站 正在提交审核(被修改或合并后未审核通过)的客户不能放入回收站。 分析业务约束,认筹登记、财务记录、订单都属于客户实体的从属信息,即客户实体与上述实体形成聚合关系,按照领域驱动设计的理念,客户实体是上述实体的聚合根,所以,判断客户是否有过认筹登记、财务记录和订单都应该是客户实体的职责,然而我们再进一步分析,实体的职责是相对的,在不同的业务上下文,业务实体所具有的业务职责是不同的,把个人客户信息放入回收站这一个用例,其业务上下文局限于客户管理, 因此,在这一范围内,客户实体并没有认筹登记、财务记录和订单等概念,客户实体是一个职责单一的实体,而上述概念分别来源于销售管理服务(包括认筹登记、订单)和财务管理服务(财务记录),对于客户管理应用服务来说,其业务上下文同样与销售管理服务、财务管理服务无关,所以,判断客户是否参加过认筹登记,是否有财务记录, 是否下过订单的职责既不应该由客户实体负责,也不应该由客户管理应用服务负责(由于销售和财务是客户的下游业务 销售和财务都是基于客户的,所以依赖关系是前两者依赖于后者,如果由客户管理应用服务负责,则客户管理应用 服务必须委托销售管理应用服务和财务管理应用服务提供判断结果,这就形成客户管理与销售管理、财务管理形成循环依赖关系,这违背了模块化设计原则)。进一步分析,上述判断逻辑都只是一种查询服务,并不会对任何业务实体产生状态影响,因此,可以通过在客户领域对象仓库中提供一个特殊的查询服务来获取。我们再分析最后一个业务约束,由于客户是否需要审核是由系统设置决定的,因此该判断逻辑同样不属于客户实体的职责范围,应该由客户管理应用服务委托系统参数设置服务完成,综上所述,得出如下时序图: 5.1.1-4把个人客户放入回收站时序图 注:该用例表达的是逻辑删除的场景,物理删除的场景与此基本一致,唯一的不同是需要在业务处理的最后通过实体对应的仓库从持久层中把对象删除。 用例 4:客户下订单(即创建订单) 典型的复杂业务处理功能 客户下订单有如下的业务约束(注:由于该用例业务功能非常复杂,而且在结构设计阶段,销售模块的需求分析还没完全完成,因此该用例的业务约束将忽略一些不是很重要的细节,该用例的最终模型和时序图以销售管理模块的详细设计为准): 下订单 时可以根据系统参数的设置同时修改客户信息; 只有状态为“可售”的且有定价的房间可以进行下订单; 当系统参数设置组合房间可以拆开销售时,组合房间和基础房间都可以下订单,否则,被组合的基础房间不可售; 根据系统参数设置判断是否可以使用历史价格; 如果有客户有进行认筹登记,需要对认筹登记进行解筹,并把认筹金额转换为定金; 需要根据各种优惠及款项信息计算订单的总折扣率和折后总房价; 分析业务约束,第一个业务约束很明显不属于订单实体及其他相关实体的职责,由销售管理应用服务委托系统参数设置应用服务进行判断,当可对客户信 息进行修改时,还需要委托客户管理应用服务提供修改服务;房间是否可售需要根据房间状态决定,这职责明显是由房间实体负责;已组合的基础房间是否可售,由系统参数设置决定,所以应该由销售管理应用服务委托系统参数设置应用服务进行判断,至于房间是否已经被组合,这是房间实体本身的职责;可否使用房间历史价格,由销售管理应用服务委托系统参数设置应用服务进行判断;对于解筹操作,订单实体包含认筹登记记录,因此应该由订单负责;订单的总折扣率和折后总房价是由订单的各种优惠及款项信息决定的,因此属于订单的职责,但进一步分析,总折扣率和折 后总房价可能由不同的计算方式,因此,应该设计一个订单总折扣率和折后总房价计算器实体,并由订单委托其进行计算,综上所述,得出如下时序图: 5.1.1-5 客户下订单时序图 这个时序图的设计并不是最终的客户下订单用例的时序图,它主要表达了一个复杂的业务,需要通过合理的抽象以及对业务变化的预见性,建立好合理的模型,并把职责合理的划分到不同的服务或领域对象中,从而得到更好的灵活性或扩展性,这也是领域驱动设计的核心思想。 5.1.2 对象 的查询业务、报表业务 分析: 对象的查询业务、报表业务同样也是系统的典型操作,与对象的增、删、改不同,对象的查询业务、报表业务的共同特征是: 1)这些操作不会改变业务实体的状态和数据; 2)这些操作返回的数据量可能比较大; 3)这些操作查询的结果很多时候是跨领域对象的数据视图; 4)这些操作通常比较频繁; 5)这些操作不需要调用领域对象的具有业务意义的方法。 基于这些特征,如果使用“充血模型”设计方法,就会出现一系列问题,下面以基础房间的查询作为例子来说明问题: 基础房间查询只需要返回一个符合查询条件的基础房间视图列表 ,它包括的数据除了基础房间的基本信息外,还包括基础房间的楼栋名、分期名、楼盘名、朝向、景观、开发商名等关联信息,如果直接获取领域对象再转换成数据传输对象,由于领域对象仓库实现使用了 ORM 框架,返回的都是对象,那么,每个房间领域对象必须要返回其相关联的所有对象: c l a s s 公共部分基础房间楼栋分期楼盘开发商景观 朝向图表 5.1.2-1 基础房间关联对象类图 而事实上,对于该查询业务来说,它只需要这些关联对象中的某一个或几个属性(如:分期对象的分期名称),可以看到,使用加 载领域对象的方式有下面的问题: 加载了大量不必要的数据,严重浪费磁盘 IO 资源,可能会导致磁盘 IO 瓶颈; 创建大量的关联对象,并且需要进行对象关系转换,浪费 CPU 资源; 大量对象会导致内存开销大增,在高并发时可能会导致内存溢出; 加载的对象是领域对象,但查询业务并不需要调用领域对象的任何业务方法; 应用服务层需要把领域对象转化为 DTO 返回,这同时浪费 CPU 和内存资源。 这一系列的问题说明,对象查询业务、报表业务并不适合使用“充血模型”进行设计。 决策: 由于对象的查询业务、报表业务没有对业务实体的状态产生影响, 因此严格来说,它们并不属于“业务”,我们可以以一种“查询通道”的方式来实现,查询通道的意思是:不加载领域对象,也不使用 ORM,而是直接使用结构化查询语言 SQL(对于不同的持久化实现机制,有不同的结构化查询语言,如 XML 的 XQuery、 XQL 等),通过组合查询直接返回数据视图所需要的数据,并组装成一个 DTO 返回 ( 注:这只是其中一种实现方案,还有一种比较可行的实现方案是:为需要查询的数据在数据库建立数据视图,然后通过 ORM 工具把视图映射为一个 DTO,这种方式就不需要直接编写 SQL 语句,但返回的对象并不是 DO,而 是没有任何业务含义的 DTO) ,下图展示了查询通过的逻辑层关系图: 展 示 层 ( W e b 层 ) 应 用 服 务 层 数 据 访 问 层( 查 询 通 道 )S e r v i c eS e r v i c eS e r v i c eA c t i o nA c t i o nA c t i o nQ u e r y S e r v i c eD T OD T OD T O图表 5.1.2-2 查询业务、报表业务设计决策图(查询通道、贫血模型) 与“充血模型”不同,应用服务层绕过了领域层,直接通过查询通道查询数据,并把查询结果直接以 DTO 的形式返回,下面是使用查询通道查询数据的时序图: 5.1.2-3 查询通道时序图 这种方式,免去了加载无用数据、对象关系映射、领域对象与 DTO 的转换逻辑,从而大大的减轻了磁盘 IO、 CPU 开销和内存开销。 注:上图只是为了表达清晰,省略了领域层,实际上,“查询通道”只是一个概念,在实际设计中,会把查询方法都封装在领域对象仓库接口中,实现放在领域对象仓库实现中,所以,应用服务层还是通过调用领域层的领域对象仓库查询接口完成查询业务的。 补充说明: DTO 即数据传输对象,它只包含数据,没有任何行为,同时, DTO 把 DO 的对象关联关系辗平,成为一个独立的数据视图 对象,以房间 DTO 为例,它不会关联到楼层、分期等 DTO,而是把楼层名、分期名作为房间 DTO 的一个属性,这种设计方式通常称为“贫血模式”,也相当于 Martin Fowler 在企业应用架构模式一书中所说的“事务脚本( Transaction Script)”模式。 另外,对于一些变化频率很低或者不会发生变化的数据,如很多页面的下拉菜单数据等,为了减轻数据库服务的 IO 压力,还需要采取缓存策略。 5.1.3 创建订单 典型的高并发资源争用业务 分析: 创建订单是整个系统一个非常重要的业务功能,它在一些特定的时间,如五一、十一 等开发商促销的时间并发性比较高,由于同一个房间 在同一时间 只能下一张订单,这里就涉及一个在下订高峰期房间争订的情况,系统要保证不要出现同一房间被不同两个客户下订的情况。根据创建订单的业务规则,订单只能预订状态为“可售”的房间,当下订成功后,房间状态被改变为“已售”,要保证不出现上述争订的情况,事实上就是要保证在整个订单创建过程房间状态数据变化的排它 性。 决策: 由于系统使用 Hibernate 作为持久化框架,我们可以利用 Hibernate 提供的为数据库相关数据上“锁”的功能来保证数据变化的排它性。 Hibernate 提供了两种数据锁定机制:悲观锁和乐观锁。悲观锁对数据的处理采取一种保守的策略,即在整个数据处理过程(完整的事务)中,对目标数据上锁,以保证事务以外的其他操作都无法在此事务提交前对目标数据进行修改,悲观锁的实现通常依赖于数据库提供的锁机制。乐观锁采取比悲观锁相对宽松的策略,它的原理是,为数据增加一个用于记录“版本”的字段,当事务读取数据时,会把数据的版本号也一并读取,当事务修改了数据后, Hibernate 会自动把该数据的版本号加 1,然后在提交事务前,把该版本号与数据库中的对应数据的版本号进行对比,如果该版本 号高于数据库记录的版本号,证明在事务过程中没有其他事务修改并提交过对应数据,事务被提交;如果该版本号不高于数据库记录的版本号,则说明事务过程中已经有其他事务修改了该数据并提交,事务提交被拒绝。 对比两种策略,我们发现,两种策略达到的效果是一致的,但悲观锁更加严谨,保证先开启的事务对数据有主动权,但同时,它却带来了数据库性能的大量开销,因为在整个事务过程中,所有其他事务都无法修改被锁定的数据,尤其对于长事务,这种开销更加明显。乐观锁不能保证先开启的事务对数据占有主动权,实际上是先提交的事务才会被成功提交,但乐 观锁基本不会浪费数据库的性能开销,而且不依赖于数据库的锁机制实现。创建订单是一种高并发的操作,每个房间在整个下订过程只被一个客户占有,这显然是客户不能接受的,而事务孰先孰后,对于客户来讲却是透明的,很明显,我们应该采用 Hibernate 的乐观锁策略来避免房间争订的情况。 创建订单只不过是整个系统的其中一个典型的功能点,对于其他类似的功能,如财务收退款这些敏感操作,我们都需要采用相同的策略对数据进行锁定处理。 5.1.4 数据权限控制 SaaS RES 1.0 在客户管理、销售管理、服务管理、财务管理和报表等模块中都有数据 权限控制的需求,数据权限控制的意思是:不同角色可以拥有同一个系统功能的使用权限,但不同角色对于同一系统功能,其操作的数据是有可能不同的。目前系统定义了三个级别的数据权限: 全部:对应功能权限能操作所有相关数据; 本人管辖的员工负责的数据:对应功能权限只能操作当前用户拥有的数据,以及当前用户所在部门(包括下级部门)的所有员工所拥有的数据; 本人负责的数据:对应功能权限只能操作当前用户拥有的数据。 分析: SaaS RES 1.0 对于功能权限和数据权限都有需求,对于功能权限控制,系统采用公司开发的通用权限组件 2.0 实现, 同时,由于系统的数据权限是根据组织架构进行划分的,数据权限控 制的组织架构还会采用公司开发的通用组织架构组件实现 , 通用权限组件 2.0 以一种事件拦截的机制来实现基于 RBAC 的功能权限控制,其原理如下图: 图表 5.1.4-1 通用权限组件 2.0原理图 当用户试图访问系统的功能服务时,功能权限拦截器会首先把用户的请求拦截下来,然后把用户信息和请求信息发送给功能权限控制器,功能权限控制器会根据用户信息从权限数据库中获 取该用户的授权信息,即角色集合,然后再获取这些角色的功能权限集合,最后判断出该用户是否拥有其请求的功能服务的访问权,如果有,则请求被传递给相应功能服务,如果没有,请求被拒绝,并重定向到拒绝访问的错误页面。 使用权限组件这种拦截机制的好处是:把基于角色的访问控制逻辑彻底的从业务逻辑中分离,业务开发人员只需要关注业务,无需编写任何权限判断的逻辑,这大大减轻了业务开发人员的工作量,也提高了系统的灵活性。 如果说基于角色的访问控制权限与业务无关,那么数据权限却与业务有比较紧密的联系,比如:销售团队 A 的普通销售员只能 跟踪自己的客户,但其团队主管却可以跟踪团队内所有成员的客户。这些可以看作是系统业务的一部分,但对于 SaaS RES 1.0 来说,这种数据级别的权限控制是相对稳定和单一的,如上所述,它只有三个级别的数据权限。对于数据权限控制,权限组件 2.0 只提供了扩展的机制,并没有提供具体的实现。 决策: 根据上面的分析,我们可以有两种方式实现数据权限控制: 直接在业务代码中编写数据权限控制的逻辑,把它视作业务逻辑的一部分; 通过权限组件 2.0 提供的框架进行扩展。 上面提到, SaaS RES 1.0 的数据权限控制是相对稳定和单 一的,这就意味着,数据权限控制的逻辑有很高的重用可能性,如果采取第一种方式,业务开发人员就不得不关注数据权限控制逻辑了,而且把数据权限控制逻辑交由业务开发人员实现,代码就很容易失控。权限组件 2.0 虽然没有提供数据权限控制的实现,但它却提供了一个良好的框架,让业务系统可以在框架的基础上进行扩展,实现数据权限控制。可以看到,两种方案都需要编写等量的数据权限控制代码,但后者可以让系统的结构更加清晰、合理和容易维护,因此,后者是一种更合适的选择。其原理如下图: 图表 5.1.4-2 权限组件 2.0中数据权限扩展原理 图 用户的请求还是先要进行 RBAC 的功能权限判断(见上述说明),当通过了功能权限判断后,用户请求会进一步被传递给访问前权限处理器,这里的“访问前权限处理器”就是权限组件的框架提供的一个扩展点, SaaS RES 1.0 需要实现此处理器,它的作用是进行数据权限处理,判断当前用户对目标数据是否有操作权,如果没有,则直接拒绝访问,如果有,则可以对用户的请求进行加工,最常见的做法是,为请求添加上数据筛选过滤条件,如:用户发起了 一个获取客户列表的功能请求,该用户是销售团队 A 的普通销售员,访问前权限处理器发现普通销售员这个角色的数据权限级别是“本人负责的数据”,则对该请求进行加工,为其添加上“数据拥有者标识”作为筛选条件,然后再把请求发送给业务系统的对应功能服务。当服务处理完后,返回结果又会被进一步传递给访问 后权限处理器,“访问后权限处理器”同样是权限组件框架提高的扩展点,可以通过实现此处理器,对返回的结果进行加工,比如屏蔽某些敏感数据等。 通过这样的设计,利用权限组件框架提供的扩展点,既能很好的实现系统对于数据权限控制的要求,也让 数据权限控制的逻辑和功能权限控制逻辑一样,从业务系统的业务逻辑中抽离,使系统的结构更加合理和灵活。 5.1.5 支持多租户的数据结构 由于目前已经确定使用 MySQL 作为数据库的约束,要支持多租户,我们有以下三种方式可以选择: 1. 每个租户都有独立的数据库 2. 租户共享同一个数据库,但独立数据结构(即一个租户对应一个 schema) 3. 租户共享同一个数据库,且共享相同的数据结构。(即一个 schema 被多个租户共享) 对于以上三种方式的比较,可以从下表看出: 方式 隔离性 安全性 成本 独立数据库 高 高 高 一 个租户一个 schema 中 中 中 多个租户共享 schema 低 低 低 图表 5.1.5-1 三种支持多租户数据结构方式比较图 第一种方式,似乎和传统的软件没什么区别,只适合高端用户和隔离性要求很强的用户,比如医院、银行等等,对于普通的租户情况不适用,因为成本太高。 第三种方式,隔离性差,且难以迁移、备份和恢复数据。 因此,我们目前选用第二种方式,即一个租户一个 schema 的方式作为目前支持多租户的数据结构。 5.1.6 基于 单域名的租户访问方式 由于用户访问方式是单域名的,比如 /res,根据这样的请求,在这个用户没有登陆之前,我们是没有办法知道正在请求的用户是属于哪个租户的。只有在他通过认证之后,我们才可以知道当前登陆用户的信息。这就决定了需要在统一的地方进行认证并登陆,从而组装相应的 url 定向到这个用户所属租户的访问路径中去。这就是“集中式认证”的概念。由于我们这一期,不会对租户提供界面个性化的功能,因此 ,用户登陆后的界面风格是一致的。 举个例子来说,登陆流程是 这样的 : 1. 用户 usera 想进入系统,由于未登录,会被应用引导至登陆页面进行登陆,比如 /res/login 2. 用户 usera 提交用户名和密码 3. 系统验证账户的有效性,如果账户有效,那么系统会查找出 usera 是属于租户 A 的,接下来构建租户 A 的有效路径返回给 usera,类似 /res (注:在存在租户个性化页面定制和按租户分区访问情况下, url 需要包含租户标识,如 /res/tenant-a,参见“ 蓝色透明部分 ”和 SaaS 模式系统参考架构设计 .doc中的“ 租户界面可定制(个性化) ” ) 4. 用户 usera 进入正确的访问地址了,如 /res 同样的,如果 userb 属于租户 B,想要登陆系统,同上面的步骤相同。 考虑到可能要同多个系统做整合,因此,我们需要在多个系统之间做到单点登陆。 Web 环境下的单点登陆,业内已经有了很多解决方案,比如著名的 CAS 和 OpenID 等等。在这里,我们使用公司的单点登陆组件(基于 CAS)。 就目前而言, 单点登陆的账号和密码等信息是存放在数据库中的( MySQL)。在将 来,也可能会将这些数据移植到 LDAP 中去。 用户账号规则 按照目前的规划,用户账号的命名规则由租户自己决定。举个例子来说:租户 A 新增了 usera,userb 这两个账户,那么租户 B 就不可以新增同名账户了。 5.1.7 租户带宽上的限制 SaaS 模式下,应用都是基于互联网的,因此最终用户也是通过互联网来使用 SaaS 应用的。而目前的信息化程度,对于大多数最终用户来说,都是在共享带宽的环境下使用互联网,比如 ADSL(上行 512K,下行 2M)。这就可能会出现多个用户在共享的带宽下同时访问我们的 SaaS 应用的情形,要使得这些用户获 得良好的响应速度和体验,就要求我们的 SaaS 应用不应该占用过多的带宽资源。因此,这对我们的设计提出了更高要求,要尽量的减少网络带宽的占用,减少不必要的网络传输,提升 web 的性能等等。下面列举影响 Web 性能的主要因素: 影响 web 性能的因素 1. 页面过大:页面在 500k 以上 2. 图片和 iframe 过多:会导致增加请求数 3. Cookie 内容过大:会导致发起请求变慢 三十四条黄金守则 著名的雅虎为我们提供了网站性能上的三十四条守则,这些守则可以约束我们的设计,总结列举如下: .1 内容类 减少 http 请求 减少 DNS 查找 避免跳 转 缓存 ajax 延迟加载 提前加载 减少 DOM 元素数量 用域名划分页面内容 减少 frame 避免 404 错误 .2 服务器与 Cookie 类 使用 CDN 为文件头制定 Expires 或 Cache-Control GZip 压缩网页 配置实体标签 尽早刷新输出缓冲 使用 Get 完成 ajax 请求 减小 Cookie 体积 对于页面内容使用无 Cookie 域名 .3 JavaScript、 CSS、图片类 把脚本至于页面底部 使用外部 JavaScript 和 CSS 消减 JavaScript 和 CSS 提出重复脚本 减少 DOM 访问 开发智能事件处 理程序 把样式置于顶部 避免使用 CSS 表达式( Expression) 使用外部 JavaScript 和 CSS 用 代替 import 避免使用滤镜 优化图像 优化 CSS Sprites 不要在 HTML 中缩放图像 favicon.ico 要小且可缓存 .4 移动应用类 保持单个内容小于 25KB 打包组件成复合文本 业务处理上 在业务处理上, 对需要展现的信息进行分析, 尽量展现比较少的数据,比如在一般的分页查询之中,每页展现 10 条数据。 5.1.8 租户存储数据分离和受限动态路由 在之前的架构分析上,我们选择了“每个租户对应 一个 schema”的策略。而对于 MySQL 来说,一个 MySQL 实例中大约只能存放 1000 个 schema,如果 再多的话,可能会对数据库的启动和性能产生影响。因此,这个限制使得 一个 MySQL 数据库实例只可为近 1000 的租户提供服务,如果租户超过 1000 那就需要另外准备一个 MySQL 实例了。而我们的应用程序都是相同的,这就 要求 我们的程序必须能感知到这一点,然后把租户 SQL 正确的发送给正确的 MySQL 实例上。为了做到这一点,我们需要一个能够根据租户标识动态路由数据源的功能,同时也要做到同目前使用的主流框架结合 , 并且 对程序员透明。 之所以说是“受限”动态路由,是因为在将来随着租户数量的不断扩大,我们可能需要多个MySQL 实例来提供服务。比如当租户只有 1000 以内的时候,一个 MySQL 实例差不多可以满足了;当数量为 1.3k 的时候,可能就需要两个 MySQL 实例;如果再更多的,那么可能会需要 N 个 MySQL实例。面对这么多 MySQL 实例,如果动态路由不受限制的话,那么在理论上就会出现一个应用服 务器上维持着 N 个数据源的连接池,这是相当消耗系统资源的!所谓“受限”,也就是指一个应用一般只维护 24 个 MySQL 实例的数据源(当然也可 能 35,这个数字需要从测试中得出,并在实际中是可以调整的)。 由于我们第一期的目标是满足 500 个租户即可,这样看来,一个 MySQL 实例基本上是可以满足要求了。因此,在这种情况下,就不需要“受限”动态路由了。 另外, 在 SaaS 模式系统参考架构设计 .doc中论述了“完全动态路由”的概念,感兴趣的可以去该文档中查阅。 5.1.9 租户敏感数据加密 一般租户很难接受主机尤其是数据托管在第三方。特別是涉及到商业机密,如财务机密、客户资料、真实价格等。因此,租户敏感数据的加密是非常重要的!这些敏感数据是只允许租户内部的用户存 取的,不能被其他租户和商业竞争对手获取,甚至连对 SaaS 服务提供商都需要保密!因此,我们需要制定合适的安全策略来满足这个要求。 从上面可以看出,这里所谓的“敏感数据加密”实际上就是指数据内容本身的安全加密,这些数据是要被加密后存储在 SaaS 服务提供商的数据库中的。 ( 就目前的需求来看,并没有敏感数据加密的要求,因此,我们目前仅仅只是对用户的密码进行 MD5 加密。 ) 下面就敏感数据加密进行论述: 数据密文 首先这里就要涉及到加密算法,由于对于租户来说,敏感数据是要能够还原成明文的,因此可采用“可逆加密”算法来处理 。“可逆加密”又分为“对称加密”和“非对称加密”,虽然两者都可逆,但是他们在加密和解密过程中的计算强度是不一样的。“非对称加密”会比“对称加密”的计算时间要长,有近 23 个数量级的差别,因此,出于性能上的考虑,我们使用“对称加密”这种方式。 既然是“对称加密”,那么每个租户都应该有一个对应的“数据密文”。这个“数据密文”是“租户管理员”在添加租户的时候随机或者根据某种不重复的算法由系统自动生成的,每个租户的“数据密文”都不同,相同租户下的所有用户都是用同一个“数据密文”(不能因为用户 a 保存数据时对数据进行了 加密,而导致用户 b 不能使用该数据)。也就是说,有了某个租户的“数据密文”,就可以对该租户的敏感数据进行操作了。这也是件比较危险的事,万一“数据密文”泄露了怎么办?因此同样需要对这个“数据密文”进行加密操作保护起来。 针对“数据密文”的加密,我们采用用户登陆密码来加密。 .1 使用用户登陆密码来加密“数据密文” 我们可以用每个用户的登陆密码来对这个“数据密文”进行对称加密并保存起来。由于用户的密码一般都是不可逆加密的,比如 MD5 算法,因此认为是可以信赖的,真正的用户密码是存储在用户记忆中的。对于这种情形,我们整理下 流程:首先,“租户管理员”在新建租户的时候就由系统生成了该租户的“数据密文”, 假设 我们新建了租户 A 的“ 租户第一人 ”,那么“数据密文”是同这个“ 租户第一人 ”的数据一起存储的(经过了“ 租户第一人 ”密码的对称加密)。由于“数据密文”是租户下每个用户都会用到的,所以当“ 租户第一人 ”再添加“用户”的时候,这个“数据密文”需要传递给其他用户并保存起来(同样经过用户密码的对称加密)。这样就做到对租户下的所有用户公用“数据密文”了。这所有的一切都是对最终用户透明的。 “数据密文”对于租户、用户来说是透明的,是租户下所有用户 共有的,因此没有修改的必要,但是用户的密码是可以修改的。因此,在修改密码的时候,我们要用新的密码加密“数据密文”。由于用户修改密码的行为并不多见,因此这里基本上不会有多大的问题。 5.1.10 可配置性 产品模块可配置 针对产品模块的可配置性,在这里主要有两个方面: 第一个就是 SaaS 服务提供商的“租户管理员”对租户进行产品模块配置(这个操作实际上就是商务人员或者运营人员根据合同,来对租户在系统中的可使用范围进行分配)。这个过程主要在BOSS 上完成。 第二个就是租户在经过“租户管理员”分配模块后,在实际使用系统的过程中, 对其自身的用户进行产品模块功能权限“再分配”的过程。这个过程可以在统一的独立平台上完成,也可以在业务系统中,比如 RES 中完成。为了简单起见,在这里我们把这个“再分配”的过程放在业务系统中去。 这里有个集合关系: RES 系统全部的 产品模块 集合 租户拥有 产品模块 租户下用户拥有的产品模块 。 如上所述,租户下权限的“再分配”是放在业务系统中的,那么就意味着,当“租户管理员”根据合同或者协议,调整了租户可使用的产品模块的时候,这个改变需要被 RES 系统感知,从而使这个改变生效。这里就涉及到 BOSS 运营系统和 RES 业务系统之间消息的交互。关于这点,在下一节中论述。 5.1.11 BOSS 运营系统与 RES 业务系统的消息交互 由上面的分析, 针对 BOSS 运营系统与 RES 业务系统的消息交互,可由 下图 来表示 : 内 部 支 撑 系 统E n t e r p r i s e S e r v i c e B u s ( 主 要 适 于 系 统 间 整 合 )业 务 系 统R E S B O S SR E S集 中认 证中 心图表 5.1.11-1 BOSS运营系统与 RES业务系统总体 关系 图 我们把 BOSS 运营系统与 RES 业务系统之间交互的消息分为三种类型: 租户、用户的账户信息交互 此类信息,首先表现为在 BOSS 系统中创建

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论