At the beginning of this article, we will present a series of ten articles detailing a go-Zero microservice example. The structure of the series is as follows:
- Environment Building (This paper)
- Service split
- Customer service
- Product/service
- Order service
- Payment service
- Auth authentication for RPC service
- Service monitoring
- Link to track
- Distributed transaction
I hope this series will take you to use the Docker environment on the machine and use go-Zero to quickly develop a mall system, so that you can quickly get started with micro services.
Full example code: github.com/nivin-studi…
1 Environment Requirements
Golang
1.15 +Etcd
Redis
Mysql
Prometheus
Grafana
Jaeger
DTM
2 Docker
Local development environment setup
In order to facilitate development and debugging, we use Docker to build a local development environment. Docker Desktop can be downloaded for Windows and macOS. For details about how to download and install Docker Desktop, you can search for related tutorials.
Docker Compose: Docker Compose: Docker Compose: Docker Compose: Docker Compose: Docker Compose: Docker Compose: Docker Compose
Gonivinck ├ ─ ─ DTM # DTM distributed transaction manager │ ├ ─ ─ config. Yml # DTM configuration file │ └ ─ ─ Dockerfile ├ ─ ─ etcd # etcd service registry found │ └ ─ ─ Dockerfile ├ ─ ─ golang # golang running environment │ └ ─ ─ Dockerfile ├ ─ ─ grafana # grafana visual data monitoring │ └ ─ ─ Dockerfile ├ ─ ─ jaeger tracking # jaeger link │ └ ─ ─ ├─ ├─ ├─ ├─ Prometheus # ├─ ├─ Prometheus ├─ ├─ Prometheus, Prometheus, Prometheus, Prometheus, Prometheus, Prometheus, Prometheus, Prometheus ├─ ├─ garbage, ├─ garbage, garbage, garbage, garbage, garbage, garbage, garbage, garbage, garbage, garbage, garbageCopy the code
2.1 writeDockerfile
In go-Zero microservice, GRPC is used for communication between services, and the compilation of GRPC needs to use Protoc and protoc-Gen-Go plug-in translated into GO language RPC stub code.
In order to improve the development efficiency, reduce the error rate of code and shorten the workload of business development, Go-Zero also provides the GoCTL code generation tool.
Therefore, we need to pre-install protoc, protoc-gen-go, goCTL into golang’s container for subsequent use.
So the golang Dockerfile code looks like this:
FROM golang:1.17
LABEL maintainer="Ving <[email protected]>"
ENV GOPROXY https://goproxy.cn,direct
Install the necessary software packages and dependencies
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
# installation goctl
USER root
RUN GOPROXY=https://goproxy.cn/,direct go install github.com/tal-tech/go-zero/tools/goctl@cli
# installation protoc
USER root
RUNcurl -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
# installation protoc - gen - go
USER root
RUNGo get the -u github.com/golang/protobuf/[email protected]
# $GOPATH/bin added to the environment variable
ENV PATH $GOPATH/bin:$PATH
# Take out the trash
USER root
RUN apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
rm /var/log/lastlog /var/log/faillog
Set the working directory
WORKDIR /usr/src/code
EXPOSE 8000
EXPOSE 8001
EXPOSE 8002
EXPOSE 8003
EXPOSE 9000
EXPOSE 9001
EXPOSE 9002
EXPOSE 9003
Copy the code
Other service containers dockerfiles need no special handling, just based on existing images.
service | Based mirror |
---|---|
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 write.env
The configuration file
TZ = # set time zone Asia/Shanghai mode NETWORKS_DRIVER = bridge # # set network PATHS # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # CODE_PATH_HOST=./code # Mysql Reids data directory DATA_PATH_HOST=./data # Mysql # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Mysql hosting service mapping port number, MYSQL_USERNAME=admin MYSQL_PASSWORD=123456 MYSQL_ROOT_PASSWORD=123456 # Mysql MYSQL_MANAGE_USERNAME=admin # MYSQL_MANAGE_USERNAME=admin # MYSQL_MANAGE_USERNAME=admin MYSQL_MANAGE_PASSWORD=123456 MYSQL_ROOT_PASSWORD MYSQL_MANAGE_ROOT_PASSWORD=123456 # MYSQL_MANAGE_CONNECT_HOST= Mysql # Mysql server port number MYSQL_MANAGE_CONNECT_PORT=3306 # MYSQL_MANAGE_CONNECT_PORT Available on the host 127.0.0.1:1000 access MYSQL_MANAGE_PORT = 1000 # REDIS # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # REDIS service port mapping host machine, REDIS_PORT=6379 # Redis visual admin user name REDIS_MANAGE_USERNAME=admin # Redis visual admin user password REDIS_MANAGE_CONNECT_HOST= Redis # Redis service port number REDIS_MANAGE_CONNECT_PORT=6379 # Redis visual management mapping host port number, Available on the host 127.0.0.1:2000 access REDIS_MANAGE_PORT = 2000 # ETCD # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ETCD mapping hosting service port, Available on the host 127.0.0.1:2379 access ETCD_PORT = 2379 # PROMETHEUS # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # PROMETHEUS mapping hosting service port, Available on the host 127.0.0.1:3000 access PROMETHEUS_PORT = 3000 # GRAFANA # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # GRAFANA mapping hosting service port, Available on the host 127.0.0.1:4000 access GRAFANA_PORT = 4000 # JAEGER # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # JAEGER mapping hosting service port, Available on the host 127.0.0.1:5000 access JAEGER_PORT = 5000 # DTM # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # DTM HTTP protocol port number DTM_HTTP_PORT=36789 # DTM gRPC port number DTM_GRPC_PORT=36790Copy the code
2.3 writedocker-compose.yml
The configuration file
version: '3.5'
# Network configuration
networks:
backend:
driver: ${NETWORKS_DRIVER}
Service container configuration
services:
golang: Create a custom container name
build:
context: ./golang # specify the Dockerfile file to use for the build
environment: Set environment variables
- TZ=${TZ}
volumes: Set the mount directory
- ${CODE_PATH_HOST}:/usr/src/code # reference the CODE_PATH_HOST variable in the. Env configuration to mount the host code directory to /usr/src/code in the container
ports: Set port mapping
- "8000:8000"
- "8001:8001"
- "8002:8002"
- "8003:8003"
- "9000:9000"
- "9001:9001"
- "9002:9002"
- "9003:9003"
stdin_open: true Turn on standard input to accept external input
tty: true
networks:
- backend
restart: always Set the container exit restart policy to always restart
etcd: Create a custom container name
build:
context: ./etcd # specify the Dockerfile file to use for the build
environment:
- TZ=${TZ}
- ALLOW_NONE_AUTHENTICATION=yes
ports: Set port mapping
- "${ETCD_PORT}:2379"
networks:
- backend
restart: always
mysql:
build:
context: ./mysql
environment:
- TZ=${TZ}
- MYSQL_USER=${MYSQL_USERNAME} Mysql > set user name for Mysql
- MYSQL_PASSWORD=${MYSQL_PASSWORD} Mysql > set Mysql user password
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} Mysql root password
volumes:
- ${DATA_PATH_HOST}/mysql:/var/lib/mysql /var/lib/ Mysql/DATA_PATH_HOST /var/lib/ Mysql
ports:
- "${MYSQL_PORT}:3306" Set container 3306 port mapping to specify host port
networks:
- backend
restart: always
redis:
build:
context: ./redis
environment:
- TZ=${TZ}
volumes:
- ${DATA_PATH_HOST}/redis:/data Env to mount the host directory containing Redis data to /data
ports:
- "${REDIS_PORT}:6379" Set container 6379 port mapping to specify host port
networks:
- backend
restart: always
mysql-manage:
build:
context: ./mysql-manage
environment:
- TZ=${TZ}
- PMA_ARBITRARY=1
- MYSQL_USER=${MYSQL_MANAGE_USERNAME} Mysql > set user name to connect to Mysql server
- MYSQL_PASSWORD=${MYSQL_MANAGE_PASSWORD} Mysql server user password
- MYSQL_ROOT_PASSWORD=${MYSQL_MANAGE_ROOT_PASSWORD} Mysql server root password
- PMA_HOST=${MYSQL_MANAGE_CONNECT_HOST} Mysql > connect to host; Mysql > connect to host
- PMA_PORT=${MYSQL_MANAGE_CONNECT_PORT} Mysql > connect to Mysql server
ports:
- "${MYSQL_MANAGE_PORT}:80" Container 80 port mapping specifies the host port used by the host to access the visual Web
depends_on: # dependency container
- mysql Start the Mysql server container after it is started
networks:
- backend
restart: always
redis-manage:
build:
context: ./redis-manage
environment:
- TZ=${TZ}
- ADMIN_USER=${REDIS_MANAGE_USERNAME} Set user name for Redis visual management
- ADMIN_PASS=${REDIS_MANAGE_PASSWORD} # Set user password for Redis visual management
- REDIS_1_HOST=${REDIS_MANAGE_CONNECT_HOST} Redis host = Redis host = Redis host = Redis host
- REDIS_1_PORT=${REDIS_MANAGE_CONNECT_PORT} Set the Redis service port number for the connection
ports:
- "${REDIS_MANAGE_PORT}:80" Container 80 port mapping specifies the host port used by the host to access the visual Web
depends_on: # dependency container
- redis Start after the Redis service container is started
networks:
- backend
restart: always
prometheus:
build:
context: ./prometheus
environment:
- TZ=${TZ}
volumes:
- ./prometheus/prometheus.yml:/opt/bitnami/prometheus/conf/prometheus.yml Mount the Prometheus configuration file to the container
ports:
- "${PROMETHEUS_PORT}:9090" Container 9090 port mapping specifies the host port used by the host to access the visual Web
networks:
- backend
restart: always
grafana:
build:
context: ./grafana
environment:
- TZ=${TZ}
ports:
- "${GRAFANA_PORT}:3000" Container 3000 port mapping specifies the host port for the host to access the visual Web
networks:
- backend
restart: always
jaeger:
build:
context: ./jaeger
environment:
- TZ=${TZ}
ports:
- "${JAEGER_PORT}:16686" Set container 16686 port mapping to specify host ports for host access to the visual Web
networks:
- backend
restart: always
dtm:
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 Mount the DTM configuration file to the container
ports:
- "${DTM_HTTP_PORT}:36789"
- "${DTM_GRPC_PORT}:36790"
networks:
- backend
restart: always
Copy the code
2.4 Build and Run
- use
docker-compose
Command to build and start running our service container by executing the following command in the root directory:
$ docker-compose up -d
Copy the code
-
Container Under construction
-
in
Windows
The following figure shows the system container construction, please selectShare it
This will allowWindows
To the container directory. -
The container is running
2.5 Container Description
Container name | Exposure to port | The host address | instructions |
---|---|---|---|
golang | A 8000-8000 A 8001-8001 A 8002-8002 A 8003-8003 A 9000-9000 A 9001-9001 A 9002-9002 A 9003-9003 |
golang | Microservices are typically clustered in a production environment, with one microservice per server or one microservice per container. In order to facilitate the development and debugging, we willgolang Start all microservices in the container and assign them to listen to different port numbers to distinguish them.80: The starting port number we will use api service90: The starting port number we will use rpc service |
dtm | A 36789-36789 A 36790-36790 |
dtm | dtm 的 http The protocol andgrpc Protocol Service port number used for client interaction.In this project we are only in Docker Internal container access between the use, so also can not expose the port number to the host |
etcd | A 2379-2379 | etcd | Etcd http api Service port number for client interaction.In this project we are only in Docker Internal container access between the use, so also can not expose the port number to the host |
mysql | A 3306-3306 | mysql | Mysql Service default port number that the host can pass127.0.0.1:3306 Connect to the database |
redis | A 6379-6379 | redis | Redis Service default port number that the host can pass127.0.0.1:6379 Connect to the database |
mysql-manage | A 1000-80 | mysql-manage | phpMyAdmin web The service port number can be on the host127.0.0.1:1000 access |
redis-manage | A 2000-80 | redis-manage | phpRedisAdmin web The service port number can be on the host127.0.0.1:2000 access |
prometheus | A 3000-9090 | prometheus | Prometheus web The service port number can be on the host127.0.0.1:3000 access |
grafana | A 4000-3000 | grafana | Grafana web The service port number can be on the host127.0.0.1:4000 access |
jaeger | A 5000-16686 | jaeger | Jaeger web The service port number can be on the host127.0.0.1:5000 access |
2.6 Access Verification
-
Mysql
Access authentication -
Redis
Access authentication -
Prometheus
Access authentication -
Grafana
Access authentication -
Jaeger
Access authentication
The project address
Github.com/zeromicro/g…
Welcome to Go-Zero and star support us!
Wechat communication group
Pay attention to the public account of “micro-service Practice” and click on the exchange group to obtain the QR code of the community group. /[email protected]