golang通过YAML语法生成微服务架构图的GraphViz插件draft的使用

Golang通过YAML语法生成微服务架构图的GraphViz插件draft使用指南

Draft简介

Draft是一个命令行工具,它使用YAML文件中定义的声明性语法生成高级微服务和无服务器架构图。

特点:

  • 支持Linux、macOS和Windows系统
  • 只需一个可移植的二进制文件
  • 使用平面YAML文本文件作为输入数据
  • 可与shell脚本配合使用

为什么选择Draft?

Draft让您专注于功能需求而非特定供应商服务:

  • "我们需要DNS吗?“而不是"我们需要Route 53吗?”
  • "我们需要CDN吗?“而不是"我们需要Cloudfront吗?”
  • "我们需要数据库吗?如果需要,是什么类型?关系型还是NoSQL?“而不是"我们需要Google Cloud Datastore吗?”
  • "我们需要一些无服务器功能吗?“而不是"我们需要Azure Function吗?”

Draft工作原理

Draft接收一个声明性YAML文件作为输入,并生成一个用于Graphviz的dot脚本。

draft backend-for-frontend.yml | dot -Tpng -Gdpi=200 > backend-for-frontend.png

通过将draft输出管道传输到GraphViz的dot,您可以生成不同的输出格式:

格式 命令
PNG draft input.yml | dot -Tpng > output.png
JPEG draft input.yml | dot -Tjpg > output.jpg
PostScript draft input.yml | dot -Tps > output.ps
SVG draft input.yml | dot -Tsvg > output.svg

安装步骤

要自己构建二进制文件(假设您已安装Go),步骤如下:

  1. 克隆仓库
git clone https://github.com/lucasepe/draft.git
  1. 进入cmd目录
cd draft/cmd
  1. 生成静态资源
go generate ../...
  1. 构建二进制工具
go build -o draft

组件

每个draft设计的基本单位是component,具有以下属性:

名称 必需 作用域 备注
id 否 用于连接 如果省略则自动生成
kind 是 标识组件类型 参见所有可用kind
provider 否 获取特定提供商的图标 参见使用自定义图标
label 否 组件图标下方的文本 可以包含基本的HTML标签
outline 否 用于分组组件的标签
impl 否 图标上方的文本 可用于指定提供程序实现
fontColor 否 标签文本颜色 十六进制颜色代码 - 也支持透明度

关于组件id的说明

  • 您可以显式定义组件id(例如id: MY_SERVICE_A)
  • 或者您可以省略组件id属性,它将自动生成

组件id如何自动生成?

自动生成的组件id有一个前缀和一个序列号:

  • 前缀与组件kind相关
    • 例如waf1, ..., wafN或ser1, ..., serN等

所有可用kind列表

Draft使用一组独立于不同提供商(AWS、Microsoft Azure、GCP)的符号。以下是当前实现的所有组件。

客户端

示例YAML文件:examples/clients.yml

draft -impl -verbose examples/clients.yml | dot -Gdpi=110 -Tpng > examples/clients.png

网络

示例YAML文件:examples/networking.yml

draft -impl -verbose examples/networking.yml | dot -Gdpi=110 -Tpng > examples/networking.png

计算

示例YAML文件:examples/compute.yml

draft -impl -verbose examples/compute.yml | dot -Gdpi=110 -Tpng > examples/compute.png

数据库

示例YAML文件:examples/database.yml

draft -impl -verbose examples/database.yml | dot -Gdpi=110 -Tpng > examples/database.png

存储

示例YAML文件:examples/storage.yml

draft -impl -verbose examples/storage.yml | dot -Gdpi=110 -Tpng > examples/storage.png

安全

示例YAML文件:examples/security.yml

draft -impl -verbose examples/security.yml | dot -Gdpi=110 -Tpng > examples/security.png

使用自定义图标

