补体c3c4是什么意思(空调显示c4是什么意思)

一种新的有效软件体系结构的活文档方法

每天?分享?最新?软件?开发?,DevOps,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?3分钟?学习?何乐而不为?,希望?大家?点赞?,加?关注?,你的?支持?是我?最大?的?动力?。
简介

我很幸运,目前作为一个解决方案架构师从事一个大型的基于微服务的项目。我负责设计不同的架构视图,每个视图针对不同的受众,因此有不同的关注点:

  • 应用程序视图处理模块和它们之间的数据流(针对产品涉众和开发人员)
  • software view 软件视图 (设计模式、数据库设计规则、编程语言的选择、库… …)开发人员应该依赖的;
  • 基础设施视图(中间件,数据库,网络连接,存储,操作…)为集成商和 DevOps 工程师提供有用的信息;
  • 尺寸视图处理表现;
  • security view主要是横向的

注意

我们使用这个开源模板来记录我们的架构。


我们当前的项目体系结构相当复杂,因为有大量的模块(数十个作业、 API 和 GUI 模块) ,因为有大量的外部合作伙伴,还因为它与大型遗留信息系统的集成。

此时,我们必须维护超过100个架构图。遵循一种活文档方法,我们每天多次调整和扩充图表、文本和表格。正如我们将在后面看到的,它通常是一个利用多个伟大工具的协作过程。

申请样本

我们用一个虚构的 AllMyData 微服务应用程序来说明本文。这是一个。「政府一站通」网上应用程式,让任何公司都可以让所有公共行政部门知悉其所有资料。

我们可以将我们的特性“提供公司数据”分为两个主要的呼叫链:

  • 第一个调用链由向系统中创建请求的 GUI 请求组成
  • 第二种是由定期启动的作业和消耗新请求构成的。它从本地存储库和另一个管理 IS (Information System)收集有关公司的数据,生成 PDF 报告,并向公司的原始请求者发送电子邮件

C4 Model

我们使用 C4模型来表示我们的架构。深入地描述它已经超出了本文的范围,但是我邀请您看一看这种非常实用的方法。我发现设计复杂的架构是很自然的。它利用了 UML2标准,并在高级关注点和代码级关注点之间提供了很好的二分法。

注意

Archimate 可能是另一个非常适合我们的选择,但是在我们非常低的模型化采用和知识背景下,它可能有点过分了。此外,我们喜欢 C4 KISS/低技术方法,考虑到许多人类心理标准。注意,一些 Archimate 工具使用概念间的映射来支持 C4图。但不确定将两者混合使用是否是个好主意。


在我们的上下文中,我们目前使用三种主要的 C4图类型(请注意,C4和 UML2包含其他在这里没有列出的图类型) :

  • System landscape diagrams 提供一个非常高层次的系统视图。我们使用它来描述一般的应用程序架构
补体c3c4是什么意思(空调显示c4是什么意思)

  • Container diagrams 用于描述中间件、数据库和许多其他技术组件以及它们之间的数据流。它们类似于 UML2部署图,但在我看来更自然。在应用程序视图中,我们主要显示模块和数据库,在基础设施视图中,我们深入到技术设备,如反向代理、负载平衡器、集群细节等。我们还使用 C4动态图,非常类似于容器图,但包括调用编号
补体c3c4是什么意思(空调显示c4是什么意思)

  • 各种 UML2图表(序列,活动,类)。我们简单地使用它们,只用于表示模式或特别重要或复杂的内容,但肯定不适用于普通代码
补体c3c4是什么意思(空调显示c4是什么意思)


注意

我非常不愿意使用 C4容器术语,因为可能会与 docker/OCI 容器混淆(正如 C4创建者 Simon Brown 所指出的)。在我们的组织中,我们更喜欢称之为可部署单位。C4模型鼓励术语的调整。C4容器基本上是一个独立的可部署流程。C4文档声明: “本质上,容器是一个单独的可运行/可部署单元(例如,一个单独的进程空间) ,它执行代码或存储数据”。

