写点什么

架构的技巧

作者:agnostic
  • 2024-02-15
    上海
  • 本文字数:3707 字

    阅读完需:约 12 分钟

软件架构师是非常具有挑战的工作,最大的挑战就是面临大量的选择和决策。要很好的完成这些决策,需要丰富的经验和大量的知识储备。这些对于新的架构师来说是一个巨大的挑战。经验的总结和知识的提炼,往往会形成一些技巧。例如本草纲目是中医的技巧、鲁班书是木工的技巧等等。在架构领域,也会有一些技巧可以帮助大家提升架构工作的效率。这里就分享一二。


对现有系统的分析

作为一个架构师,不可能所有的工作都是从 0 到 1,总有需要了解现有系统的场景。但是作为一个软件工程师(架构师首先应该是一个合格的软件工程师),大家往往对他人的代码有着天生的抵触,历史的系统在大家眼里往往就如屎山一般。需要了解一个现有的系统,很多情况下是一个费时费力的事情。但是对于架构师来说,一需要了解系统的全貌,二不会给这么多的时间去一点点的抽丝剥茧。那有没有好的方式可以快速的了解一个系统呢?答案是肯定的。

首先,对于一个系统,我们只需要抓住系统的两个方面:

  • 对外提供的服务和对外依赖的服务;

  • 内部的模型设计。

抓住了这两方面,基本上一个系统的全貌大半就已经掌握了。所以,对于一个不熟悉的系统,需要首先去分析这个系统的领域模型以及 Facade 和 Integration。

其次,Facade、Integraion 和 Model 都是静态的,往往很难和这个系统在实际业务场景中扮演的角色联系起来。这里就需要用到业务链路来进行补充。我们需要分析和当前系统相关业务场景有哪些,然后针对逐个业务场景,实际发起一笔请求,然后通过端到端链路对系统之间的服务调用关系以及业务行为对模型的影响进行分析,将服务模型和对应的业务场景串联起来。

通过上述两步的分析,基本上一个系统的全貌就可以掌握七七八八了。


高阶的架构设计

架构设计是分层的,架构师的能力也是分层的。初级的架构师,往往可以比较好的设计一个模块或者一个应用,但是对于一个大型的项目或者大型的应用系统,可能会觉得无从下手。当然,那些只会套用 referece architecture,只能做高阶战略规划设计,无法实际落地一个应用模块的混子,也不是合格的架构师。

一个架构师从初级往中高级走,从应用内架构到应用间系统间架构走,最重要的是培养自己的抽象能力。

抽象能力,换一句大白话就是抓住重点忽略细枝末节的能力。

前面说了一个应用一个系统,最主要的就是服务和模型,那所谓的抽象就是抓住关键的服务和关键的模型。

这就好比我们用高德地图的时候,zoom out 的时候,很多细小的道路河流山脉都不见了,留下的可能只是大江大河大路。做架构的时候也一样:

  • 我们在做一个模块或者一个应用的设计的时候,需要关注所有的服务和所有的模型及其关系。

  • 但是如果我们是在做一个大型系统的设计,只需要关注其中重点的服务和模型。

  • 首先,我们需要分析这个系统的最核心功能是什么。

  • 将核心功能之外的模型和服务先忽略。

  • 将后台类的服务和模型也先忽略。

  • 将异常链路的服务和模型先忽略。

  • 将非根模型的模型忽略。

  • 剩下的就是需要重点关注的模型和服务。在做系统高阶设计的时候,关注点应该在这里。

这个抽象的方法说的比较笼统,听着也比较玄乎。那我们就举一个例子来说明。

比如我们要做一个卡收单系统,那么:

  • 核心的功能就是下单和支付。

  • 旁支的认证、鉴权、审计类服务先忽略。

  • 后台类的小二改单服务先忽略。

  • 拒付和拒付反转先忽略。

  • 重点关注商品订单和支付订单。

  • 商品订单中为了支撑合并支付设计的订单行模型先忽略。

  • 支付订单中为了支持跨币种支付设计的兑换模型先忽略。

  • 最终重点关注:createOrder、auth、capture 三个服务和两个订单模型。同时关注三个服务过程中和商户、卡组交互的 Open API。


架构边界的确定

架构边界是一个模块一个应用乃至一个系统担负的职责,架构边界是明确架构定位近而明确组织协同关系的关键。但同时,架构边界的确定往往又是最具挑战的,在日常工作过程中争论最多的部分。对于一些经验尚浅的架构师而言,要明确架构边界是比较困难的。同时架构边界的不合理在后续的架构设计过程中又会被成倍的放大。

架构边界,是在回答一个做什么不做什么的问题,也是在回答一个架构是什么不是什么的问题。归根到底,这个和系统或应用的定位密切相关。

首先,做架构边界的切分,无非就是水平和垂直两种方式。

对于垂直的职责划分,就是我们通常说的分层架构。按照惯常的分法,无非就是基础设施、平台服务(中间件)、容器、应用这样的分层。首先我们要明确的是提供网络、计算、存储的基盘能力,还是提供消息、通讯、缓存、数据库的平台服务,或者是应用服务。对于应用架构师而言,一般都是处于提供业务服务的应用层。在微服务架构下,对于应用层,有时候可以继续细分为原子服务、产品服务、对外集成(Gateway)三层。

