一年好景君须记,最是橙黄橘绿时。这篇文章主要讲述带你十天轻松搞定 Go 微服务系列相关的知识,希望能为你提供帮助。
本文开始,我们会出一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下:
- 环境搭建(本文)
- 服务拆分
- 用户服务
- 产品服务
- 订单服务
- 支付服务
- RPC 服务 Auth 验证
- 服务监控
- 链路追踪
- 分布式事务
完整示例代码:https://github.com/nivin-studio/go-zero-mall
1 环境要求
Golang
1.15+Etcd
Redis
mysql
Prometheus
Grafana
Jaeger
DTM
Docker
本地开发环境搭建为了方便开发调试,我们使用 Docker
构建本地开发环境。Windows
和 macOS
系统可下载 Docker Desktop
安装使用,具体下载安装方法可自行搜索相关教程。这里我们使用
Docker Compose
来编排管理我们的容器,创建如下目录: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
2.1 编写
Dockerfile
在
go-zero
的微服务中采用 grpc
进行服务间的通信,而 grpc
的编写就需要用到 protoc
和翻译成 go
语言 rpc stub
代码的插件 protoc-gen-go
。为了提高开发效率,减少代码的出错率,缩短业务开发的工作量,
go-zero
还提供了 goctl
代码生成工具。因此,我们需要将
protoc
, protoc-gen-go
, goctl
, 给提前安装到 golang
的容器中,以便后续使用。所以
golang
容器的 Dockerfile
代码如下:FROM golang:1.17LABEL maintainer="Ving <
ving@nivin.cn>
"ENV GOPROXY https://goproxy.cn,direct# 安装必要的软件包和依赖包
USER root
RUN 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 # 安装 goctl
USER root
RUN GOPROXY=https://goproxy.cn/,direct go install github.com/tal-tech/go-zero/tools/goctl@cli# 安装 protoc
USER root
RUN 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-go
USER root
RUN go get -u github.com/golang/protobuf/protoc-gen-go@v1.4.0# $GOPATH/bin添加到环境变量中
ENV PATH $GOPATH/bin:$PATH# 清理垃圾
USER root
RUN apt-get clean &
&
\\
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* &
&
\\
rm /var/log/lastlog /var/log/faillog# 设置工作目录
WORKDIR /usr/src/codeEXPOSE 8000
EXPOSE 8001
EXPOSE 8002
EXPOSE 8003
EXPOSE 9000
EXPOSE 9001
EXPOSE 9002
EXPOSE 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 |
.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=3306
MYSQL_USERNAME=admin
MYSQL_PASSWORD=123456
MYSQL_ROOT_PASSWORD=123456# Mysql 可视化管理用户名称,同 MYSQL_USERNAME
MYSQL_MANAGE_USERNAME=admin
# Mysql 可视化管理用户密码,同 MYSQL_PASSWORD
MYSQL_MANAGE_PASSWORD=123456
# Mysql 可视化管理ROOT用户密码,同 MYSQL_ROOT_PASSWORD
MYSQL_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.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: true
networks:
- backend
restart: always# 指定容器退出后的重启策略为始终重启etcd:# 自定义容器名称
build:
context: ./etcd# 指定构建使用的 Dockerfile 文件
environment:
- TZ=$TZ
- ALLOW_NONE_AUTHENTICATION=yes
- ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
ports:# 设置端口映射
- "$ETCD_PORT:2379"
networks:
- backend
restart: alwaysmysql:
build:
context: ./mysql
environment:
- 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:
- backend
restart: alwaysredis:
build:
context: ./redis
environment:
- TZ=$TZ
volumes:
- $DATA_PATH_HOST/redis:/data# 引用 .env 配置中 DATA_PATH_HOST 变量,将宿主机上存放 Redis 数据的目录挂载到容器中 /data 目录
ports:
- "$REDIS_PORT:6379"# 设置容器6379端口映射指定宿主机端口
networks:
- backend
restart: alwaysmysql-manage:
build:
context: ./mysql-manage
environment:
- 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端口映射指定宿主机端口,用于宿主机访问可视化web
depends_on:# 依赖容器
- mysql# 在 Mysql 服务容器启动后启动
networks:
- backend
restart: alwaysredis-manage:
build:
context: ./redis-manage
environment:
- 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端口映射指定宿主机端口,用于宿主机访问可视化web
depends_on:# 依赖容器
- redis# 在 Redis 服务容器启动后启动
networks:
- backend
restart: alwaysprometheus:
build:
context: ./prometheus
environment:
- TZ=$TZ
volumes:
- ./prometheus/prometheus.yml:/opt/bitnami/prometheus/conf/prometheus.yml# 将 prometheus 配置文件挂载到容器里
ports:
- "$PROMETHEUS_PORT:9090"# 设置容器9090端口映射指定宿主机端口,用于宿主机访问可视化web
networks:
- backend
restart: alwaysgrafana:
build:
context: ./grafana
environment:
- TZ=$TZ
ports:
- "$GRAFANA_PORT:3000"# 设置容器3000端口映射指定宿主机端口,用于宿主机访问可视化web
networks:
- backend
restart: alwaysjaeger:
build:
context: ./jaeger
environment:
- TZ=$TZ
ports:
- "$JAEGER_PORT:16686"# 设置容器16686端口映射指定宿主机端口,用于宿主机访问可视化web
networks:
- backend
restart: alwaysdtm:
build:
context: ./dtm
environment:
- 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:
- backend
restart: always
2.4 构建与运行
- 使用
docker-compose
命令来构建和启动运行我们的服务容器,在根目录执行如下命令:
$ docker-compose up -d
- 容器构建中
文章图片
- 在
Windows
系统容器构建中出现如下图所示,请选择Share it
这将允许Windows
的文件目录挂载到容器目录中。
文章图片
- 容器已启动运行
文章图片
文章图片
容器名称 | 暴露端口 | host地址 | 说明 |
---|---|---|---|
golang | 8000:8000< br> 8001:8001< br> 8002:8002< br> 8003:8003< br> 9000:9000< br> 9001:9001< br> 9002:9002< br> 9003:9003 | golang | 在生产环境中微服务一般都是集群部署,可能一个微服务一台服务器,也可能一个微服务一个容器。为了方便开发调试,我们将在 golang 容器中启动所有微服务,并为它们分配监听不同的端口号以示区分。<
br>
80:开头的端口号我们将用于 api 服务 <
br>
90:开头的端口号我们将用于 rpc 服务 |
dtm | 36789:36789< br> 36790:36790 | dtm | dtm 的 http 协议和 grpc 协议服务端口号,供客户端交互使用。<
br>
此项目中我们只在 Docker 内部容器之间访问使用,所以也可以不暴露端口号给宿主机 |
etcd | 2379:2379 | etcd | Etcd http api 服务端口号,供客户端交互使用。<
br>
此项目中我们只在 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 访问 |
Mysql
访问验证
文章图片
Redis
访问验证
文章图片
Prometheus
访问验证
文章图片
Grafana
访问验证
文章图片
Jaeger
访问验证
文章图片
欢迎使用
go-zero
并 star 支持我们!微信交流群【带你十天轻松搞定 Go 微服务系列】关注『微服务实践』公众号并点击 交流群 获取社区群二维码。
推荐阅读
- 准时下班系列!Excel合集之第6集—如何拆分和统计单据金额
- #yyds干货盘点#公司规定所有接口都用 POST请求,这是为什么()
- 想说爱你不容易 | 使用最小 WEB API 实现文件上传(Swagger 支持)#yyds干货盘点#
- spring cloud alibaba 组件版本关系 以及 毕业版本依赖关系
- #yyds干活盘点# 3 Css3 的背景
- Kubernetes家族容器小管家Pod在线答疑()
- Xp设置系统无法打开QQ提示找不到ssocommon该怎样办?
- XP深度纯净版开机慢点击程序半天没反应该怎样办?消除电脑右下角感叹号!
- 深度windows xp上不了网该怎样办?驱动删除了上不了网的处理办法