使用golang修改配置文件

背景

每次在一个新环境独立部署后,如果是为了开发调试,都需要手动修改如下配置:

  1. java.json文件:开启swagger、开启api访问
  2. 开启不同服务的debug日志,开启远程端口调试

可以写一个脚本来修改这些配置,可用的语言有很多,比如shell、python、go等,这里使用go语言,也算是学习golang的一个小任务。

代码

修改配置源码

package main
 
import (
    "bufio"
    "fmt"
    "io/ioutil"
    "os"
    "strings"
 
    "github.com/spf13/viper"
)
 
const CONF_LOG_DEBUG = " -Dlogging.level.debug=debug"
const CONF_REMOTE_PORT = " -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address="
const LAST_CHAR = "\""
 
func main() {
    fmt.Println("start update conf ...")
 
    // 修改java.json文件
    updateJavaJsonMap := map[string]interface{}{
        "app.gateway.refer_check":  false,
        "app.swagger.enable":       true,
        "base.api_auth_white_path": "/**",
    }updateJavaJson("/data/app/titan-config", "java", "json", updateJavaJsonMap)
 
    // 修改不同服务的xxx.conf文件
    serverConfMap := map[string]string{
        "/data/app/titan-detect-srv/detect-srv.conf": "5012",
        "/data/app/titan-wisteria/wisteria.conf":   "5006",
    }
    updateServerConf(serverConfMap)
 
    fmt.Println("finish update conf ...")
}
 
/**
 * 修改java.json文件
 *
 * @param updateJavaJsonMap:需要更新的配置项。key=配置项的key,value=配置项的value
 */
func updateJavaJson(configPath string, configName string, configType string, updateJavaJsonMap map[string]interface{}) {
    viper.AddConfigPath(configPath)
    viper.SetConfigName(configName)
    viper.SetConfigType(configType)
 
    if err := viper.ReadInConfig(); err != nil {
        if _, ok := err.(viper.ConfigFileNotFoundError); ok {
            fmt.Println("找不到配置文件..")
        } else {
            fmt.Println("配置文件出错..")
        }
    }
 
    // kafka的配置,key是以.分割的,重新写入时,容易被分割成多个key,所以这里特别处理
    dealKafkaProperties()
 
    // 更新配置
    for updateKey, updateValue := range updateJavaJsonMap {
        viper.Set(updateKey, updateValue)
    }
 
    // 写入当前文件
    viper.WriteConfig()
}
 
/**
 * kafka的配置,key是以.分割的,重新写入时,容易被分割成多个key,所以这里特别处理
 */
func dealKafkaProperties() {
    var kafkaPropertiesMap map[string]string = make(map[string]string)
    kafkaPropertiesMap["sasl.jaas.config"] = "org.apache.kafka.common.security.plain.PlainLoginModule required \n username=\"qingteng\" \n password=\"${kafka.password}\";"
    kafkaPropertiesMap["sasl.mechanism"] = "PLAIN"
    kafkaPropertiesMap["security.protocol"] = "SASL_PLAINTEXT"
    viper.Set("kafka.properties", kafkaPropertiesMap)
}
 
/**
 * 修改不同服务的xxx.conf文件。修改内容包括:1、开启debug日志  2、增加远程调试端口
 *
 * @param serverConfMap:需要修改的服务配置。key=配置文件路径,value=远程调试端口号
 */
func updateServerConf(serverConfMap map[string]string) {
    for configPath, remotePort := range serverConfMap {
        modifySingleConf(configPath, remotePort)
    }
}
 
/**
 * 修改单个服务的xxx.conf文件
 *
 */