对于水平的职责划分,就是在同一层内部,根据系统提供的能力进行能力的聚合和隔离。对于 Paas 层,这种切分比较容易,Messaging、Cache、Database、OSS,业界已经有比较明确的切分方式。

但是对于 Saas 层,这个分法就五花八门了。根据康威定律,组织架构设计的不同,往往也会影响到这个应用层水平的架构边界划分的结果。

在确定这部分的架构边界上,可以通过职责切分和系统交互两方面来验证边界的定义是否合理。

我们首先可以通过对应用系统承担的职责或者所服务的组织来对架构边界进行第一轮的确定。一个业务部门或业务领域对应的能力就是对应业务系统天然的架构边界。比如财务、法务、客户服务、各类产品服务等。

其次,在微服务架构中,架构边界往往可以通过服务定义来体现。系统之间的服务交互,应该遵循如下原则:

  • 完整性原则:一个系统提供的能力应该是完整的,比如支付服务、资金服务,上游系统对下游系统对调用可以遵循申明式的原则,将一部分的需求完整的代理给下游系统。对于下游系统提供的业务能力,不应该要求上游系统有编排的动作。

  • 最简化原则:一个链路上所有的系统都应该能明确自己的定位,要么提供基础的能力,要么组合下游的能力包装出一个完整的独立能力。如果不满足这俩条件,这个系统的架构边界就会有问题,这个系统就不应该可以被简化掉。

  • 有用原则:对于业务层的系统,都应该提供相应的业务能力,如果仅仅提供的是技术服务,一般不应该以单独系统的方式出现,而应该以类库的方式被集成。即使是像 Gateway 这样的应用,往往也需要提供验证、鉴权、组合产品的能力。

通过这些原则,将前面根据业务领域切分的架构边界做进一步的细化,就可以得到一个比较合理的架构边界。


实施路径的规划

如果说架构边界的选择是解决做什么的问题,那么实施路径的选择就是要解决怎么做的问题。

对于一个架构师,最挑战也是最无奈的地方往往是现实跟不上理想的翅膀。设计了一个完美的架构,给出了一个“合理”的资源需求之后,最后能从老板那里拿到的资源往往不到一半甚至 1/3。这里就需要对架构的实施路径做好规划,需要分步实施,需要有裁剪和取舍。

这下又是一个痛苦的烦恼了,自己设计的架构那真是哪里都好,哪里都应该是 P0 优先级。哪些功能应该缓一缓,选择困难症出现了。

其实,对于实施路径的规划,其实很简单。我们只需要牢记两个原则:

  • 尽快成功原则:一个成功的架构是最好的证明。对自己、对老板、对团队都是一个最好的交代。所以我们做路径规划的时候,需要尽可能的快速拿到架构成果。

  • 有奶便是娘原则:一个软件架构,总有一个最大的 sponsor,要么是直接领导,要么是业务方,要么是甲方,要么是用户。怎么判断?钱来自哪里,哪里就是最重要的 sponsor。sponsor 的优先级,就是路径规划的优先级。

基于上述两个原则,我们需要将整个软件架构中的模块划分成核心功能、重要功能和辅助功能三类,实施路径呼之欲出。

什么是核心功能,也很简单,就是 MVP 需要的功能:「支撑 MVP,架构师需要做什么」


应用集成模式的选择

在服务架构中,应用和应用之间存在大量的依赖和交互。系统间集成模式的选择是一个常见的架构决策点。

这部分的架构决策相对比较简单。

系统间的集成模式,从集成方式上可以分为同步和异步,从通讯协议上一般有 HTTP(s)、RPC,从编码方式上一般有二进制、XML、json、plan text 等。

首先,对于同步和异步的选择,我们可以从以下几个方面去考量:

  • 用户体验:用户需要及时拿到结果的,考虑同步方式;用户可以通过事后通知的方式交互的,可以考虑异步方式。

  • 服务的 SLA:对于服务的响应实时性要求高的,可以考虑用同步的方式;对于非实时的服务,可以考虑异步的方式。

  • 数据量:对于小数据量(单条、交易性的),一般用同步的方式;对于大数据量(批量、统计性的),一般用异步的方式。

  • 应用可用性比较:如果是下游系统可用等级不小于上游系统的,可以考虑同步的方式;如果下游系统的可用等级远小于上游系统的,一般需要考虑采用异步的方式解除强依赖。

其次,对于通讯协议上的选择:

  • 对于内部的集成,没有太强的安全限制,同时调用相对频繁,对时延要求相对较高的,可以采用 RPC 的方式,通过长连接等能力提升集成性能。

  • 对于外部的集成,需要有安全认证,调用相对低频,同时对时延的要求没有那么苛刻的,可以采用 HTTP(s)的方式,同时通过 Gateway 进行交互。

最后,对于编码方式的选择:

  • 如果是 RPC 的集成方式,一般采用二进制,例如 protobuf、hessian 等。

  • 如果是采用 HTTP(s)的集成 fang 是,一般采用文本的方式,目前国内流行 json,国外相对用 xml 的也挺多。这俩者区分不大。


发布于: 刚刚阅读数: 3
用户头像

agnostic

关注

常识、KISS、高可用、合规架构、架构治理 2019-02-14 加入

二十年架构经验,互联网金融专业架构师。Open Group Master Certified Architect

评论

发布
暂无评论
架构的技巧_agnostic_InfoQ写作社区