在 C4模型中,容器可以包含一个或多个软件组件。这个概念并不指基础结构组件,而是指一些大段代码(比如一组 Java 类)。我们很少在架构文档中使用 C4组件,因为我们并不真的需要深入到那个层次的细节(我们的六边形架构仅仅通过阅读代码就使事情变得简单易懂,而我们的敏捷方法使我们更喜欢限制我们必须维护的设计文档)。


Plantuml

Plantuml 是一个令人印象深刻的工具,它可以从一个非常简单的文本 DSL (领域特定语言)生成即时图。

例如,这个非常短的文本:

Plain Text

@startumlbr   [Browser] -> [API Foo]: HTTPSbr@enduml

足以产生这样的图解:

补体c3c4是什么意思(空调显示c4是什么意思)

Plantuml 提供了数以百计的特性和语法优点,有时没有文档记录,并且发展非常迅速。我建议这个网站作为一个明确和详尽的文件参考。

点击这里查看一些真实世界的例子。

Plantuml 联合 C4

Plantuml 组件图可以使用这个扩展库定制为 C4图。

只需在 Plantuml 图表的顶部导入它,然后使用 C4宏:

@startuml
   !include HTTPS://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
   !include <tupadr3/devicons2/chrome>
   !include <tupadr3/devicons2/java>
   !include <tupadr3/devicons2/Postgresql>
   LAYOUT_LEFT_RIGHT()
   Container(browser, "Browser","Firefox or Chrome", $sprite="chrome")
   Container(api_a, "API A","Spring Boot", $sprite="java")
   ContainerDb(db_a, "Database A","Postgresql", $sprite="postgresql")
   Rel(browser,api_a,"HTTPS")
   Rel_R(api_a,db_a,"pg")
@enduml

输出为:

补体c3c4是什么意思(空调显示c4是什么意思)


注意

  • 始终导出 SVG 格式的图表,以允许无限缩放。在处理大型图表时,这是可以理解的。
  • 我们在这里使用在线最新版本,但您可能更喜欢使用静态下载版本的气隙模式。

图表分解

Plantuml 的一个优点是使用了! include 和! include 子预处理器指令的因子分解功能。

可以包括本地或远程关系图(即。以@startuml 开始,以@enduml 指令结束)。例如,使用以下指令包含 C4宏:

!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

更有趣的是,还可以导入图片片段(例如,以! startsub 开始,以! endsub 指令结束) :

fragments.iuml文件:

!startsub dmz
  !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
  !include <tupadr3/devicons2/chrome>
  !include <tupadr3/devicons2/java>
  Container(browser, "Browser","Firefox or Chrome", $sprite="chrome")
  Container(api_a, "API A","Spring Boot", $sprite="java")
!endsub

!startsub intranet
  !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
  !include <tupadr3/devicons2/postgresql>
  ContainerDb(db_a, "Database A","Postgresql", $sprite="postgresql")
}
!endsub

!startsub extranet
  !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
  !include <tupadr3/devicons2/postgresql>
  ContainerDb(db_b, "Database B","Postgresql", $sprite="postgresql")
}
!endsub

File diags-1.puml:

@startuml use-case-1
  ' We only include context-related sub-diagams
  !includesub static.iuml!dmz
  !includesub static.iuml!intranet
    
  Rel(browser,api_a,"","HTTPS")
  Rel_R(api_a,db_a,"pg")
@enduml

过滤未链接的容器

自2020年中期以来,Plantuml 为软件架构师提供了一个改变游戏规则的特性:。它只从 C4图中保留调用或被调用的容器,并删除其他任何容器。

这个特性(以及图片片段能力)是实现下面描述的图模式的需求。

Sprites

数以千计的精灵可用于装饰 C4容器。它们现在直接嵌入到最新的 Plantuml 版本中。它们包括 Devicon、 Font-Awesome、 Materials、 Office、 Weather 和许多其他图标库。大多数软件、硬件、网络和面向业务的图标已经准备好开箱即用了!