以下是使用特定aws、google和azure图标渲染组件的方法:

  1. 下载云提供商的PNG图标(AWS、GCP、Azure)
  2. 仅获取与draft支持的组件相关的图标
  3. 创建一个以提供商名称命名的目录(例如/draft/icons/aws、/draft/icons/google、/draft/icons/azure)
  4. 将每个图标重命名为draft组件的kind(例如dns.png、cdn.png等)
  5. 使用环境变量DRAFT_ICONS_PATH指定图标文件夹运行draft
    • 示例:DRAFT_ICONS_PATH=/draft/icons draft my-file.yml | dot > ark-aws.png

连接

连接组件的箭头。

要将一个origin组件与一个或多个targets组件连接,您需要至少指定每个id。

一个connection具有以下属性:

属性 类型 必需 说明
origin string 是 起始组件的id
targets object 是 一个或多个目标

每个target具有以下属性:

属性 类型 必需 说明
id string 是 目标组件id
label string 否 连接上的文本
labeldistance float 否 标签与连接尾部的距离
labelangle float 否 确定标签相对于尾部的位置
minlen float 否 设置最小连接长度
num int 否 用于跟踪图中的顺序路径
color string 否 标签颜色(十六进制颜色字符串)
dashed bool 否 如果为true,连接线将为虚线
dir string 否 箭头方向(forward, back, both, none)
highlight bool 否 如果为true,箭头会变粗

示例YAML文件:examples/connections.yml

draft examples/connections.yml | dot -Gdpi=110 -Tpng > examples/connections.png

完整示例

以下是一个完整的微服务架构YAML示例:

# 微服务架构示例
components:
  - kind: client
    label: Web Browser
    id: web_browser

  - kind: cdn
    label: Content Delivery Network
    id: cdn

  - kind: lb
    label: Load Balancer
    id: lb

  - kind: container
    label: API Gateway
    id: api_gateway

  - kind: container
    label: User Service
    id: user_service

  - kind: container
    label: Product Service
    id: product_service

  - kind: db
    label: User Database
    id: user_db

  - kind: db
    label: Product Database
    id: product_db

connections:
  - origin: web_browser
    targets:
      - id: cdn
        label: HTTPS

  - origin: cdn
    targets:
      - id: lb
        label: HTTPS

  - origin: lb
    targets:
      - id: api_gateway
        label: HTTP/2

  - origin: api_gateway
    targets:
      - id: user_service
        label: gRPC
      - id: product_service
        label: gRPC

  - origin: user_service
    targets:
      - id: user_db
        label: SQL

  - origin: product_service
    targets:
      - id: product_db
        label: SQL

要生成架构图,运行:

draft microservices.yml | dot -Tpng -Gdpi=200 > microservices.png

这将生成一个PNG格式的微服务架构图,清晰地展示了各个组件及其连接关系。


更多关于golang通过YAML语法生成微服务架构图的GraphViz插件draft的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang通过YAML语法生成微服务架构图的GraphViz插件draft的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用Go通过YAML生成微服务架构图的GraphViz插件

GraphViz是一个强大的图形可视化工具,而Go语言可以通过YAML定义来生成微服务架构图。下面我将介绍如何使用Go实现这一功能。

基本概念

  1. YAML:用于定义微服务及其关系的结构化格式
  2. GraphViz:生成图形可视化的工具
  3. Go实现:解析YAML并转换为GraphViz的DOT语言

实现步骤

1. 定义YAML结构

首先,我们需要定义描述微服务架构的YAML结构:

services:
  - name: user-service
    description: Handles user authentication and profiles
    dependencies:
      - auth-service
      - database
  - name: auth-service
    description: Manages authentication tokens
    dependencies:
      - database
  - name: order-service
    description: Processes customer orders
    dependencies:
      - user-service
      - inventory-service
      - database

2. Go数据结构

定义对应的Go结构体:

type Service struct {
    Name         string   `yaml:"name"`
    Description  string   `yaml:"description,omitempty"`
    Dependencies []string `yaml:"dependencies,omitempty"`
}

type Architecture struct {
    Services []Service `yaml:"services"`
}

3. 主实现代码

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"

	"gopkg.in/yaml.v2"
)

