Go微服务十一 Dockerfile ENTRYPOINT的使用 – 接受参数 读取nacos对应的配置文件

471 次浏览次阅读
没有评论

[微服务二] 这篇文章中,简单谈了从 nacos 读取服务配置文件。在 [微服务七] 这篇文章中,谈了制作 Dockerfile,通过 docker 将 Go 项目部署并运行在服务器上。在 [微服务八] 谈了使用 shell 脚本一键重新构建基于 Docker 的 Go 项目。

这篇文章中,实现动态获取 nacos 对应的配置文件。在 [微服务二] 这篇文章中,获取 nacos 配置文件,是在代码里面写的 nacos 的 ip、端口、组、DataID。这样写,如果要读取其他配置文件就要改动代码,及其的不方便。如果在项目目录写成配置文件,也行。但是每次打包项目上传服务器,配置文件也要上传。不太方便。>[微服务二]这篇文章中,获取 nacos 配置文件,是在代码里面写的 nacos 的 ip、端口、组、DataID。这样写,如果要读取其他配置文件就要改动代码,及其的不方便。如果在项目目录写成配置文件,也行。但是每次打包项目上传服务器,配置文件也要上传。不太方便。**

现在通过命令行参数传参的形式,根据传入的参数加载 nacos 上对应的配置文件。

首先要先理解 nacos 的使用。其次懂得使用 Go 语言中的 flag 包来解析命令行参数。获取命令行参数的形式有多种,这里只以 flag 包为例。

可以通 flag.String、flag.Int 等等获取对应类型的命令行参数。方法中包含三个字 name、value、usage 分别是参数名、参数值、参数说明. 如果忘记传什么参数可以通过 –help 查看参数说明。

这里以从 nacos 读取配置文件连接 mysql 和 redis 为例浅谈。

话不多说直接上 Demo

1. 打开 nacos 新建一个 demo.yaml 的配置文件

demo:
  datasource:
    dsn: root:root@tcp(127.0.0.1:3306)/test
    showSql: true
  redis:
    host: 127.0.0.1:6379
    password: root
    db: 0

2. Demo 程序

var (viperConfig *viper.Viper)

var (nacosIP2 = flag.String("ip", "127.0.0.1", "The nacos of ip address")
    port2    = flag.Int("p", 8848, "The nacos of port")
    group2   = flag.String("g", "demo", "The nacos of Group")
    cfg2     = flag.String("c", "demo.yml", "The path of configuration file")
)

type MysqlConfig struct {
    DbDsn   string
    ShowSQL bool
}

type RedisConfig struct {
    RedisAddr string
    Password  string
    RedisDb   int
}

func init() {flag.Parse()
}

func main() {ParseRemoteConfig(*nacosIP2, *port2, *group2, *cfg2)
    fmt.Println(GetMysqlConfig())
    fmt.Println(GetRedisConfig())
}

//ParseRemoteConfig 解析 nacos 配置文件
func ParseRemoteConfig(ip2 string, port2 int, group2 string, cfg2 string) *viper.Viper {viperConfig = viper.New()
    viperConfig.SetConfigType("yaml")
    viperConfig.SetConfigName(cfg2)
    serverConfigs := []constant.ServerConfig{{IpAddr: ip2, Port: uint64(port2)},
    }
    nacosClient, err := clients.NewConfigClient(vo.NacosClientParam{ClientConfig:  &constant.ClientConfig{TimeoutMs: 5000},
        ServerConfigs: serverConfigs,
    })
    if err != nil {logger.OmpLog.Fatal("nacos init failed :", err)
    }
    content, err := nacosClient.GetConfig(vo.ConfigParam{
        DataId: cfg2,
        Group:  group2,
    })
    if err != nil {logger.OmpLog.Fatal("read from nacos failed:" + content)
    }

    viperConfig.ReadConfig(strings.NewReader(content))
    return viperConfig
}

//GetMysqlConfig mysql 配置
func GetMysqlConfig() MysqlConfig {
    var mc MysqlConfig
    mc.DbDsn = viperConfig.GetString("demo.datasource.dsn")
    mc.ShowSQL = viperConfig.GetBool("demo.datasource.showSql")
    return mc
}

