欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用go連接clickhouse的實戰(zhàn)操作

 更新時間:2023年03月17日 09:54:11   作者:風靈動銘  
這篇文章主要給大家介紹了關(guān)于使用go連接clickhouse的實戰(zhàn)操作,文中通過實例代碼介紹的非常詳細,對大家學習或者使用go具有一定的參考學習價值,需要的朋友可以參考下

前言

近段時間業(yè)務在一個局點測試clickhouse,用java寫的代碼在環(huán)境上一直連接不上clickhouse服務,報錯信息也比較奇怪,No client available,研發(fā)查了一段時間沒查出來,讓運維這邊繼續(xù)查:

運維同學查了各種監(jiān)聽配置,防火墻這些,都沒什么問題,但是沒有明確證據(jù)能夠提供證明通過http方式能訪問到數(shù)據(jù)庫,時間拖得比較久,項目上就急了,讓盡快找到問題,所以就用go寫了個小工具拉到集群上試試看8123這個端口到底能不能正常提供服務。

正文

先安裝必要的庫,clickhouse官方提供了2個版本的庫,v1和v2,v1版本已經(jīng)明確不會繼續(xù)更新了,所以用新不用舊哈,可以用官方庫的方式或者用dsn的方式,這個我下面一起說,安裝庫的命令:

go get github.com/ClickHouse/clickhouse-go/v2

構(gòu)造結(jié)構(gòu)體

編寫結(jié)構(gòu)體,存放基本信息:

type Clickhouse struct {
	Host       string    // 服務端主機
	Port       int       // 端口
	DB         string    // 數(shù)據(jù)庫
	User       string    // 用戶名
	Password   string    // 密碼
	Connection *sql.DB   // 建立連接后存放連接
	Rows       *sql.Rows // 運行sql后的結(jié)果存放
}

Connection主要是用來建立連接后把相關(guān)信息存放,這樣方便繼續(xù)調(diào)用其他的方法,因為我的主要目的是測試數(shù)據(jù)庫能否連通和運行Sql,所以這里Rows用來存放測試的select語句的結(jié)果。

參數(shù)讀取

這塊沒什么好說的,連接的參數(shù)直接從命令行讀取,用flag包就好:

var (
	host  = flag.String("host", "localhost", "clickhouse host")
	port  = flag.Int("port", 8123, "clickhouse port")
	user  = flag.String("user", "default", "clichouse user")
	pass  = flag.String("password", "", "clickhouse password")
	db    = flag.String("db", "default", "clickhouse database")
	query = flag.String("query", "show tables", "query you will run")
	mode  = flag.String("mode", "driver", "driver or dsn")
)

前面幾個參數(shù)不用解釋,主要是querymodequery是要運行的sql語句,我們默認就認為跑的是select語句,然后是mode,允許選擇模式,用戶可以使用driver或者dsn兩種模式進行連接,我寫了兩個不同的方法,其實也可以在一個Connect方法里做判斷,看個人習慣;

建立連接

接下來我們建立數(shù)據(jù)庫連接:

// 
func (c *Clickhouse) Conn() {
	c.Connection = clickhouse.OpenDB(&clickhouse.Options{
		Addr: []string{fmt.Sprintf("%s:%d", c.Host, c.Port)},
		Auth: clickhouse.Auth{
			Database: c.DB,
			Username: c.User,
			Password: c.Password,
		},
		Settings: clickhouse.Settings{
			"max_execution_time": 60,
		},
		DialTimeout: 5 * time.Second,
		Compression: &clickhouse.Compression{
			Method: clickhouse.CompressionBrotli,
			Level:  5,
		},
		// 必須添加協(xié)議方式
		Protocol: clickhouse.HTTP,
	})

}

func (c *Clickhouse) ConnDsn() {
	conn, err := sql.Open("clickhouse", fmt.Sprintf("http://%s:%d/%s?username=%s&password=%s", c.Host, c.Port, c.DB, c.User, c.Password))
	if err != nil {
		log.Printf("Connect to the server failed, %s.\n", err.Error())
		return
	}
	c.Connection = conn
}

參考官網(wǎng)的實例,實現(xiàn)兩種連接方式,關(guān)閉方法就直接把sql.DB和sql.Rows都關(guān)閉就可以了:

func (c *Clickhouse) Close() {
	c.Connection.Close()
	c.Rows.Close()
}

發(fā)起查詢

查詢使用Query方法進行:

func (c *Clickhouse) Select(query string) {
	rows, err := c.Connection.Query(query)
	if err != nil {
		log.Printf("Query select failed, %s.\n", err.Error())
		return
	}
	c.Rows = rows
}

查詢的結(jié)果我保存到Rows里,方便后面的解析

結(jié)果解析

比較麻煩的就是結(jié)果的解析了,用過database/sql庫的哥們都知道,這個庫只提供了基礎(chǔ)的一些接口,查詢出來一般用Scan去獲取數(shù)據(jù),用法類似這樣:

問題就在于,Scan要指定和sql查詢出來一樣多的變量,對于我們這個小工具來說,sql是不一定的,所以查詢出來的字段數(shù)量肯定yes不定的,如何動態(tài)處理這個問題,肯定是不能直接寫一個結(jié)構(gòu)體解決的,先看我的代碼:

