At the beginning of this article, we will publish a series of articles to show you a go zero micro service example in detail. The whole series is divided into ten articles, and the directory structure is as follows:
- Environment construction (this article)
- Service splitting
- User services
- Product service
- Order service
- Payment services
- RPC service Auth authentication
- Service monitoring
- Link tracking
- Distributed transaction
Through this series, we hope to take you to quickly develop a mall system by using the Docker environment and go zero on the machine, so that you can quickly start micro services.
Complete sample code: https://github.com/nivin-studio/go-zero-mall
1 environmental requirements
- Golang 1.15+
- Etcd
- Redis
- Mysql
- Prometheus
- Grafana
- Jaeger
- DTM
2. Construction of docker local development environment
In order to facilitate development and debugging, we use Docker to build a local development environment. For Windows and macOS systems, you can download Docker Desktop for installation. For specific download and installation methods, you can search relevant tutorials by yourself.
Here, we use Docker Compose to organize and manage our containers, and create the following directories:
gonivinck ├── dtm # DTM distributed transaction manager │ ├── config.yml # DTM profile │ └── Dockerfile ├── etcd # Etcd service registration discovery │ └── Dockerfile ├── golang # Golang running environment │ └── Dockerfile ├── grafana # Grafana visual data monitoring │ └── Dockerfile ├── jaeger # Jaeger link tracking │ └── Dockerfile ├── mysql # Mysql service │ └── Dockerfile ├── mysql-manage # Mysql visual management │ └── Dockerfile ├── prometheus # Prometheus service monitoring │ ├── Dockerfile │ └── prometheus.yml # Prometheus profile ├── redis # Redis service │ └── Dockerfile ├── redis-manage # Redis visual management │ └── Dockerfile ├── .env # env configuration └── docker-compose.yml
2.1 writing Dockerfile
In the micro service of go zero, grpc is used for the communication between services, and the writing of grpc requires protocol and the plug-in protocol Gen go translated into rpc stub code of go language.
In order to improve development efficiency, reduce the error rate of code and shorten the workload of business development, go zero also provides goctl code generation tool.
Therefore, we need to install protoc, protoc Gen go and goctl into the container of golang in advance for subsequent use.
Therefore, the Dockerfile code of the golang container is as follows:
FROM golang:1.17 LABEL maintainer="Ving <ving@nivin.cn>" ENV GOPROXY https://goproxy.cn,direct # Install the necessary software packages and dependent packages 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 # Install goctl USER root RUN GOPROXY=https://goproxy.cn/,direct go install github.com/tal-tech/go-zero/tools/goctl@cli # Install protoc ol 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 # Install protocol Gen go USER root RUN go get -u github.com/golang/protobuf/protoc-gen-go@v1.4.0 # $GOPATH/bin added to environment variable ENV PATH $GOPATH/bin:$PATH # Clean up garbage USER root RUN apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ rm /var/log/lastlog /var/log/faillog # Set working directory WORKDIR /usr/src/code EXPOSE 8000 EXPOSE 8001 EXPOSE 8002 EXPOSE 8003 EXPOSE 9000 EXPOSE 9001 EXPOSE 9002 EXPOSE 9003
Other service containers dockerfiles do not need special processing, but are based on existing images.
service | Based mirroring |
---|---|
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 preparation env profile
# Set time zone TZ=Asia/Shanghai # Set network mode NETWORKS_DRIVER=bridge # PATHS ########################################## # Directory path of code storage on host CODE_PATH_HOST=./code # The path where the MySQL host data is stored DATA_PATH_HOST=./data # MYSQL ########################################## # The Mysql service maps the port number of the host, which can be accessed at the host 127.0.0.1:3306 MYSQL_PORT=3306 MYSQL_USERNAME=admin MYSQL_PASSWORD=123456 MYSQL_ROOT_PASSWORD=123456 # Mysql visual management user name, the same as MYSQL_USERNAME MYSQL_MANAGE_USERNAME=admin # Mysql visual management user password, the same as MYSQL_PASSWORD MYSQL_MANAGE_PASSWORD=123456 # Mysql visual management root user password, the same as MYSQL_ROOT_PASSWORD MYSQL_MANAGE_ROOT_PASSWORD=123456 # Mysql service address MYSQL_MANAGE_CONNECT_HOST=mysql # Mysql service port number MYSQL_MANAGE_CONNECT_PORT=3306 # Mysql visual management maps the host port number, which can be accessed in the host 127.0.0.1:1000 MYSQL_MANAGE_PORT=1000 # REDIS ########################################## # Redis service maps the port number of the host, which can be accessed at 127.0.0.1:6379 of the host REDIS_PORT=6379 # Redis visual management user name REDIS_MANAGE_USERNAME=admin # Redis visual management user password REDIS_MANAGE_PASSWORD=123456 # Redis service address REDIS_MANAGE_CONNECT_HOST=redis # Redis service port number REDIS_MANAGE_CONNECT_PORT=6379 # Redis visual management maps the host port number, which can be accessed in the host 127.0.0.1:2000 REDIS_MANAGE_PORT=2000 # ETCD ########################################### # The Etcd service maps the port number of the host, which can be accessed at the host 127.0.0.1:2379 ETCD_PORT=2379 # PROMETHEUS ##################################### # The Prometheus service maps the port number of the host, which can be accessed at the host 127.0.0.1:3000 PROMETHEUS_PORT=3000 # GRAFANA ######################################## # The Grafana service maps the port number of the host, which can be accessed at the host 127.0.0.1:4000 GRAFANA_PORT=4000 # JAEGER ######################################### # Jaeger service maps the port number of the host, which can be accessed at 127.0.0.1:5000 of the host JAEGER_PORT=5000 # DTM ######################################### # DTM HTTP protocol port number DTM_HTTP_PORT=36789 # DTM gRPC protocol port number DTM_GRPC_PORT=36790
2.3 write docker compose YML profile
version: '3.5' # network configuration networks: backend: driver: ${NETWORKS_DRIVER} # Service container configuration services: golang: # Custom container name build: context: ./golang # Specifies the Dockerfile file used for the build environment: # Setting environment variables - TZ=${TZ} volumes: # Set mount directory - ${CODE_PATH_HOST}:/usr/src/code # quote. Code in env configuration_ PATH_ Host variable, mount the directory where the code is stored on the host to the / usr/src/code directory 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 # Open standard input to accept external input tty: true networks: - backend restart: always # Specifies that the restart policy after the container exits is always restart etcd: # Custom container name build: context: ./etcd # Specifies the Dockerfile file used for the build environment: - TZ=${TZ} - ALLOW_NONE_AUTHENTICATION=yes - ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379 ports: # Set port mapping - "${ETCD_PORT}:2379" networks: - backend restart: always mysql: build: context: ./mysql environment: - TZ=${TZ} - MYSQL_USER=${MYSQL_USERNAME} # Set Mysql user name - MYSQL_PASSWORD=${MYSQL_PASSWORD} # Set Mysql user password - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} # Set Mysql root user password volumes: - ${DATA_PATH_HOST}/mysql:/var/lib/mysql # quote. Data in env configuration_ PATH_ Host variable, mount the directory where Mysql data is stored on the host to the / var/lib/mysql directory in the container ports: - "${MYSQL_PORT}:3306" # Set container 3306 port mapping to specify the host port networks: - backend restart: always redis: build: context: ./redis environment: - TZ=${TZ} volumes: - ${DATA_PATH_HOST}/redis:/data # quote. Data in env configuration_ PATH_ Host variable: mount the directory where Redis data is stored on the host to the / data directory in the container 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} # Set the Mysql service user name of the connection - MYSQL_PASSWORD=${MYSQL_MANAGE_PASSWORD} # Set the password of the connected Mysql service user - MYSQL_ROOT_PASSWORD=${MYSQL_MANAGE_ROOT_PASSWORD} # Set the root password of the connected Mysql service - PMA_HOST=${MYSQL_MANAGE_CONNECT_HOST} # Set the connected Mysql service host, which can be the name of the Mysql service container or the ip address of the Mysql service container - PMA_PORT=${MYSQL_MANAGE_CONNECT_PORT} # Set the Mysql service port number of the connection ports: - "${MYSQL_MANAGE_PORT}:80" # Set the container 80 port mapping to specify the host port for the host to access the visual web depends_on: # Dependent container - mysql # Start after the Mysql service container starts networks: - backend restart: always redis-manage: build: context: ./redis-manage environment: - TZ=${TZ} - ADMIN_USER=${REDIS_MANAGE_USERNAME} # Set the user name of Redis visual management - ADMIN_PASS=${REDIS_MANAGE_PASSWORD} # Set user password for Redis visual management - REDIS_1_HOST=${REDIS_MANAGE_CONNECT_HOST} # Set the connected Redis service host, which can be the name of the Redis service container or the ip address of the Redis service container - REDIS_1_PORT=${REDIS_MANAGE_CONNECT_PORT} # Set the connected Redis service port number ports: - "${REDIS_MANAGE_PORT}:80" # Set the container 80 port mapping to specify the host port for the host to access the visual web depends_on: # Dependent 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 into the container ports: - "${PROMETHEUS_PORT}:9090" # Set the container 9090 port mapping to specify the host port for the host to access the visual web networks: - backend restart: always grafana: build: context: ./grafana environment: - TZ=${TZ} ports: - "${GRAFANA_PORT}:3000" # Set the container 3000 port mapping to specify 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 the container 16686 port mapping to specify the host port for the host to access 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 into the container ports: - "${DTM_HTTP_PORT}:36789" - "${DTM_GRPC_PORT}:36790" networks: - backend restart: always
2.4 construction and operation
- Use the docker compose command to build and start our service container. Execute the following commands in the root directory:
$ docker-compose up -d
- Container building
- In the Windows system container construction, as shown in the figure below, please select Share it, which will allow the file directory of Windows to be mounted in the container directory.
Container started running
2.5 vessel description
Container name | Exposed port | host address | explain |
---|---|---|---|
golang | 8000:8000 8001:8001 8002:8002 8003:8003 9000:9000 9001:9001 9002:9002 9003:9003 | golang | In the production environment, microservices are generally deployed in clusters. One microservice may be a server, or one microservice may be a container. In order to facilitate development and debugging, we will start all microservices in the golang container and assign them different port numbers to listen to. 80: the port number at the beginning will be used for api service 90: the port number at the beginning will be used for rpc service |
dtm | 36789:36789 36790:36790 | dtm | The http protocol and grpc protocol service port number of dtm are used for client interaction. In this project, we only access and use between Docker internal containers, so we can also not expose the port number to the host |
etcd | 2379:2379 | etcd | Etcd http api service port number, which is used for client interaction. In this project, we only access and use between Docker internal containers, so we can also not expose the port number to the host |
mysql | 3306:3306 | mysql | The default port number of Mysql service. The host can connect to the database through 127.0.0.1:3306 |
redis | 6379:6379 | redis | The default port number of Redis service. The host can connect to the database through 127.0.0.1:6379 |
mysql-manage | 1000:80 | mysql-manage | phpMyAdmin web service port number, which can be accessed on the host machine 127.0.0.1:1000 |
redis-manage | 2000:80 | redis-manage | The host number of the web service is redisadmin 1.0.0, and the host number is redisadmin 1.0 |
prometheus | 3000:9090 | prometheus | Prometheus web service port number, which can be accessed on the host machine 127.0.0.1:3000 |
grafana | 4000:3000 | grafana | Grafana web service port number, which can be accessed on the host 127.0.0.1:4000 |
jaeger | 5000:16686 | jaeger | Jaeger web service port number, which can be accessed on the host machine 127.0.0.1:5000 |
2.6 access verification
- Mysql access verification
- Redis access verification
- Prometheus access authentication
- Grafana access authentication
- Jaeger access verification
Project address
https://github.com/zeromicro/go-zero
Welcome to go zero and star support us!
Wechat communication group
Focus on the "micro service practice" official account and click on the exchange group to get the community community's two-dimensional code.