2.1 环境要求
- Golang 1.17
- DTM
- Etcd
- Redis
- Mysql
- Prometheus
- Grafana
- Jaeger
2.2 Docker 本地开发环境搭建
为了方便开发调试,我们使用 Docker 构建本地开发环境。Windows 和 macOS 系统可下载 Docker Desktop 安装使用,具体下载安装方法可自行搜索相关教程。
这里我们使用 Docker Compose 来编排管理我们的容器,创建如下目录: ```bash gonivinck ├── dtm # DTM 分布式事务管理器 │ ├── config.yml # DTM 配置文件 │ └── Dockerfile ├── etcd # Etcd 服务注册发现 │ └── Dockerfile ├── golang # Golang 运行环境 │ └── Dockerfile ├── grafana # Grafana 可视化数据监控 │ └── Dockerfile ├── jaeger # Jaeger 链路追踪 │ └── Dockerfile ├── mysql # Mysql 服务 │ └── Dockerfile ├── mysql-manage # Mysql 可视化管理 │ └── Dockerfile ├── prometheus # Prometheus 服务监控 │ ├── Dockerfile │ └── prometheus.yml # Prometheus 配置文件 ├── redis # Redis 服务 │ └── Dockerfile ├── redis-manage # Redis 可视化管理 │ └── Dockerfile ├── .env # env 配置 └── docker-compose.yml
<a name="VJZWN"></a>### 2.2.1 编写 Dockerfile在 go-zero 的微服务中采用 grpc 进行服务间的通信,而 grpc 的编写就需要用到 protoc 和翻译成 go 语言 rpc stub 代码的插件 protoc-gen-go。<br />为了提高开发效率,减少代码的出错率,缩短业务开发的工作量,go-zero 还提供了 goctl 代码生成工具。<br />因此,我们需要将 protoc, protoc-gen-go, goctl, 给提前安装到 golang 的容器中,以便后续使用。<br />所以 golang 容器的 Dockerfile 代码如下:```dockerfileFROM golang:1.17LABEL maintainer="Ving <ving@nivin.cn>"ENV GOPROXY https://goproxy.cn,direct# 安装必要的软件包和依赖包USER rootRUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.list && \sed -i 's/security.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.list && \sed -i 's/security-cdn.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.list && \apt-get update && \apt-get upgrade -y && \apt-get install -y --no-install-recommends \curl \zip \unzip \git \vim# 安装 goctlUSER rootRUN GOPROXY=https://goproxy.cn/,direct go install github.com/tal-tech/go-zero/tools/goctl@cli# 安装 protocUSER rootRUN curl -L -o /tmp/protoc.zip https://github.com/protocolbuffers/protobuf/releases/download/v3.19.1/protoc-3.19.1-linux-x86_64.zip && \unzip -d /tmp/protoc /tmp/protoc.zip && \mv /tmp/protoc/bin/protoc $GOPATH/bin# 安装 protoc-gen-goUSER rootRUN go get -u github.com/golang/protobuf/protoc-gen-go@v1.4.0# $GOPATH/bin添加到环境变量中ENV PATH $GOPATH/bin:$PATH# 清理垃圾USER rootRUN apt-get clean && \rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \rm /var/log/lastlog /var/log/faillog# 设置工作目录WORKDIR /usr/src/codeEXPOSE 8000EXPOSE 8001EXPOSE 8002EXPOSE 8003EXPOSE 9000EXPOSE 9001EXPOSE 9002EXPOSE 9003
其他服务容器 Dockerfile 无需特殊处理,只要基于现有的镜像即可。
| 服务 | 基于的镜像 |
|---|---|
| DTM | yedf/dtm |
| Etcd | bitnami/etcd |
| Mysql | mysql:5.7 |
| Redis | redis:5.0 |
| Mysql Manage | phpmyadmin/phpmyadmin |
| Redis Manage | erikdubbelboer/phpredisadmin |
| Prometheus | bitnami/prometheus |
| Grafana | grafana/grafana |
| Jaeger | jaegertracing/all-in-one:1.28 |
2.2.2 编写 .env 配置文件
# 设置时区TZ=Asia/Shanghai# 设置网络模式NETWORKS_DRIVER=bridge# PATHS ########################################### 宿主机上代码存放的目录路径CODE_PATH_HOST=./code# 宿主机上Mysql Reids数据存放的目录路径DATA_PATH_HOST=./data# MYSQL ########################################### Mysql 服务映射宿主机端口号,可在宿主机127.0.0.1:3306访问MYSQL_PORT=3306MYSQL_USERNAME=adminMYSQL_PASSWORD=123456MYSQL_ROOT_PASSWORD=123456# Mysql 可视化管理用户名称,同 MYSQL_USERNAMEMYSQL_MANAGE_USERNAME=admin# Mysql 可视化管理用户密码,同 MYSQL_PASSWORDMYSQL_MANAGE_PASSWORD=123456# Mysql 可视化管理ROOT用户密码,同 MYSQL_ROOT_PASSWORDMYSQL_MANAGE_ROOT_PASSWORD=123456# Mysql 服务地址MYSQL_MANAGE_CONNECT_HOST=mysql# Mysql 服务端口号MYSQL_MANAGE_CONNECT_PORT=3306# Mysql 可视化管理映射宿主机端口号,可在宿主机127.0.0.1:1000访问MYSQL_MANAGE_PORT=1000# REDIS ########################################### Redis 服务映射宿主机端口号,可在宿主机127.0.0.1:6379访问REDIS_PORT=6379# Redis 可视化管理用户名称REDIS_MANAGE_USERNAME=admin# Redis 可视化管理用户密码REDIS_MANAGE_PASSWORD=123456# Redis 服务地址REDIS_MANAGE_CONNECT_HOST=redis# Redis 服务端口号REDIS_MANAGE_CONNECT_PORT=6379# Redis 可视化管理映射宿主机端口号,可在宿主机127.0.0.1:2000访问REDIS_MANAGE_PORT=2000# ETCD ############################################ Etcd 服务映射宿主机端口号,可在宿主机127.0.0.1:2379访问ETCD_PORT=2379# PROMETHEUS ###################################### Prometheus 服务映射宿主机端口号,可在宿主机127.0.0.1:3000访问PROMETHEUS_PORT=3000# GRAFANA ######################################### Grafana 服务映射宿主机端口号,可在宿主机127.0.0.1:4000访问GRAFANA_PORT=4000# JAEGER ########################################## Jaeger 服务映射宿主机端口号,可在宿主机127.0.0.1:5000访问JAEGER_PORT=5000# DTM ########################################## DTM HTTP 协议端口号DTM_HTTP_PORT=36789# DTM gRPC 协议端口号DTM_GRPC_PORT=36790
2.2.3 编写 docker-compose.yml 配置文件
version: '3.5'# 网络配置networks:backend:driver: ${NETWORKS_DRIVER}# 服务容器配置services:golang: # 自定义容器名称build:context: ./golang # 指定构建使用的 Dockerfile 文件environment: # 设置环境变量- TZ=${TZ}volumes: # 设置挂载目录- ${CODE_PATH_HOST}:/usr/src/code # 引用 .env 配置中 CODE_PATH_HOST 变量,将宿主机上代码存放的目录挂载到容器中 /usr/src/code 目录ports: # 设置端口映射- "8000:8000"- "8001:8001"- "8002:8002"- "8003:8003"- "9000:9000"- "9001:9001"- "9002:9002"- "9003:9003"stdin_open: true # 打开标准输入,可以接受外部输入tty: truenetworks:- backendrestart: always # 指定容器退出后的重启策略为始终重启etcd: # 自定义容器名称build:context: ./etcd # 指定构建使用的 Dockerfile 文件environment:- TZ=${TZ}- ALLOW_NONE_AUTHENTICATION=yesports: # 设置端口映射- "${ETCD_PORT}:2379"networks:- backendrestart: alwaysmysql:build:context: ./mysqlenvironment:- TZ=${TZ}- MYSQL_USER=${MYSQL_USERNAME} # 设置 Mysql 用户名称- MYSQL_PASSWORD=${MYSQL_PASSWORD} # 设置 Mysql 用户密码- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} # 设置 Mysql root 用户密码volumes:- ${DATA_PATH_HOST}/mysql:/var/lib/mysql # 引用 .env 配置中 DATA_PATH_HOST 变量,将宿主机上存放 Mysql 数据的目录挂载到容器中 /var/lib/mysql 目录ports:- "${MYSQL_PORT}:3306" # 设置容器3306端口映射指定宿主机端口networks:- backendrestart: alwaysredis:build:context: ./redisenvironment:- TZ=${TZ}volumes:- ${DATA_PATH_HOST}/redis:/data # 引用 .env 配置中 DATA_PATH_HOST 变量,将宿主机上存放 Redis 数据的目录挂载到容器中 /data 目录ports:- "${REDIS_PORT}:6379" # 设置容器6379端口映射指定宿主机端口networks:- backendrestart: alwaysmysql-manage:build:context: ./mysql-manageenvironment:- TZ=${TZ}- PMA_ARBITRARY=1- MYSQL_USER=${MYSQL_MANAGE_USERNAME} # 设置连接的 Mysql 服务用户名称- MYSQL_PASSWORD=${MYSQL_MANAGE_PASSWORD} # 设置连接的 Mysql 服务用户密码- MYSQL_ROOT_PASSWORD=${MYSQL_MANAGE_ROOT_PASSWORD} # 设置连接的 Mysql 服务 root 用户密码- PMA_HOST=${MYSQL_MANAGE_CONNECT_HOST} # 设置连接的 Mysql 服务 host,可以是 Mysql 服务容器的名称,也可以是 Mysql 服务容器的 ip 地址- PMA_PORT=${MYSQL_MANAGE_CONNECT_PORT} # 设置连接的 Mysql 服务端口号ports:- "${MYSQL_MANAGE_PORT}:80" # 设置容器80端口映射指定宿主机端口,用于宿主机访问可视化webdepends_on: # 依赖容器- mysql # 在 Mysql 服务容器启动后启动networks:- backendrestart: alwaysredis-manage:build:context: ./redis-manageenvironment:- TZ=${TZ}- ADMIN_USER=${REDIS_MANAGE_USERNAME} # 设置 Redis 可视化管理的用户名称- ADMIN_PASS=${REDIS_MANAGE_PASSWORD} # 设置 Redis 可视化管理的用户密码- REDIS_1_HOST=${REDIS_MANAGE_CONNECT_HOST} # 设置连接的 Redis 服务 host,可以是 Redis 服务容器的名称,也可以是 Redis 服务容器的 ip 地址- REDIS_1_PORT=${REDIS_MANAGE_CONNECT_PORT} # 设置连接的 Redis 服务端口号ports:- "${REDIS_MANAGE_PORT}:80" # 设置容器80端口映射指定宿主机端口,用于宿主机访问可视化webdepends_on: # 依赖容器- redis # 在 Redis 服务容器启动后启动networks:- backendrestart: alwaysprometheus:build:context: ./prometheusenvironment:- TZ=${TZ}volumes:- ./prometheus/prometheus.yml:/opt/bitnami/prometheus/conf/prometheus.yml # 将 prometheus 配置文件挂载到容器里ports:- "${PROMETHEUS_PORT}:9090" # 设置容器9090端口映射指定宿主机端口,用于宿主机访问可视化webnetworks:- backendrestart: alwaysgrafana:build:context: ./grafanaenvironment:- TZ=${TZ}ports:- "${GRAFANA_PORT}:3000" # 设置容器3000端口映射指定宿主机端口,用于宿主机访问可视化webnetworks:- backendrestart: alwaysjaeger:build:context: ./jaegerenvironment:- TZ=${TZ}ports:- "${JAEGER_PORT}:16686" # 设置容器16686端口映射指定宿主机端口,用于宿主机访问可视化webnetworks:- backendrestart: alwaysdtm:build:context: ./dtmenvironment:- TZ=${TZ}entrypoint:- "/app/dtm/dtm"- "-c=/app/dtm/configs/config.yaml"volumes:- ./dtm/config.yml:/app/dtm/configs/config.yaml # 将 dtm 配置文件挂载到容器里ports:- "${DTM_HTTP_PORT}:36789"- "${DTM_GRPC_PORT}:36790"networks:- backendrestart: always
2.2.4 构建与运行
使用 docker-compose 命令来构建和启动运行我们的服务容器,在根目录执行如下命令:
$ docker-compose up -d
容器构建中

