架构师日常(一)

架构师日常(一)

四月伊始,进入新项目担任架构师角色,帮助项目整理和解决架构方面的问题。在三月技术,完成了前一个项目的工作并进行了交接,基本把手里需要项目注意的事项都写成了Markdown文档,记录在了Azure DevOps Wiki中,分门别类供团队成员查阅搜索。这里必须提到团队的知识管理,有一个可以及时更新并且能进行搜索的Wiki是很重要的,架构上的很多内容如果无法通过架构文档更新就应该提现到团队的Wiki中,已供涉众(包括客户方团队和运维团队,不仅限于开发团队)参考,并且可供后期架构文档更新提供素材。

新的项目领域为供应链管理(SCM, Supply Chain Management)或供应商管理(SM, Supplier Management),大致浏览一下网上关于供应链管理所需要的能力,包括:

  • 平台能力:包括分析、继承、个性化等;
  • 供应商管理运维模型:包括供应商绩效管理、供应商关系管理、供应商风险和合规性、供应商激励等;
  • 供应商生命周期管理(工作流):包括供应商开发、供应商监控和智能化、风险管理、供应商注册、战略溯源、供应商分类、供应商登记、供应商协作、冲突解决、供应商度量等;
  • 供应商信息管理:包括纲要、元数据、权限、集成、表单和规则、外部内容、自服务、分析等;
    内容还挺多,为了快速成为供应商领域的架构师看来得动用万能的某宝或某东了,在网上迅速选了两本最新跟供应链管理相关的书籍,当然内容也要跟架构和时下流行的数字化搭上关系,所以选择了《供应链架构师——从战略到运营》《数字化供应链》这两本,迅速下单估计周内就能到手,对于刚进入项目至少需要2周搞清状况的架构师,1周时间阅读行业相关内容是绰绰有余了。

行业内容大致有了把握,接下来就是对现有系统的分析。包括从组织架构、系统集成和系统涉众三个方面:

  • 组织结构指的是开发、运维这边的组织结构,可以查阅应用在内网的相关信息,通过聊天获取团队组成结构的情报。这个项目是一个敏捷项目,项目集采用SAFe框架进行管理,每个独立子项有相应的Scrum Master(团队敏捷教练)、Product Owner/Business Analyst(产品拥有者/业务分析师,一般对接客户团队,帮助澄清需求)、Technology Architect(技术架构师,设计和实现技术架构),为了实现产品化开发还有Product Manager(产品经理,控制产品化开发流程),在整个项目集上还有Portfolio/Program Manager(项目集经理,统管项目集),在组织级别或称Delivery Lead,还因为运行SAFe,有RTE(Release Train Engineer,发布训练工程师?因为对SAFe了解不深,这个称呼第一次听说,不过项目里这个人我倒是很熟悉)。熟悉各个角色的人之后方便我们沟通,具体问题找合适的人,比如业务问题找BA或测试人员,技术问题找架构师或Tech Lead,项目资源问题找SM或PM等等。
  • 系统集成方面,要了解上下游系统之间的关系,调用关系、数据流等,也要了解各系统所属项目集以及管辖团队,方便需要了解相关背景的时候能够问到合适的人。对于所有集成点,要了解使用的协议(HTTP/HTTPS)、方法(GET/POST)、架构样式(API/Event Driven)等等,如果调用了单点登录或者OAuth,要拿到相关的Credential方便我们去调用、测试;如果是Web应用,就应该让团队给我们加权限,以便我们能够访问系统了解系统的用途。
  • 系统涉众,要清楚系统的客户是谁,我们在为谁工作,为谁创造价值;还要知道用户是谁,他们是如何使用系统,与系统进行交互的。
    以上三点是整个2周我们要弄清楚的东西,但不能着急,首先要从项目相关的信息入手,了解项目的背景、目的,要实现大致业务功能,了解系统在流程中的位置,都有哪些用户,用系统主要要解决什么问题等。