根据我的经验,在 C4容器中使用Sprites可以使图更通顺,因此更容易阅读。也许它能帮助我们的大脑更快地识别每个容器的性质?

请注意,即使您可以使用不同的背景颜色来区分 C4容器基于特定的标准(例如,我使用浅灰色的外部 API) ,我们建议使用Sprites代替表示自然,因为它使图表更清晰,默认的蓝色在大多数情况下是好的。

Plantuml IDE Plugins

Plantuml 是一种非常通用的技术,可用于许多不同的场合,包括:

  • 一个简单的 base64编码的 URL,比如 https://www.plantuml.com/plantuml/uml/sowkiimgastdul9gk8xsaielbqujybngjle8twpml73bpuzli5bm20a92epoicrb0qe40000;
  • 在像 LibreOffice 或 Word 这样的 Word 处理器内部;
  • 从编程语言,如 Groovy、 Java 或 Python;
  • 在大多数 IDE 像 Intellij IDEA 感谢这个插件;
  • 或者在 Eclipse 中使用这个插件;
  • 但是我自己最喜欢的是 VScode 插件。除了其他特性之外,它还支持从单个。docker文件和多图/多docker文件图的生成。它可以被微调。

补体c3c4是什么意思(空调显示c4是什么意思)

Architecture as Code

IDE Plantuml 集成的一个非常好的副作用是,您不仅可以通过从排列杂务中释放而更快地创建图表,而且还可以在编写代码时编写图表。可以在键入时自动生成和刷新关系图。

Mob Designing

这种工具支持我称之为“暴徒设计”的东西。特别是在我们项目的开始阶段,但是目前,我们仍然在对软件架构进行头脑风暴。使用 Plantuml 和一个大型共享屏幕,创建和比较多个体系结构场景非常方便。

“如果 API A 被客户机 B 直接调用怎么办?”或者“作业 J 应该异步调用它吗?”…

与最终用户真正需要可视化屏幕原型的方式相同,开发人员和架构师在图表面前思考得更好。这也极大地限制了由于自然语言的局限性和大量的模糊性而引起的误解。

Inventory and Dependencies Diagrams

作为一个蓝图,我们使用! include 和/或! include 子指令来分隔:

  • 库存图显示体系结构的静态元素(分为不同的网络区域,并用边界表示) ,但不显示它们之间的关系。它们对于回答诸如“什么包含某一区域?”这样的问题很有用或“哪些模块涵盖系统 xyz?”).在应用程序视图中,清楚地显示复杂微服务体系结构的系统模块,或在基础设施视图中表示每个网络区域及其可部署单元中的节点,都是特别有用的。这种图使用 C4容器图。

  • 依赖关系图利用静态关系图,但是通过容器之间的调用来增强它们。库存图可以单独使用,但是依赖关系图必须导入库存图。它应该回答“ X 调用了哪个模块/容器”或“ X 调用了哪个模块/容器?”.这对于影响研究也很有帮助: “如果我改变 API X,会有什么影响?”.

库存图示例:

inventory.puml文件:

@startuml
header Inventory diagram
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
!include <tupadr3/devicons2/chrome>
!include <tupadr3/devicons2/java>
!include <tupadr3/devicons2/postgresql>
!include <tupadr3/devicons2/nginx_original>
!include <tupadr3/devicons2/react_original>
!include <tupadr3/devicons2/android>
!include <tupadr3/devicons2/groovy>
!include <tupadr3/material/queue>
!include <tupadr3/material/mail>
!include <tupadr3/devicons2/dot_net_wordmark>
!include <tupadr3/devicons2/oracle_original>
!include <office/Concepts/web_services>
skinparam linetype polyline
HIDE_STEREOTYPE()
SHOW_PERSON_PORTRAIT()