//GetRedisConfig redis 配置
func GetRedisConfig() RedisConfig {
    var rrc RedisConfig
    rrc.RedisAddr = viperConfig.GetString("demo.redis.host")
    rrc.Password = viperConfig.GetString("demo.redis.password")
    rrc.RedisDb = viperConfig.GetInt("demo.redis.db")
    return rrc
}

执行:

  go run main.go -ip 127.0.0.1 -p 8848 -g demo -c demo.yaml

  # 或者先编译 
  go build
  ./main -ip 127.0.0.1 -p 8848 -g demo -c demo.yaml

即可看到接受到的命令行参数和读取到的配置信息

Go 微服务十一  Dockerfile ENTRYPOINT 的使用 - 接受参数 读取 nacos 对应的配置文件

Go 微服务十一  Dockerfile ENTRYPOINT 的使用 - 接受参数 读取 nacos 对应的配置文件

3. 链接 mysql 和 redis, 修改 main 函数

ParseRemoteConfig(*nacosIP2, *port2, *group2, *cfg2)
    //  链接 mysql
    db, err := sql.Open("mysql", GetMysqlConfig().DbDsn)
    if err != nil {panic(err)
    }
    err = db.Ping()

    if err != nil {panic(err)
    }
    fmt.Println("mysql connect success...")

    // 链接 redis
    rdb := redis.NewClient(&redis.Options{Addr:     GetRedisConfig().RedisAddr,
        Password: GetRedisConfig().Password,
        DB:       GetRedisConfig().RedisDb,})
    ping := rdb.Ping()

    err = ping.Err()
    if err != nil {panic(err)
    }
    fmt.Println("redis connect success...")

执行:

  go run main.go -ip 127.0.0.1 -p 8848 -g demo -c demo.yaml

  # 或者先编译 
  go build
  ./main -ip 127.0.0.1 -p 8848 -g demo -c demo.yaml

即可看到数据库和 redis 连接成功

Go 微服务十一  Dockerfile ENTRYPOINT 的使用 - 接受参数 读取 nacos 对应的配置文件

四. 结合之前谈到的 Dockerfile 进行命令行传参

因为部署项目是结合 docker 进行部署的,不可能把代码上传到服务器,去执行 go run 或者 go build。采用 shell 脚本,一键完成自动服务重载。那么就要通过 dockerfile 来将上面的参数传递过来。

这个脚本采用 upx 来帮我们对 go 项目进行打包

#!/usr/bin/env bash
echo " 开始编译文件 "
buildFileName="main"
BuildTime=`date +'%Y.%m.%d.%H:%M:%S'`
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-w -s" -o ${buildFileName}
#go build -o main main.go
echo " 编译完成, 编译时间 ${BuildTime}"
echo " 开始压缩文件 "
upx -9 ${buildFileName}
echo " 完成压缩 "

Dcokerfile

FROM golang:1.17.2-alpine

# 设置工作目录
WORKDIR /root/demo

# 添加可执行文件
ADD ./main $WORKDIR

# 添加
ADD config /root/omp-go/omp-router/config
ADD log /root/omp-go/omp-router/log

# 声明服务端口
EXPOSE 9999

# 启动容器时运行的命令
ENTRYPOINT ["./demo", "-ip","127.0.0.1","-p","8848","-g","demo","-c","demo.yml"]

start.sh

#! /bin/bash

if [! -f 'main']; then
  echo 文件不存在! 待添加的安装包: 'main'
  exit
fi

echo "main-demo..."
sleep 3
docker stop main-demo

sleep 2
docker rm main-demo

docker rmi main-demo
echo ""

echo "main-demo packing..."
sleep 3
docker build -t main-demo .
echo ""

echo "main-demo running..."
sleep 3
docker run --name main-demo \
  -p 9804:9804 \
  -d main-demo \

docker logs -f main-demo | sed '/Started main-demoApplication/q'

echo ""

先进行打包,然后启动即可 …

正文完
 0
评论(没有评论)