func modifySingleConf(configPath, remotePort string) {
    newContent := getConfContent(configPath, remotePort)
 
    // os.O_TRUNC清空文件重新写入
    file, err := os.OpenFile(configPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
    if err != nil {
        panic(err)
    }
 
    writer := bufio.NewWriter(file)
    writer.WriteString(newContent)
    writer.Flush()
}
 
/**
 * 读取.conf文件内容,并添加配置项
 */
func getConfContent(configPath, remotePort string) string {
    content, err := ioutil.ReadFile(configPath)
    if err != nil {
        panic(err)
    }
    contentStr := string(content)
 
    var appendStr string = ""
    if !strings.Contains(contentStr, CONF_LOG_DEBUG) {
        appendStr += CONF_LOG_DEBUG
    }
 
    if !strings.Contains(contentStr, remotePort) {
        appendStr += CONF_REMOTE_PORT + remotePort
    }
 
    if len(appendStr) == 0 {
        return contentStr
    }
 
    // 计算最后一个引号的位置,用于后面去掉引号及引号之后的字符
    lastIndex := strings.LastIndex(contentStr, LAST_CHAR)
    deleteStrLen := len(contentStr) - lastIndex
 
    // 去掉引号之后的字符
    contentStr1 := contentStr[:len(contentStr)-deleteStrLen]
 
    // 追加字符串
    newContent := contentStr1 + appendStr + LAST_CHAR
 
    return newContent
}

说明:

  • 示例中的java.json文件,配置项不是固定的,数据格式是随意变化的。
  • 如果希望 更新/新增 更多的 java.json 文件中的配置,在 updateJavaJsonMap 中直接添加即可。
  • 这里默认只会修改conf文件中,wisteria 和 detect-srv 两个服务的配置,如果需要修改其他服务的,需要在 serverConfMap 中加上对应配置即可。

本地调试:

  • 如果想在本地修改调试,需要先配置好GOPATH,然后安装 viper 组件。安装命令:go get -u github.com/spf13/viper
  • 创建一个go文件(比如:update_conf.go),拷贝上面的源码后,执行 go run update_conf.go 即可运行(注意修改为本地的配置文件路径)。

服务器上运行:

  • 创建一个go文件(比如:update_conf.go),拷贝上面的源码后,执行 go build update_conf.go 命令,会在同级目录下生成一个二进制的可执行文件 update_conf,然后拷贝到对应的服务器上,执行 ./update_conf 即可。
  • 修改配置文件后,需要自行重启对应的服务。

 

重启服务源码

package main
 
import (
    "fmt"
    "os/exec"
)
 
const DEFAULT_OPT string = "Y"
 
/**
 * linux命令
 */
func main() {
    restart()
}
 
/**
 * 重启服务
 */
func restart() {
    restartService("detect-srv", "/data/app/titan-detect-srv/init.d/detect-srv")
    restartService("wisteria", "/data/app/titan-wisteria/init.d/wisteria")
    restartService("gateway", "/data/app/titan-gateway/init.d/gateway")
}
 
/**
 * 重启服务
 *
 * @serviceName 服务名称
 * @restartPath 重启脚本路径
 */
func restartService(serviceName, restartPath string) {
    var result string
    fmt.Printf("restart %s [Y/N]? default is Y\n", serviceName)
    fmt.Print("Enter [Y/N]: ")
    fmt.Scanln(&result)
 
    if len(result) == 0 {
        result = DEFAULT_OPT
    }
 
    if result == DEFAULT_OPT {
        fmt.Printf("start restart %s...\n", serviceName)
        doExecCmd(restartPath, "restart")
    }
}
 
/**
 * 执行操作
 */
func doExecCmd(name string, operate string) {
    cmd := exec.Command(name, operate)
 
    var output []byte
    var err error
    if output, err = cmd.CombinedOutput(); err != nil {
        fmt.Println("error is :", err)
        return
    }
 
    // 打印输出结果
    fmt.Println(string(output))
}

说明:这里只配置了重启detect-srv、wisteria、gateway服务,如果需要重启其它服务,可自行添加。

 

posted @ 2022-11-02 09:30  仅此而已-远方  阅读(1001)  评论(0编辑  收藏  举报