System(client, "Client") {
    Container(spa, "SPA allmydata-gui", "Container: javascript, React.js", "Graphical interface for requesting information", $sprite="react_original")
    Container(mobile, "AllMyData mobile application", "Container: Android", "Graphical interface allowing to request information", $sprite="android")
}    

Enterprise_Boundary(organisation, "System organisation B") {
    Container_Ext(saccounting, "Accounting system", "REST service", $sprite="web_services")
}

Enterprise_Boundary(si, "Information System") {
    Container(static_resources, "allmydata-gui Web Application", "Container: nginx", "Delivers static resources (js, html, images ...)", $sprite="nginx_original")
    Container(sm, "allmydata-api", "Container: Tomcat, Spring Boot", "REST service allowing to request information", $sprite="java")
    Container(crep, "Companies repository", "Container", "SOAP webservice providing data about companies known by administration A", $sprite="dot_net_wordmark")
    ContainerDb(crep_db, "companies-repository-db", "Container: SqlServer", "Stores companies data",$sprite="oracle_original")
    Container(batch, "allmydata-batch", "Container: groovy", "Process requests, launched by cron every minute", $sprite="groovy")
    ContainerQueue(queue, "requests-queue", "Container: RabbitMQ", "Stores requests", $sprite="queue")
    ContainerDb(amd_db, "allmydata-db", "Container: PostgreSQL", "Stores requests history and status",$sprite="postgresql")
    Container(sreporting, "service-reporting-pdf", "Container: Tomcat, JasperReport", "Reporting REST service", $sprite="java")
    Container(smails, "mail server", "Container: Postfix", "Send emails", $sprite="mail")
}
@enduml

补体c3c4是什么意思(空调显示c4是什么意思)

依赖关系图示例(导入它的库存对应物,然后添加一个人和一堆调用) :

dependencies.puml文件:

文件依赖:

@startuml dependencies
  header Dependencies diagram

  !import inventory.puml
  
  Rel(client, static_resources, "HTTPS")
  Rel(spa,sm,"REST call","HTTPS")
  Rel(sm,queue,"AMQP")
  Rel(sm,amd_db,"psql")
  Rel(batch, queue, "AMQP")
  Rel_R(batch, saccounting, "HTTPS")
  Rel(batch, sreporting,"HTTP")
  Rel(batch, smails, "SMTP")

  remove @unlinked
@enduml

补体c3c4是什么意思(空调显示c4是什么意思)

描述调用链的动态图

一旦我们使用清单视图和依赖视图提供了系统大图,我们将使用第三种 C4图: C4动态图来描述每个主要特性的详细体系结构。C4容器和动态图非常相似,但后者带有自动调用编号。


注意

  • 对于复杂的交互,有些人可能更喜欢旧的优秀的 UML2序列图。在大多数情况下,当处理容器交互时,我发现 C4动态图更容易阅读。
  • 当处理复杂的代码设计时,我们宁愿使用 UML2序列图。

C4动态图面向开发人员。它们详细描述了特定特性上下文中涉及的 C4容器之间的调用或数据流,从而提供了每个调用链的详细视图。

特性术语应该是敏捷的意思(满足涉众的需求)。它可以是“允许企业在线访问其数据”或“为订单付费”之类的东西。

这种类型的关系图仍然可以包含区域或边界(在库存或依赖关系图中已经可用) ,从而在更全局的上下文中设置调用链。

体系结构利用一个或多个调用链,调用链由一组有序的调用或操作(如调用 API、在磁盘上写文件等)组成,所有这些都是同步执行的。任何进一步的调用都会在下一个调用链中引用。

补体c3c4是什么意思(空调显示c4是什么意思)


注意

  • “同步”是指一组共享相同逻辑“事务”的活动。技术上的异步调用(比如在使用响应式编程时)仍然适用。相反,在一个呼叫链产生一条消息作为事件驱动架构的一部分的情况下,即使该事件的产生和消耗在技术上几乎是瞬间的,这个事件消耗和另一个模块的计算并不计入同一个呼叫链中。
  • 如果认为有帮助,我们会在图之前或之后使用一些文本上下文(使用 AsciiDoc)来增加图,但是这些文本应该是综合的,而不是与图本身冗余。然而,调用链图本身通常就足够了。

