go项目多环境配置

news2024/9/22 20:49:10

1.java项目配置加载最佳实践

在 Spring Boot 项目中,配置文件的加载和管理是开发过程中不可或缺的一部分。Spring Boot 提供了一套灵活且强大的机制来加载配置文件,使得开发者能够根据不同的环境和需求轻松地管理配置。当多个位置存在相同的配置文件时,springboot会先加载优先级高的配置数据。

springboot加载的逻辑比较复杂,简化版的生产模式大致会以下面的思路:

  1. 对于应用程序本身的内部配置参数,不希望运维同学修改,例如关于spring本身的参数,这类配置统一放在application.xml或application.yml
    spring:
      profiles:
        active: dev
      servlet:
        multipart:
          max-file-size: 50MB
          max-request-size: 50MB
      main:
        banner-mode: off
      ##缓存
      cache:
        type: REDIS
        redis:
          timeToLive: 3600s
          cacheNullValues: true
  2. 在本地开发环境,通过配置spring变量,例如spring.profiles.active=dev,启用多环境配置,读取java项目resources目录下的pplication-dev. yml文件
  3. 在生产环境,如果运维希望覆盖某些配置,例如各种中间件(mysql,s3,redis等等)。则在可执行jar包同级目录下新建一个文件,例如application-prod. yml,并在启动脚本里显式申明 --spring.profiles.active=prod,启用环境变量

     nohup  java  $JVM_ARGS  -jar $jarName  --spring.profiles.active=prod  >  output.txt 2>&1  &

2.Go模仿springboot配置加载策略 

2.1.go项目多环境配置目标

在Go项目,我们也来模仿springboot的配置加载策略,实现以下的效果:

  1. 优先读default.yml文件,应用程序内部配置,项目打包成二进制可执行文件也会嵌入该配置
  2. 在开发环境,若环境变量为xxx,则读取config-xxx.yml(环境变量默认为dev) 
  3. 在生产环境(打包成二进制可执行文件),若环境变量为yyy,则读取config-yyy.yml(环境变量默认为dev)

2.2.使用viper加载配置

在 Go 项目中,Viper 是一个流行的库,用于处理配置文件。它支持多种格式的配置文件,包括 JSON、TOML、YAML 等,并且可以从不同的来源加载配置,如文件、环境变量、命令行参数等。Viper 也支持配置文件的热重载,这意味着在不重启应用程序的情况下,可以重新加载配置文件的更改。

安装命令: go get github.com/spf13/viper

假设我们有一个配置结构体,存储mysql的路径,以及绑定的socket服务地址,如下:

type Config struct {
	DbUrl     string
	ServerUrl string
}

在项目工程新建一个目录,叫做config,并新建一个default.yml的文件,文件内容

db:
  url: root:123456@tcp(localhost:3306)/game_user?charset=utf8mb4&parseTime=True&loc=Local

server:
  addr: 127.0.0.1:9090

 使用viper进行加载,相关代码如下:

    v := viper.New()
	// 设置配置文件名称(不包括扩展名)
	v.SetConfigName("default") // 配置文件名称(不包括扩展名)
	// 设置配置文件类型
	v.SetConfigType("yml")
	// 添加配置文件搜索路径
	v.AddConfigPath("./config")         
	// 读取配置文件
	if err := v.ReadInConfig(); err != nil {
		fmt.Printf("Error reading config: %s\n", err)
		return
	}
    ServerConfig = Config{
		DbUrl:     v.GetString("db.url"),
		ServerUrl: v.GetString("server.addr"),
	}
	fmt.Println("dbUrl", ServerConfig.DbUrl)
	fmt.Println("serverAddr", ServerConfig.ServerUrl)

在本地开发环境,程序运行正常,然而,当程序打包成二进制程序再执行,会报错表示找不到配置文件

这是因为,go build默认只会编译.go文件而不会处理其余静态资源,解决方案,可以引入go-bindata,将配置文件转化为go代码。从 Go 1.16 开始,也可以使用 embed 包将配置文件嵌入到二进制文件中。幸运的是,viper跟embed包搭配起来非常方便。

//go:embed default.yml
var configFS embed.FS

v := viper.New()
v.SetConfigType("yml")
f, err := configFS.Open("default.yml")
if err != nil {
	panic(fmt.Errorf("failed to open config file: %w", err))
}
defer f.Close()
// 从 io.Reader 读取配置
if err := v.ReadConfig(f); err != nil {
	panic(fmt.Errorf("failed to read config: %w", err))
}

根据环境变量读取对应的配置文件,覆盖同名参数

下面实现使用多环境配置,例如config-dev.yml,覆盖同名参数。在config目录下新建一个文件config-dev.yml,编辑内容

server:
  addr: 127.0.0.1:9091

