go 使用http长连接读写influxdb

由于服务一直在向influxdb中写入数据,使用短连接的话连接会频繁的创建和关闭,所以改写为长连接

代码如下:

package main

import (
    "context"
    "crypto/tls"
    "fmt"
    "github.com/influxdata/influxdb1-client"
    "io/ioutil"
    "net"
    "net/http"
    "net/url"
    "path"
    "strings"
    "time"
)

type Client struct {
	url        url.URL
	unixSocket string
	username   string
	password   string
	httpClient *http.Client
	userAgent  string
	precision  string
}

// 写influxdb,参考github.com/influxdata/influxdb1-client
func (c *Client) WriteLineProtocol(data, database, retentionPolicy, precision, writeConsistency string) (*client.Response, error) {
	u := c.url
	u.Path = path.Join(u.Path, "write")

	r := strings.NewReader(data)

	req, err := http.NewRequest("POST", u.String(), r)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "")
	req.Header.Set("User-Agent", c.userAgent)
	if c.username != "" {
		req.SetBasicAuth(c.username, c.password)
	}
	params := req.URL.Query()
	params.Set("db", database)
	params.Set("rp", retentionPolicy)
	params.Set("precision", precision)
	params.Set("consistency", writeConsistency)
	req.URL.RawQuery = params.Encode()

	resp, err := c.httpClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var response client.Response
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusNoContent && resp.StatusCode != http.StatusOK {
		err := fmt.Errorf(string(body))
		response.Err = err
		return &response, err
	}

	return nil, nil
}

// 使用http长连接去写influxdb, “github.com/influxdata/influxdb1-client” 使用的不是长连接,这里进行重新定义
func longConnectionInfluxClient(c client.Config) (*Client, error){
	tlsConfig := new(tls.Config)
	if c.TLS != nil {
		tlsConfig = c.TLS.Clone()
	}
	tlsConfig.InsecureSkipVerify = c.UnsafeSsl
	// 这里是对长连接的定义
	tr := &http.Transport{
		Proxy:           c.Proxy,
		TLSClientConfig: tlsConfig,
		DialContext: (&net.Dialer{
			Timeout:   5 * time.Second,
			KeepAlive: 120 * time.Second,
			DualStack: true,
		}).DialContext,
		ForceAttemptHTTP2: true,
		MaxConnsPerHost: 100,
		MaxIdleConns:    1000,
		MaxIdleConnsPerHost: 100,
		IdleConnTimeout: 300 * time.Second,
	}
	if c.UnixSocket != "" {
		// No need for compression in local communications.
		tr.DisableCompression = true

		tr.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {
			return net.Dial("unix", c.UnixSocket)
		}
	}
	cl := Client{
		url:        c.URL,
		unixSocket: c.UnixSocket,
		username:   c.Username,
		password:   c.Password,
		httpClient: &http.Client{Timeout: c.Timeout, Transport: tr},
		userAgent:  c.UserAgent,
		precision:  c.Precision,
	}
	if cl.userAgent == "" {
		cl.userAgent = "InfluxDBClient"
	}
	return &cl, nil
}

func initClient(hostIp, userName, password string, timeout int) *Client {
	host, err := url.Parse(fmt.Sprintf("http://%s", hostIp))
	conf := client.Config{
		URL: *host,
		Username: userName,
		Password: password,
		Timeout:  time.Duration(timeout) * time.Second,
	}
	cl, err := longConnectionInfluxClient(conf)
	if err != nil {
		panic(err)
	}
	return cl
}

func main() {
	cl := initClient("10.10.25.50:8086", "", "", 5)
	str := "cpu,host=localhost value=10 1564387285"
	cl.WriteLineProtocol(str, "test", "autogen", "s", "")
}
发布了11 篇原创文章 · 获赞 1 · 访问量 2205

猜你喜欢

转载自blog.csdn.net/weixin_42450836/article/details/104801907