func (c *Clickhouse) Show() {
	cols, err := c.Rows.Columns()
	if err != nil {
		log.Printf("Failed to get table columns, %s.\n", err.Error())
		return
	}
	// 一行數(shù)據(jù),使用any是為了避開數(shù)據(jù)類型的問題
	var rows = make([]any, len(cols))
	// 存實際的值,是byte數(shù)組,長度以列的數(shù)量為準
	var values = make([][]byte, len(cols))
	for i := 0; i < len(cols); i++ {
		rows[i] = &values[i]
	}
	// 打印表頭
	fmt.Println(strings.Join(cols, ","))
	for c.Rows.Next() {
		if err = c.Rows.Scan(rows...); err != nil {
			fmt.Println(err)
			return
		}
		var vString []string
		for _, v := range values {
			vString = append(vString, string(v))
		}
		// 逐行打印出來
		fmt.Println(strings.Join(vString, ","))
	}
}

大概思路是這樣:

  • Scan需要傳入每個用來綁定單行數(shù)據(jù)值的變量,所以values是實際存儲數(shù)據(jù)的byte數(shù)組,然后把數(shù)組的每個元素的地址再存入到rows數(shù)組中;
  • 現(xiàn)在可以用rows[index]這樣的方式來訪問values中的值了,把rows直接作為入?yún)魅氲絊can,在每次循環(huán)中,把values的值轉(zhuǎn)成逗號分割的字符串,直接打印

結(jié)果驗證

OK,現(xiàn)在邏輯完成了,我們運行測試一下,

go run main.go -host hostname -password paswword -query "select * from clusters" -db system -mode dsn

只查詢2個字段,2行數(shù)據(jù):

結(jié)語

完成,然后把工具放到生產(chǎn)環(huán)境一測試,查詢都正常,這下開發(fā)哥們要繼續(xù)查他的程序問題了,??,運維甩鍋成功??????

到此這篇關(guān)于使用go連接clickhouse的實戰(zhàn)操作的文章就介紹到這了,更多相關(guān)go連接clickhouse內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言入門教程之Arrays、Slices、Maps、Range操作簡明總結(jié)

    Go語言入門教程之Arrays、Slices、Maps、Range操作簡明總結(jié)

    這篇文章主要介紹了Go語言入門教程之Arrays、Slices、Maps、Range操作簡明總結(jié),本文直接給出操作代碼,同時對代碼加上了詳細注釋,需要的朋友可以參考下
    2014-11-11
  • 詳解Go如何實現(xiàn)協(xié)程并發(fā)執(zhí)行

    詳解Go如何實現(xiàn)協(xié)程并發(fā)執(zhí)行

    線程是通過本地隊列,全局隊列或者偷其它線程的方式來獲取協(xié)程的,目前看來,線程運行完一個協(xié)程后再從隊列中獲取下一個協(xié)程執(zhí)行,還只是順序執(zhí)行協(xié)程的,而多個線程一起這么運行也能達到并發(fā)的效果,接下來就給給大家詳細介紹一下Go如何實現(xiàn)協(xié)程并發(fā)執(zhí)行
    2023-08-08
  • GoFrame?gtree樹形結(jié)構(gòu)的使用技巧示例

    GoFrame?gtree樹形結(jié)構(gòu)的使用技巧示例

    這篇文章主要為大家介紹了GoFrame?gtree樹形結(jié)構(gòu)的使用技巧示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Golang優(yōu)雅保持main函數(shù)不退出的辦法

    Golang優(yōu)雅保持main函數(shù)不退出的辦法

    很多時候我們需要讓main函數(shù)不退出,讓它在后臺一直執(zhí)行,下面這篇文章主要給大家介紹了關(guān)于Golang優(yōu)雅保持main函數(shù)不退出的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • Go 協(xié)程超時控制的實現(xiàn)

    Go 協(xié)程超時控制的實現(xiàn)

    本文主要介紹了Go 協(xié)程超時控制的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Go語言入門13之runtime包案例講解

    Go語言入門13之runtime包案例講解

    這篇文章主要介紹了Go語言入門runtime包相關(guān)知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • GoLang中拼接字符串性能優(yōu)化方法詳解

    GoLang中拼接字符串性能優(yōu)化方法詳解

    最近在做性能優(yōu)化,有個函數(shù)里面的耗時特別長,看里面的操作大多是一些字符串拼接的操作,而字符串拼接在 golang 里面其實有很多種實現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Golang語言如何高效拼接字符串的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • Golang程序漏洞檢測器govulncheck的安裝和使用

    Golang程序漏洞檢測器govulncheck的安裝和使用

    govulncheck 是一個命令行工具,可以幫助 Golang 開發(fā)者快速找到項目代碼和依賴的模塊中的安全漏洞,該工具可以分析源代碼和二進制文件,識別代碼中對這些漏洞的任何直接或間接調(diào)用,本文就給大家介紹一下govulncheck安裝和使用,需要的朋友可以參考下
    2023-09-09
  • GoLang之使用Context控制請求超時的實現(xiàn)

    GoLang之使用Context控制請求超時的實現(xiàn)

    這篇文章主要介紹了GoLang之使用Context控制請求超時的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • Go語言實現(xiàn)UDP版聊天小工具的示例詳解

    Go語言實現(xiàn)UDP版聊天小工具的示例詳解

    這篇文章主要為大家詳細介紹了如何利用Go語言實現(xiàn)聊天小工具(UDP版),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03

最新評論