Take you ten days to easily handle the Go micro service series

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:

  1. Environment construction (this article)
  2. Service splitting
  3. User services
  4. Product service
  5. Order service
  6. Payment services
  7. RPC service Auth authentication
  8. Service monitoring
  9. Link tracking
  10. 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.

serviceBased mirroring
DTMyedf/dtm
Etcdbitnami/etcd
Mysqlmysql:5.7
Redisredis:5.0
Mysql Managephpmyadmin/phpmyadmin
Redis Manageerikdubbelboer/phpredisadmin
Prometheusbitnami/prometheus
Grafanagrafana/grafana
Jaegerjaegertracing/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 nameExposed porthost addressexplain
golang8000:8000
8001:8001
8002:8002
8003:8003
9000:9000
9001:9001
9002:9002
9003:9003
golangIn 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
dtm36789:36789
36790:36790
dtmThe 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
etcd2379:2379etcdEtcd 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
mysql3306:3306mysqlThe default port number of Mysql service. The host can connect to the database through 127.0.0.1:3306
redis6379:6379redisThe default port number of Redis service. The host can connect to the database through 127.0.0.1:6379
mysql-manage1000:80mysql-managephpMyAdmin web service port number, which can be accessed on the host machine 127.0.0.1:1000
redis-manage2000:80redis-manageThe host number of the web service is redisadmin 1.0.0, and the host number is redisadmin 1.0
prometheus3000:9090prometheusPrometheus web service port number, which can be accessed on the host machine 127.0.0.1:3000
grafana4000:3000grafanaGrafana web service port number, which can be accessed on the host 127.0.0.1:4000
jaeger5000:16686jaegerJaeger 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.

Keywords: Go Web Development rpc Microservices go-zero

Added by robsgaming on Tue, 15 Feb 2022 05:26:15 +0200