由于服务一直在向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", "")
}