學習筆記:帶你十天輕鬆搞定 Go 微服務系列(一)

zhaocrazy發表於2022-02-13

個人環境:
centos7.4
go.15.10
Docker version 19.03.13
部落格:帶你十天輕鬆搞定 Go 微服務系列(一) 學習筆記

一、建立目錄 mkdir 與 touch 命令

cd 目錄(你放專案的目錄)
mkdir gonivinck
cd gonivinck
mkdir dtm
cd dtm
touch config.yml
touch Dockerfile

其他目錄同上 返回上級目錄 cd ../

二、編寫 Dockerfile

不熟悉Dockerfile的點選這裡

golang 容器的Dockerfile` 程式碼如下:

#基於golang:1.17 操作
FROM golang:1.17

#宣告維護者
LABEL maintainer="Ving <ving@nivin.cn>"

#設定環境變數 代理配置
ENV GOPROXY https://goproxy.cn,direct

#安裝必要的軟體包和依賴包
#指定使用者root run就執行後面的命令
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/code

#宣告埠
EXPOSE 8000
EXPOSE 8001
EXPOSE 8002
EXPOSE 8003
EXPOSE 9000
EXPOSE 9001
EXPOSE 9002
EXPOSE 9003

其他服務容器 Dockerfile
例子:/gonivinck/dtm/Dockerfile 其他的依此類推

FROM yedf/dtm

LABEL maintainer="Ving <ving@nivin.cn>"

三、編寫 .env 配置檔案

為了讓環境執行 可以先直接複製部落格上的 後續再手打下 加深印象

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: always

  mysql:
    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: always

  redis:
    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: always

  mysql-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: always

  redis-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: always

  prometheus:
    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: always

  grafana:
    build:
      context: ./grafana
    environment:
      - TZ=${TZ}
    ports:
      - "${GRAFANA_PORT}:3000"                        # 設定容器3000埠對映指定宿主機埠,用於宿主機訪問視覺化web
    networks:
      - backend
    restart: always

  jaeger:
    build:
      context: ./jaeger
    environment:
      - TZ=${TZ}
    ports:
      - "${JAEGER_PORT}:16686"                        # 設定容器16686埠對映指定宿主機埠,用於宿主機訪問視覺化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 # 將 dtm 配置檔案掛載到容器裡
    ports:
      - "${DTM_HTTP_PORT}:36789"
      - "${DTM_GRPC_PORT}:36790"
    networks:
      - backend
    restart: always

四、編寫 docker-compose.yml 配置檔案

不熟悉docker-composer.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: always

  mysql:
    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: always

  redis:
    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: always

  mysql-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: always

  redis-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: always

  prometheus:
    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: always

  grafana:
    build:
      context: ./grafana
    environment:
      - TZ=${TZ}
    ports:
      - "${GRAFANA_PORT}:3000"                        # 設定容器3000埠對映指定宿主機埠,用於宿主機訪問視覺化web
    networks:
      - backend
    restart: always

  jaeger:
    build:
      context: ./jaeger
    environment:
      - TZ=${TZ}
    ports:
      - "${JAEGER_PORT}:16686"                        # 設定容器16686埠對映指定宿主機埠,用於宿主機訪問視覺化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 # 將 dtm 配置檔案掛載到容器裡
    ports:
      - "${DTM_HTTP_PORT}:36789"
      - "${DTM_GRPC_PORT}:36790"
    networks:
      - backend
    restart: always

五、構建執行

docker-compose up -d

bug 1

ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule:  (iptables failed: iptables --wait -t nat -I DOCKER -i br-dfbf6d743c13 -j RETURN: iptab            les: No chain/target/match by that name.
 (exit status 1))

解決:重啟docker即可 service docker restart

bug 2

debconf: delaying package configuration, since apt-utils is not installed

解決:可以安裝apt-utils,或忽略這個錯誤

bug 3 golang服務報錯

package github.com/tal-tech/go-zero/tools/goctl@cli: cannot use path@version syntax in GOPATH mode
ERROR: Service 'golang' failed to build : The command '/bin/sh -c GOPROXY=https://goproxy.cn/,direct go install github.com/tal-tech/go-zero/tools/goctl@cli' returned a non-zero code: 1

解決:我的錯誤是因為 from go 1.17 被我改成 from go 1.15 網上類似情況解決

bug 4 signal: killed 雲伺服器配置(1核2g)較低

go build github.com/zeromicro/ddl-parser/gen: /usr/local/go/pkg/tool/linux_amd64/compile: signal: killed
ERROR: Service 'golang' failed to build : The command '/bin/sh -c GOPROXY=https://goproxy.cn/,direct go install github.com/tal-tech/go-zero/tools/goctl@cli' returned a non-zero code: 1

解決:

  • 土豪:加錢直接升級雲伺服器配置
  • 屌絲:配置 swap 分割槽 參考

bug 4 埠被佔用

ERROR: for mysql  Cannot start service mysql: driver failed programming external connectivity on endpoint gonivinck_mysql_1 (aac3792c0966c870d1b350c5e61589df38bdd14eb0ba567da463f05c94c3a22d): Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already in use

ERROR: for redis  Cannot start service redis: driver failed programming external connectivity on endpoint gonivinck_redis_1 (f09a8ca17958070e81d93b7cfff9e8826b18a3f4261a990c599a8e7366d8abbc): Error starting userland proxy: listen tcp 0.0.0.0:6379: bind: address already in use

ERROR: for golang  Cannot start service golang: driver failed programming external connectivity on endpoint gonivinck_golang_1 (8430bb625604162ae64b5d2addadc9fb2b897cc8b6d87e3af5ff6ae6ca7496f2): Error starting userland proxy: listen tcp 0.0.0.0:9001: bind: address already in use
ERROR: Encountered errors while bringing up the project.

解決:
netstat -apn | grep 9001
netstat -apn | grep 3306
netstat -apn | grep 6379
找到程式 kill -9 pid 不行強行關掉宿主機佔用埠的服務

成功 我在我的雲伺服器啟動了
docker-compose up -d

gonivinck_etcd_1 is up-to-date
Starting gonivinck_golang_1 ...
gonivinck_prometheus_1 is up-to-date
gonivinck_grafana_1 is up-to-date
Starting gonivinck_mysql_1  ...
gonivinck_dtm_1 is up-to-date
gonivinck_jaeger_1 is up-to-date
Starting gonivinck_golang_1       ... done
Starting gonivinck_mysql_1  ... done
Creating gonivinck_mysql-manage_1 ... done

docker ps

學習筆記:帶你十天輕鬆搞定 Go 微服務系列(一)

本作品採用《CC 協議》,轉載必須註明作者和本文連結
滴水穿石,石破天驚----馬乂

相關文章