追加代码,如下:

    // 允许 Viper 读取环境变量
	v.AutomaticEnv()
	replacer := strings.NewReplacer(".", "_")
	v.SetEnvKeyReplacer(replacer)

	// 获取环境变量,确定要加载的配置文件
	env := os.Getenv("ENV")
	if env == "" {
		env = "dev"
	}
	v.SetConfigName("config-" + env)
	// ./config路径在开发及部署环境均适用
	v.AddConfigPath("./config")
	// 再次读取配置文件,这次是根据环境变量,使用合并配置的方法确保旧配置被替换
	if err := v.MergeInConfig(); err != nil {
		panic(fmt.Errorf("failed to read config: %w", err))
	}

这里的代码  v.AddConfigPath("./config") 非常关键,它确保了无论是在开发环境还是生产环境,都能加载到对应的多环境配置文件。

在开发环境,由于main.go启动入口与config目录在同一级,且参数里的路径是相应于main函数,而不是代码所在的文件,开发环境加载成功。

在生产环境,我们只需在可执行程序,例如myapp.exe同级目录新建一个config目录,目录下添加一个config-prod.yml即可。

完整的代码如下,去掉注释,空行的话,也就区区50行左右,可以说,viper非常牛逼

package config

import (
	"embed"
	"fmt"
	"github.com/spf13/viper"
	"os"
	"strings"
)

type Config struct {
	DbUrl     string
	ServerUrl string
}

//go:embed default.yml
var configFS embed.FS

var (
	ServerConfig Config
)

// 多环境配置读取规则:
// 加载顺序: default -> 根据开发环境或者部署环境读取相应子目录config/config-env文件
// 先加载的配置会被后加载的同名配置所替换!!!!
// 1.优先读default.yml文件,应用程序内部配置,项目打包成二进制可执行文件也会嵌入该配置
// 2.在开发环境,若环境变量为xxx,则读取config-xxx.yml(环境变量默认为dev)
// 3.在部署环境(打包成二进制可执行文件),若环境变量为yyy,则读取config-yyy.yml(环境变量默认为dev)
func init() {
	// 创建 Viper 实例
	v := viper.New()
	v.SetConfigType("yml")
	// 打包后的二进制文件也要
	f, err := configFS.Open("default.yml")
	if err != nil {
		panic(fmt.Errorf("failed to open config file: %w", err))
	}
	defer f.Close()
	// 从 io.Reader 读取配置
	if err := v.ReadConfig(f); err != nil {
		panic(fmt.Errorf("failed to read config: %w", err))
	}

	// 允许 Viper 读取环境变量
	v.AutomaticEnv()
	replacer := strings.NewReplacer(".", "_")
	v.SetEnvKeyReplacer(replacer)

	// 获取环境变量,确定要加载的配置文件
	env := os.Getenv("ENV")
	if env == "" {
		env = "dev"
	}
	v.SetConfigName("config-" + env)
	// ./config路径在开发及部署环境均适用
	v.AddConfigPath("./config")
	// 再次读取配置文件,这次是根据环境变量,使用合并配置的方法确保旧配置被替换
	if err := v.MergeInConfig(); err != nil {
		panic(fmt.Errorf("failed to read config: %w", err))
	}

	ServerConfig = Config{
		DbUrl:     v.GetString("db.url"),
		ServerUrl: v.GetString("server.addr"),
	}
	fmt.Println("dbUrl", ServerConfig.DbUrl)
	fmt.Println("serverAddr", ServerConfig.ServerUrl)
}

 完整代码请移步:

--> go游戏服务器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2155860.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python语法进阶之路

一、Python基础 1.1 注释 定义和作用 对代码解释说明,增强可读性 单行注释 # 多行注释 """ 这是一个多行注释 """ 1.2 变量及变量类型 定义和作用 计算机目的是计算,编程是为了更方便计算,计算对象就是…

vue循环渲染动态展示内容案例(“更多”按钮功能)

当我们在网页浏览时,常常会有以下情况:要展示的内容太多,但展示空间有限,比如我们要在页面的一部分空间中展示较多的内容放不下,通常会有两种解决方式:分页,“更多”按钮。 今天我们的案例用于…

mybatis 配置文件完成增删改查(二):根据条件查询一个

文章目录 参数占位符#{}:会将其替换为? ——为了防止sql注入${}:会将其替换为实际接收到的数据,拼sql ——无法防止sql注入 查询一个sql特殊字符的处理 参数占位符 #{}:会将其替换为? ——为了防止sql注入 ${}:会将其替换为实际接收到的数据…

Java继承教程!(o|o)

Java 继承 Java面向对象设计 - Java继承 子类可以从超类继承。超类也称为基类或父类。子类也称为派生类或子类。 从另一个类继承一个类非常简单。我们在子类的类声明中使用关键字extends,后跟超类名称。 Java不支持多重继承的实现。 Java中的类不能有多个超类。…

Linux-gcc/g++