中间抽空还是找项目的技术架构师和SM聊聊,多少先去了解项目有哪些问题,毕竟空降架构师一般都是为了解决项目中比较棘手的问题,根据四象限原则要么是重要的,要么是紧急的。那么我们先了解一下亟待解决的问题吧。原来上个月该项目已经参加了公司的架构评审组的评审会,架构评审委员会给出了以下的建议:

  • 要清楚的数据模型,方便了解系统;
  • 要清楚集成点;
  • 现在NoSQL数据库的使用方式比较奇怪,建议部分数据使用关系型数据库;
  • 多语言组件需要开源组件审核团队的批准;
  • 代码模板应该使用公司通用的代码模板;
  • 认证审核方面应该增加与公司级访问控制平台的集成;
  • 微服务方面没有实现每个服务使用独立的数据库;
  • 部分容器化服务是否可以考虑使用无服务(函数即服务)的架构风格;
  • 报表系统应该使用公司的数据湖和统一的报表系统;
  • 集成的几个子系统之间应该使用统一的通用ID来标识数据,这样可以保证数据的唯一性;
  • 对于计算服务是否能采用低碳区域云服务以达到节能减排可持续发展的目的?

那我们就一个一个问题来拆解:

  • 问题1:要清楚的数据模型,方便了解系统。
    这个问题我们需要创建三个文档来解决架构评审委员会的疑问,为了能把数据模型解释得清楚明白,我们就需要最基本的三个关于数据的文档,Conceptual Data Model概念数据模型、Logical Data Model逻辑数据模型和Physical Data Model物理数据模型。
    其中,概念数据模型只标识到实体或者值对象级别,线框图的框中基本都是数据实体或值对象的对象名称,没有细化到它的属性或字段。为的是突出系统需要哪些数据实体参与,实体之间是怎样的关系,是1对多还是多对1或者多对多,当然也有1对1的情况,还有0或者1对1或对多的情况。
    而概念模型就要细化一些实体的属性,让我们能了解如何收集、管理和使用这些数据。最后就是物理模型,是能直接表现出在关系型数据库或者非关系型数据库例如NoSQL数据库中如何定义和存储这些数据。

  • 问题2:搞清集成点。
    最简单的方法就是画架构图,要清晰、要将上下文都呈现出来。有哪些上下游系统如何交互,有哪些系统用户,有哪些数据流转,主要使用哪些服务或者组件,都要清晰,这样在讨论的时候才能搞清楚问题。这部分跟我们上面提到的分析系统要分析系统的客户、用户和涉众以及上下游系统是没什么分别的。这可能也是今天要跟团队做的主要部分。

  • 问题3:现在NoSQL数据库的使用方式比较奇怪,建议部分数据使用关系型数据库;
    因为前期开发系统的目标主要为创建一个调查问卷系统用于评估供应商,但久而久之随着需求的扩大,就需要管理许多关系型数据,如层级结构的数据、需要联合查询的数据,这部分数据是不太适合NoSQL数据库的。因为你从NoSQL数据库进行联合查询的性能极低,要么是先取出主表数据,然后根据主表数据分别查找子表数据,而且很多需要关联查询的地方要很多复合的条件,如果要在NoSQL数据库实现,就需要创建很多的索引,会降低NoSQL的数据访问性能。这部分可以考虑将关系型数据库迁出NoSQL数据库,使用内存型缓存数据库和关系型数据库的方式进行缓存和存储,提高访问性能。

  • 问题4:多语言组件需要开源组件审核团队的批准;
    这个比较好解决,注意许可问题,然后找开源组件审核团队批准就可以了。

  • 问题5:代码模板应该使用公司通用的代码模板;
    这种属于合规性问题,基本只需要照着做就可以了,当然我们也会考虑公司代码模板可能有部分无法实现和满足需求,这里我们可以做一个融合。如果是基础类,那么我们可以继承公司模板的基础类然后用我们自己定义的基础类再封装一层让业务逻辑或者实体进行继承,如果是辅助类或者工具类方法则可以直接进行使用或者调用,当然如果能使用公司模板中的方法尽量不要二次造轮子自己开发。

  • 问题6:认证审核方面应该增加与公司级访问控制平台的集成;
    这是认证、审核管理的问题。公司统一的访问控制平台提供了集中式管理的能力,这点我们还是要使用公司级的平台和系统,因为它们的集中式管理运维可以帮助我们节省日后的更新或者配置出现的问题和麻烦。

  • 问题7:微服务方面没有实现每个服务使用独立的数据库;
    微服务有很多模式,不同的模式解决的问题也不尽相同,不过对于微服务我们更多的考虑隔离性,通过不同的边界上下文、不同领域(不同的业务能力或者业务领域)进行划分,从物理和逻辑两个层面解耦,这是微服务的核心诉求,所以要考虑尽可能的符合基本的模式,如Database per Service或者Saga。

  • 问题8:部分容器化服务是否可以考虑使用无服务(函数即服务)的架构风格;
    虽然这已经是最大的变化了,从容器到无服务计算,基本就是Re-Arch而不仅仅是Re-Platform或者Re-Factor。虽然成本大,付出高,但是这样做的未来收益很多,因为不必再考虑可扩展性和可用性的技术性需求,因为函数即服务都可以满足。当然,无服务计算不是银弹,如果有诸如需要大量内存或者本地存储,高性能计算,长时间后台运算或者组件需要操作系统接口进行安装等要求的时候就无法使用无服务计算,所以可以先对现有服务进行评估再行决定。

  • 问题9:报表系统应该使用公司的数据湖和统一的报表系统;
    赞成,但需要看报表需求究竟真的只是报表功能,还是只是数据的“导出”功能,另外与数据湖集成我们也要考虑数据延迟,我们的报表需求是否有即时或者接近实时(Near Real Time)输出的需求等等。

  • 问题10:集成的几个子系统之间应该使用统一的通用ID来标识数据,这样可以保证数据的唯一性;
    赞成,业务方面我们最好在相近功能的子系统间维护统一的数据标识,同样的,对于一次会话或者连续调用的多个API之间或者微服务之间我们也应该使用类似的CorrelationID来关联所有的操作日志,以保证我们的数据也好日志也罢在大批量数据查看的过程中能体现出连续性和一致性。

  • 问题11:对于计算服务是否能采用低碳区域云服务以达到节能减排可持续发展的目的?
    这个是为了实现碳中和、可持续发展的目标,我们还是要支持的。