func main() {
	// 读取YAML文件
	data, err := ioutil.ReadFile("architecture.yaml")
	if err != nil {
		panic(err)
	}

	// 解析YAML
	var arch Architecture
	err = yaml.Unmarshal(data, &arch)
	if err != nil {
		panic(err)
	}

	// 生成DOT文件
	dot := generateDot(arch)

	// 写入DOT文件
	err = ioutil.WriteFile("architecture.dot", []byte(dot), 0644)
	if err != nil {
		panic(err)
	}

	fmt.Println("DOT file generated successfully. Use GraphViz to render it:")
	fmt.Println("dot -Tpng architecture.dot -o architecture.png")
}

func generateDot(arch Architecture) string {
	var builder strings.Builder

	// DOT文件头部
	builder.WriteString("digraph G {\n")
	builder.WriteString("  rankdir=LR;\n")
	builder.WriteString("  node [shape=box, style=rounded];\n")
	builder.WriteString("  edge [arrowhead=vee];\n\n")

	// 添加节点
	for _, service := range arch.Services {
		builder.WriteString(fmt.Sprintf("  \"%s\" [label=\"%s\\n%s\"];\n", 
			service.Name, service.Name, service.Description))
	}

	builder.WriteString("\n")

	// 添加边(依赖关系)
	for _, service := range arch.Services {
		for _, dep := range service.Dependencies {
			builder.WriteString(fmt.Sprintf("  \"%s\" -> \"%s\";\n", service.Name, dep))
		}
	}

	builder.WriteString("}\n")

	return builder.String()
}

4. 使用说明

  1. 将微服务架构定义保存为architecture.yaml
  2. 运行程序生成architecture.dot文件
  3. 使用GraphViz生成图片:
    dot -Tpng architecture.dot -o architecture.png
    

5. 高级功能扩展

可以扩展上述基础实现,添加更多功能:

// 扩展的generateDot函数,支持更多GraphViz特性
func generateDot(arch Architecture) string {
	var builder strings.Builder

	builder.WriteString(`digraph G {
  rankdir=LR;
  node [shape=box, style="rounded,filled", fillcolor="#f0f0f0"];
  edge [arrowhead=vee, color="#666666"];
  graph [bgcolor="transparent"];
  
  // 定义一些样式
  subgraph cluster_0 {
    style=dashed;
    label="Core Services";
    color="#888888";
    
    "database" [shape=cylinder, fillcolor="#e6f3ff"];
  }

`)

	// 按服务类型分组
	apiServices := make([]Service, 0)
	internalServices := make([]Service, 0)
	
	for _, service := range arch.Services {
		if strings.HasSuffix(service.Name, "-api") {
			apiServices = append(apiServices, service)
		} else {
			internalServices = append(internalServices, service)
		}
	}

	// 添加API服务
	builder.WriteString("  // API Services\n")
	for _, service := range apiServices {
		builder.WriteString(fmt.Sprintf("  \"%s\" [fillcolor=\"#ffe6e6\", label=\"%s\\n%s\"];\n", 
			service.Name, service.Name, service.Description))
	}

	// 添加内部服务
	builder.WriteString("\n  // Internal Services\n")
	for _, service := range internalServices {
		builder.WriteString(fmt.Sprintf("  \"%s\" [label=\"%s\\n%s\"];\n", 
			service.Name, service.Name, service.Description))
	}

	// 添加依赖关系
	builder.WriteString("\n  // Dependencies\n")
	for _, service := range arch.Services {
		for _, dep := range service.Dependencies {
			style := ""
			if strings.HasPrefix(dep, "external-") {
				style = ` [style=dashed, color="#ff9999"]`
			}
			builder.WriteString(fmt.Sprintf("  \"%s\" -> \"%s\"%s;\n", 
				service.Name, dep, style))
		}
	}

	builder.WriteString("}\n")

	return builder.String()
}

总结

通过上述Go代码,我们可以:

  1. 从YAML文件读取微服务架构定义
  2. 解析并转换为GraphViz的DOT格式
  3. 生成可视化的架构图
  4. 支持分组、不同样式等高级特性

这种方法使得架构文档可以代码化,随着微服务的变化而轻松更新,保持文档与实际架构的一致性。

要运行此代码,需要安装Go和GraphViz,以及Go的YAML解析库:

go get gopkg.in/yaml.v2
回到顶部