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:

  1. Environment Building (This paper)
  2. Service split
  3. Customer service
  4. Product/service
  5. Order service
  6. Payment service
  7. Auth authentication for RPC service
  8. Service monitoring
  9. Link to track
  10. 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

  • Golang1.15 +
  • Etcd
  • Redis
  • Mysql
  • Prometheus
  • Grafana
  • Jaeger
  • DTM

2 DockerLocal 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.envThe 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.ymlThe 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

  • usedocker-composeCommand 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

  • inWindowsThe following figure shows the system container construction, please selectShare itThis will allowWindowsTo 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 willgolangStart all microservices in the container and assign them to listen to different port numbers to distinguish them.

80: The starting port number we will useapiservice

90: The starting port number we will userpcservice
dtm A 36789-36789

A 36790-36790
dtm dtmhttpThe protocol andgrpcProtocol Service port number used for client interaction.

In this project we are only inDockerInternal container access between the use, so also can not expose the port number to the host
etcd A 2379-2379 etcd Etcd http apiService port number for client interaction.

In this project we are only inDockerInternal container access between the use, so also can not expose the port number to the host
mysql A 3306-3306 mysql MysqlService default port number that the host can pass127.0.0.1:3306Connect to the database
redis A 6379-6379 redis RedisService default port number that the host can pass127.0.0.1:6379Connect to the database
mysql-manage A 1000-80 mysql-manage phpMyAdmin webThe service port number can be on the host127.0.0.1:1000access
redis-manage A 2000-80 redis-manage phpRedisAdmin webThe service port number can be on the host127.0.0.1:2000access
prometheus A 3000-9090 prometheus Prometheus webThe service port number can be on the host127.0.0.1:3000access
grafana A 4000-3000 grafana Grafana webThe service port number can be on the host127.0.0.1:4000access
jaeger A 5000-16686 jaeger Jaeger webThe service port number can be on the host127.0.0.1:5000access

2.6 Access Verification

  • MysqlAccess authentication

  • RedisAccess authentication

  • PrometheusAccess authentication

  • GrafanaAccess authentication

  • JaegerAccess 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]