我们利用前面解释的库存图片片段和未链接的容器过滤来实现有效的架构即代码模式。

文件调用链传递 -1. pul (注意这里的 remove@unlink 用法) :

@startuml deliver-1.puml
  !import inventory.puml
  ' For call chains, we advise to put a header (displayed by default at the upper-right 
  ' side of the diagram) to ease its identification.
  header deliver-1

  Person_Ext(company, "Company", "[person] \nWeb client (PC, tablet, mobile)")
  Rel(client, static_resources, "Visit https://allmydata.gouv", "HTTPS (R)")
  Rel(client, spa, "Retrieves information via")
  Rel(spa,sm,"REST call","HTTPS (W)")
  RelIndex(LastIndex()-1,sm,queue,"Produces a request message to the queue","AMQP (W)")
  RelIndex(LastIndex()-2,sm,amd_db,"Stores the request data","JDBC (W)")
  increment()
  
  ' Remove all C4 containers imported from inventory.puml file but not involved 
  ' in this call chain to make the diagram much cleaner
  remove @unlinked
@enduml

补体c3c4是什么意思(空调显示c4是什么意思)


注意

标准化调用链命名(比如传递 -1、付费 -3、 …)是至关重要的,因为它成为开发人员和业务分析人员之间沟通的强大载体。这样就可以使用规范的名称进行交谈,例如,传递 -13-1。这是一个巨大的误解杀手,节省了时间,也是这种方法的主要优点之一。

我建议简单地使用 < Feature >-< ? 递增數字 > 命名方案。


文件调用链传递 -2. pul (请注意这里的“ remove@unlink”用法) :

@startuml deliver-2.puml
  !import inventory.puml
  header deliver-2

  Rel(sm,amd_db,"JDBC CRUD calls","psql")
  Rel(batch, queue, "Consume each request message", "AMQP (R)")
  Rel(batch, amd_db, "Read various very interesting data about the requester company", "JDBC (R)")
  Rel(batch, saccounting, "Get more interesting data from the Accounting system", "HTTPS (R)")
  Rel(batch, sreporting, "Produces a great PDF including great pie charts", "HTTP (W)")
  Rel(batch, smails, "Send an e-mail to original requester with the attached PDF", "SMTP (W)")
  Rel(batch, amd_db, "Store the request data (date, final status...)", "JDBC (W)")
 
  remove @unlinked
@enduml

补体c3c4是什么意思(空调显示c4是什么意思)


注意

每个调用都应该详细说明使用过的网络协议以及修饰符标志(R: Read,W: Write,E: Execute)。这些标志对于确定呼叫意图非常重要。可以在同一个调用上使用多个标志。


在我们的上下文中,这些调用链图提供了足够的体系结构细节来编写应用程序。它们是我们在实际编码之前编写的唯一设计文档。除此之外,真正的(也是最好的)文档是(干净的)代码本身。

结论

我希望本文的介绍能够引起您对使用 Plantuml 和 C4编码体系结构的好奇心。将来的一篇文章将提供我们的图表最佳实践和一些 Plantuml 在架构上下文中的有用技巧,请保持联系!

最后,我将以一种我无法正式演示但多次观察到的个人感觉结束: 架构图的图形“和谐”与其内在质量成正比。因此,只要看一眼墙上的主图,就可以对复杂的建筑形成第一印象。

按照同样的思想顺序,依赖关系图突出了战略模块,并反映了架构背后隐藏的权力平衡(正如 Conway 定律所预期的那样)。

如果你有债务逾期方面的困扰。可以添加微信: 5290085   添加时请备注: 逾期
本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2798148619@qq.com 举报,一经查实,本站将立刻删除。
如若转载,请注明出处:https://www.181dx.com/4176.html