系列文章目录 C语言中的编译和链接 文章目录 系列文章目录一、编译过程gcc如何完成过程在这里涉及到一个重要的概念:函数库 二、动态库、静态库2.1 函数库一般分为静态库和动态库两种。 三、gcc选项gcc选项记忆 一、编译过程 具体过程在这一片c语言文章中讲解过:C语言中的编…

shardingjdbc分库分表原理

一 Mysql的瓶颈 二 解决方案 三 hash环算法 四 雪花算法

CCF csp认证 小白必看

c支持到C17(还是更高?);所以学一些封装好的函数功能是必要的---比如STL里的函数; 因为可携带纸质资料,建议打印带入,需要时可翻阅。 【题目概述:】 0-devc环境配置 配置好你常用的编译版本: 想要调试记得开启下选…

分布式系统的CAP原理

CAP 理论的起源 CAP 理论起源于 2000 年,由加州大学伯克利分校的 Eric Brewer 教授在分布式计算原理研讨会(PODC)上提出,因此 CAP 定理又被称作布鲁尔定理(Brewer’s Theorem)。2002 年,麻省理…

「OC」引用计数(一)

iOS学习 前言自动引用计数引用计数引用计数的思考方式自己生成的对象,自己持有非自己生成的对象,自己也能持有不再需要自己持有的对象时释放无法释放非自己持有的对象 总结 前言 在学习oc时对引用计数略有了解,现在进行系统的学习总结。 自动…

力扣 无重复字符的最长子串

无重复字符的最长子串 https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/ 题目描述 题目分析 寻找无重复字符子串,首先要求是子串,然后是无重复 子串可以用滑动窗口确定 问题在于如何确定无重复 如果用暴力枚…

Java笔试面试题AI答之设计模式(5)

文章目录 21. 简述Java什么是适配器模式 ?适配器模式的主要组成部分包括:适配器模式的实现方式主要有两种:适配器模式的优点:适配器模式的缺点:示例说明: 22. 请用Java代码实现适配器模式的案例 ? 21. 简述…

01 基础request

目录 类 WxRequest 的定义 静态属性 default 构造函数 constructor 方法 request HTTP 方法封装 创建 WxRequest 实例并导出 完整代码: 类 WxRequest 的定义 创建一个 WxRequest 类包含一个静态属性 default 和几个方法,用于处理网络请求。 静态…

Kotlin编程全攻略:从基础到实战项目的系统学习资料

Kotlin作为一种现代、简洁的编程语言,正逐渐成为Android开发的新宠。本文将为您介绍一套全面的Kotlin学习资料,包括学习大纲、PDF文档、源代码以及配套视频教程,帮助您从Kotlin的基础语法到实战项目开发,系统地提升您的编程技能。…

jetlinks物联网平台学习2(加盐算法登陆)

加盐算法 加盐算法加密验证密码是否正确 对于传统的MD5加密,比更传统的直接保存账号密码稍微安全一点。 md5加密是一种hash算法 比如对于123456来说,md5算法结果一定是e10adc3949ba59abbe56e057f20f883e 这个结果是固定的。于是有的人准备一张彩虹表 预先…

vscode 配置django

创建运行环境 使用pip安装Django:pip install django。 创建一个新的Django项目:django-admin startproject myproject。 打开VSCode,并在项目文件夹中打开终端。 在VSCode中安装Python扩展(如果尚未安装)。 在项…

SpringCloud-07 GateWay01 网关技术

Spring Cloud Gateway组件的核心是一系列的过滤器,通过这些过滤器可以将客户端发送的请求转发(路由)到对应的微服务。 Spring Cloud Gateway是加在整个微服务最前沿的防火墙和代理器,隐藏微服务结点IP端口信息,从而加强安全保护。Spring Clou…

基于SpringBoot+Vue的高校门禁管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 精品专栏:Java精选实战项目源码、Python精…

长亭WAF绕过测试

本文的Bypass WAF 的核心思想在于,一些 WAF 产品处于降低误报考虑,对用户上传文件的内 容不做匹配,直接放行 0、环境 环境:两台服务器,一台配置宝塔面板,一台配置长亭雷池WAF 思路主要围绕:m…

Python | Leetcode Python题解之第423题从英文中重建数字

题目: 题解: class Solution:def originalDigits(self, s: str) -> str:c Counter(s)cnt [0] * 10cnt[0] c["z"]cnt[2] c["w"]cnt[4] c["u"]cnt[6] c["x"]cnt[8] c["g"]cnt[3] c["h…

DAY78服务攻防-数据库安全RedisCouchDBH2database未授权访问CVE 漏洞

知识点: 1、数据库-Redis-未授权RCE&CVE 2、数据库-Couchdb-未授权RCE&CVE 3、数据库-H2database-未授权RCE&CVE 前置知识 1、复现环境:Vulfocus(官方在线的无法使用,需要自己本地搭建) 官方手册:https://fofapr…