- 在 Windows 系统容器构建中出现如下图所示,请选择 Share it 这将允许 Windows 的文件目录挂载到容器目录中。

- 容器已启动运行
2.2.5 容器说明
| 容器名称 | 暴露端口 | host地址 | 说明 |
|---|---|---|---|
| golang | 8000:8000 8001:8001 8002:8002 8003:8003 9000:9000 9001:9001 9002:9002 9003:9003 |
golang | 在生产环境中微服务一般都是集群部署,可能一个微服务一台服务器,也可能一个微服务一个容器。为了方便开发调试,我们将在 golang 容器中启动所有微服务,并为它们分配监听不同的端口号以示区分。 80:开头的端口号我们将用于 api 服务 90:开头的端口号我们将用于 rpc 服务 |
| dtm | 36789:36789 36790:36790 |
dtm | dtm 的 http 协议和 grpc 协议服务端口号,供客户端交互使用。 此项目中我们只在 Docker 内部容器之间访问使用,所以也可以不暴露端口号给宿主机 |
| etcd | 2379:2379 | etcd | Etcd http api 服务端口号,供客户端交互使用。 此项目中我们只在 Docker 内部容器之间访问使用,所以也可以不暴露端口号给宿主机 |
| mysql | 3306:3306 | mysql | Mysql 服务默认端口号,宿主机可通过 127.0.0.1:3306 进行数据库的连接 |
| redis | 6379:6379 | redis | Redis 服务默认端口号,宿主机可通过 127.0.0.1:6379 进行数据库的连接 |
| mysql-manage | 1000:80 | mysql-manage | phpMyAdmin web 服务端口号,可以在宿主机 127.0.0.1:1000 访问 |
| redis-manage | 2000:80 | redis-manage | phpRedisAdmin web 服务端口号,可以在宿主机 127.0.0.1:2000 访问 |
| prometheus | 3000:9090 | prometheus | Prometheus web 服务端口号,可以在宿主机 127.0.0.1:3000 访问 |
| grafana | 4000:3000 | grafana | Grafana web 服务端口号,可以在宿主机 127.0.0.1:4000 访问 |
| jaeger | 5000:16686 | jaeger | Jaeger web 服务端口号,可以在宿主机 127.0.0.1:5000 访问 |
2.2.6 访问验证
- Mysql 访问验证

- Redis 访问验证

- Prometheus 访问验证

- Grafana 访问验证

- Jaeger 访问验证

项目地址:github