解决了架构的基本问题,我就开始看代码,因为项目的Azure DevOps的代码仓库中一共有29个代码仓库(Code Repository),我就从头到尾看了一遍,发现有几种情况:

  • 项目采用JavaScript或TypeScript或Java或Python,实现自动化测试为目的的代码仓库;
  • 项目使用JavaScript或Python,实现区块链核心的代码仓库;
  • 项目使用TypeScript,实现页面前后台的代码仓库;
  • 实现Terraform,以代码实现基础设施配置的代码仓库;
  • 实验性项目的代码仓库;
  • 空的无用的代码仓库;

对于后两种代码仓库可以删除或者另行保存,防止对开发人员的干扰,另外需要按区块链核心、业务前后台合、测试、基础设施配置等并为同一代码仓库,采用同MonoRepo的理念,设计一个代码的组成结构,这样能保证开发人员得到的所有代码都是一致的,而且可以和当前开发的Sprint(敏捷中的阶段,也叫冲刺)对应。

因为是既有项目,很多业务都是测试人员更新测试Case或者重新编写业务说明文档,有时候有文档更新不及时的情况。这里比较推荐使用BDD(Behavior Driven Design,行为驱动设计),它使用Gherkin语法(Given, When, Then)描述输入和期待的输出行为,可以作为业务说明文档使用,而且也有相结合的活文档工具,通过BDD测试结果标识哪些场景已经通过测试并可以被使用。这部分还属于项目要试验的部分。

另外因为主要业务逻辑还有前台都是使用TypeScript或者JavaScript实现的,正好跟我前端时间研究的TypeScript生态有交集。可以使用nvm(Node版本管理器)、yarn(比npm更快的包管理器)、ESLint(代码静态检查工具)、Prettier(代码格式化工具)、Husky(Git提交钩子程序)以及Cucumber.js(BDD测试工具)等加速开发,减少提交后的代码检查(Code Review)工作,把静态代码检查测试能工作都留到提交前完成。

另外两个系统之间的数据同步集成可以考虑使用最新的Data Fabric的技术实现。

页面下部广告