Go語言實戰 : API服務器 (4) 配置文件讀取及連接數據庫

讀取配置文件

1. 主函數中增加配置初始化入口

  1. 先導入viper包
import (..."github.com/spf13/pflag""github.com/spf13/viper""log")
  1. 在 main 函數中增加了 config.Init(*cfg) 調用,用來初始化配置,cfg 變量值從命令行 flag 傳入,可以傳值,比如 ./apiserver -c config.yaml,也可以為空,如果為空會默認讀取 conf/config.yaml。
	if err:=config.Init(*cfg) ;err != nil {panic(err)}
  1. 將相應的配置改成從配置文件config.yaml(配置內容如下)讀取,例如程序的端口號,ip地址,運行模式,
runmode: debug                 # 開發模式, debug, release, test
addr: :8080                  # HTTP綁定端口
name: apiserver              # API Server的名字
url: http://127.0.0.1:8080   # pingServer函數請求的API服務器的ip:port
max_ping_count: 10           # pingServer函數try的次數

完整代碼如下:

import (..."github.com/spf13/pflag""github.com/spf13/viper""log")
var (cfg = pflag.StringP("config", "c", "", "apiserver config file path.")
)
func main() {pflag.Parse()if err:=config.Init(*cfg) ;err != nil {panic(err)}// Create the Gin engine.g := gin.New()gin.SetMode(viper.GetString("runmode"))middlewares := []gin.HandlerFunc{}// Routes.router.Load(// Cores.g,// Middlwares.middlewares...,)// Ping the server to make sure the router is working.go func() {if err := pingServer(); err != nil {log.Fatal("The router has no response, or it might took too long to start up.", err)}log.Print("The router has been deployed successfully.")}()log.Printf("Start to listening the incoming requests on http address: %s", viper.GetString("addr"))log.Printf(http.ListenAndServe(viper.GetString("addr"), g).Error())
}

2. 解析配置的函數

  1. func Init(cfg string) 如果cfg不為空,加載指定配置文件,否則加載默認配置文件,并且調用監控配置文件的函數。
func Init(cfg string) error {c := Config {Name: cfg,}// 初始化配置文件if err := c.initConfig(); err != nil {return err}// 監控配置文件變化并熱加載程序c.watchConfig()return nil
}
  1. func (c *Config) watchConfig通過該函數的 viper 設置,可以使 viper 監控配置文件變更,如有變更則熱更新程序。所謂熱更新是指:可以不重啟 API 進程,使 API 加載最新配置項的值。
func (c *Config) watchConfig() {viper.WatchConfig()viper.OnConfigChange(func(e fsnotify.Event) {log.Printf("Config file changed: %s", e.Name)})
}
  1. func (c *Config) initConfig() error調用viper包提供的方法,讀取所需要的配置
