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, ..., wafNser1, ..., 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

使用自定义图标

以下是使用特定awsgoogleazure图标渲染组件的方法:

  1. 下载云提供商的PNG图标(AWS、GCP、Azure)
  2. 仅获取与draft支持的组件相关的图标
  3. 创建一个以提供商名称命名的目录(例如/draft/icons/aws/draft/icons/google/draft/icons/azure
  4. 将每个图标重命名为draft组件的kind(例如dns.pngcdn.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
回到顶部