func (c *Config) initConfig() error {if c.Name != "" {viper.SetConfigFile(c.Name) // 如果指定了配置文件,則解析指定的配置文件} else {viper.AddConfigPath("conf") // 如果沒有指定配置文件,則解析默認的配置文件viper.SetConfigName("config")}viper.SetConfigType("yaml") // 設置配置文件格式為YAMLviper.AutomaticEnv() // 讀取匹配的環境變量viper.SetEnvPrefix("APISERVER") // 讀取環境變量的前綴為APISERVERreplacer := strings.NewReplacer(".", "_") viper.SetEnvKeyReplacer(replacer)if err := viper.ReadInConfig(); err != nil { // viper解析配置文件return err}return nil
}

完整代碼如下:

package configimport ("log""strings""github.com/fsnotify/fsnotify""github.com/spf13/viper"
)type Config struct {Name string
}func Init(cfg string) error {c := Config {Name: cfg,}// 初始化配置文件if err := c.initConfig(); err != nil {return err}// 監控配置文件變化并熱加載程序c.watchConfig()return nil
}func (c *Config) initConfig() error {if c.Name != "" {viper.SetConfigFile(c.Name) // 如果指定了配置文件,則解析指定的配置文件} else {viper.AddConfigPath("conf") // 如果沒有指定配置文件,則解析默認的配置文件viper.SetConfigName("config")}viper.SetConfigType("yaml") // 設置配置文件格式為YAMLviper.AutomaticEnv() // 讀取匹配的環境變量viper.SetEnvPrefix("APISERVER") // 讀取環境變量的前綴為APISERVERreplacer := strings.NewReplacer(".", "_") viper.SetEnvKeyReplacer(replacer)if err := viper.ReadInConfig(); err != nil { // viper解析配置文件return err}return nil
}// 監控配置文件變化并熱加載程序
func (c *Config) watchConfig() {viper.WatchConfig()viper.OnConfigChange(func(e fsnotify.Event) {log.Printf("Config file changed: %s", e.Name)})
}

數據庫連接

1.ORM框架

apiserver 用的 ORM 是 GitHub 上 star 數最多的 gorm,相較于其他 ORM,它用起來更方便,更穩定,社區也更活躍。 gorm有如下特性:

  • 全功能 ORM (無限接近)
  • 關聯 (Has One, Has Many, Belongs To, Many To Many, 多態)
  • 鉤子 (在創建/保存/更新/刪除/查找之前或之后)
  • 預加載
  • 事務
  • 復合主鍵
  • SQL 生成器
  • 數據庫自動遷移
  • 自定義日志
  • 可擴展性, 可基于 GORM 回調編寫插件
  • 所有功能都被測試覆蓋
  • 開發者友好

2.建立數據連接

1.先配置文件中,配置數據庫相關參數

db:name: db_apiserveraddr: 127.0.0.1:3306username: rootpassword: root
docker_db:name: db_apiserveraddr: 127.0.0.1:3306username: rootpassword: root
  1. 創建數據庫連接結構體,并且初始化連接
type Database struct {Self *gorm.DBDocker *gorm.DB
}
func (db *Database) Init() {DB = &Database{Self:   GetSelfDB(),Docker: GetDockerDB(),}
}

3.根據用戶名密碼等參數,打開連接

func openDB(username,password,addr,name string) *gorm.DB  {config :=fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=%t&loc=%s",username,password,addr,name,true,//"Asia/Shanghai"),"Local")db, err := gorm.Open("mysql", config)if err!=nil{log.Printf("Database connection failed. Database name: %s", name)}setupDB(db)return db
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/391344.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391344.shtml
英文地址,請注明出處:http://en.pswp.cn/news/391344.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

方差偏差權衡_偏差偏差權衡:快速介紹

方差偏差權衡The bias-variance tradeoff is one of the most important but overlooked and misunderstood topics in ML. So, here we want to cover the topic in a simple and short way as possible.偏差-方差折衷是機器學習中最重要但被忽視和誤解的主題之一。 因此&…

win10 uwp 讓焦點在點擊在頁面空白處時回到textbox中

原文:win10 uwp 讓焦點在點擊在頁面空白處時回到textbox中在網上 有一個大神問我這樣的問題:在做UWP的項目,怎么能讓焦點在點擊在頁面空白處時回到textbox中? 雖然我的小伙伴認為他這是一個 xy 問題,但是我還是回答他這個問題。 首…

python:當文件中出現特定字符串時執行robot用例

#coding:utf-8 import os import datetime import timedef execute_rpt_db_full_effe_cainiao_city():flag Truewhile flag:# 判斷該文件是否存在# os.path.isfile("/home/ytospid/opt/docker/jsc_spider/jsc_spider/log/call_proc.log")# 存在則獲取昨天日期字符串…

MySQL分庫分表方案

1. MySQL分庫分表方案 1.1. 問題:1.2. 回答: 1.2.1. 最好的切分MySQL的方式就是:除非萬不得已,否則不要去干它。1.2.2. 你的SQL語句不再是聲明式的(declarative)1.2.3. 你招致了大量的網絡延時1.2.4. 你失去…

linux創建sudo用戶_Linux終極指南-創建Sudo用戶

linux創建sudo用戶sudo stands for either "superuser do" or "switch user do", and sudo users can execute commands with root/administrative permissions, even malicious ones. Be careful who you grant sudo permissions to – you are quite lit…

重學TCP協議(1) TCP/IP 網絡分層以及TCP協議概述

1. TCP/IP 網絡分層 TCP/IP協議模型(Transmission Control Protocol/Internet Protocol),包含了一系列構成互聯網基礎的網絡協議,是Internet的核心協議,通過20多年的發展已日漸成熟,并被廣泛應用于局域網和…

分節符縮寫p_p值的縮寫是什么?

分節符縮寫pp是概率嗎? (Is p for probability?) Technically, p-value stands for probability value, but since all of statistics is all about dealing with probabilistic decision-making, that’s probably the least useful name we could give it.從技術…

Spring-----AOP-----事務

xml文件中&#xff1a; 手動處理事務&#xff1a; 設置數據源 <bean id"dataSource" class"com.mchange.v2.c3p0.ComboPooledDataSource"> <property name"driverClass" value"com.mysql.jdbc.Driver"></property…

[測試題]打地鼠

Description 小明聽說打地鼠是一件很好玩的游戲&#xff0c;于是他也開始打地鼠。地鼠只有一只&#xff0c;而且一共有N個洞&#xff0c;編號為1到N排成一排&#xff0c;兩邊是墻壁&#xff0c;小明當然不可能百分百打到&#xff0c;因為他不知道地鼠在哪個洞。小明只能在白天打…

在PHP服務器上使用JavaScript進行緩慢的Loris攻擊[及其預防措施!]

Forget the post for a minute, lets begin with what this title is about! This is a web security-based article which will get into the basics about how HTTP works. Well also look at a simple attack which exploits the way the HTTP protocol works.暫時忘掉這個帖…

三星為什么要賣芯片?手機干不過華為小米,半導體好掙錢!

據外媒DigiTimes報道&#xff0c;三星有意向其他手機廠商出售自家的Exynos芯片以擴大市場份額。知情人士透露&#xff0c;三星出售自家芯片旨在提高硅晶圓工廠的利用率&#xff0c;同時提高它們在全球手機處理器市場的份額&#xff0c;尤其是中端市場。 三星為什么要賣芯片&…

重學TCP協議(2) TCP 報文首部

1. TCP 報文首部 1.1 源端口和目標端口 每個TCP段都包含源端和目的端的端口號&#xff0c;用于尋找發端和收端應用進程。這兩個值加上IP首部中的源端IP地址和目的端IP地址唯一確定一個TCP連接 端口號分類 熟知端口號&#xff08;well-known port&#xff09;已登記的端口&am…

linux:vim中全選復制

全選&#xff08;高亮顯示&#xff09;&#xff1a;按esc后&#xff0c;然后ggvG或者ggVG 全部復制&#xff1a;按esc后&#xff0c;然后ggyG 全部刪除&#xff1a;按esc后&#xff0c;然后dG 解析&#xff1a; gg&#xff1a;是讓光標移到首行&#xff0c;在vim才有效&#xf…

機器學習 預測模型_使用機器學習模型預測心力衰竭的生存時間-第一部分

機器學習 預測模型數據科學 &#xff0c; 機器學習 (Data Science, Machine Learning) 前言 (Preface) Cardiovascular diseases are diseases of the heart and blood vessels and they typically include heart attacks, strokes, and heart failures [1]. According to the …

程序2:word count

本程序改變自&#xff1a;http://blog.csdn.net/zhixi1050/article/details/72718638 語言&#xff1a;C 編譯環境&#xff1a;visual studio 2015 運行環境&#xff1a;Win10 做出修改的地方&#xff1a;在原碼基礎上修改了記錄行數的功能&#xff0c;刪去了不完整行數的記錄&…

重學TCP協議(3) 端口號及MTU、MSS

1. 端口相關的命令 1.1 查看端口是否打開 使用 nc 和 telnet 這兩個命令可以非常方便的查看到對方端口是否打開或者網絡是否可達。如果對端端口沒有打開&#xff0c;使用 telnet 和 nc 命令會出現 “Connection refused” 錯誤 1.2 查看監聽端口的進程 使用 netstat sudo …

Diffie Hellman密鑰交換

In short, the Diffie Hellman is a widely used technique for securely sending a symmetric encryption key to another party. Before proceeding, let’s discuss why we’d want to use something like the Diffie Hellman in the first place. When transmitting data o…

高效能程序猿的修煉

下載地址&#xff1a;http://download.csdn.net/detail/xiaole0313/8931785 高效能程序猿的修煉 《高效能程序猿的修煉是人民郵電出版社出版的圖書。本書是coding horror博客中精華文章的集合。全書分為12章。涉及邁入職業門檻、高效能編程、應聘和招聘、團隊協作、高效工作環境…

Spring 中的 LocalSessionFactoryBean和LocalContainerEntityManagerFactoryBean

Spring和Hibernate整合的時候我們經常會有如下的配置代碼 1&#xff0c;非JPA支持的配置 <!-- 配置 Hibernate 的 SessionFactory 實例: 通過 Spring 提供的 LocalSessionFactoryBean 進行配置 --> <!-- FacotryBean 配置的時候返回的不是本身而是返回的FactoryBean 的…

如何通過建造餐廳來了解Scala差異

I understand that type variance is not fundamental to writing Scala code. Its been more or less a year since Ive been using Scala for my day-to-day job, and honestly, Ive never had to worry much about it. 我了解類型差異并不是編寫Scala代碼的基礎。 自從我在日…