天天看点

【笔记】macos上部署thanos_receiver + thanos_query

  • 为了方便起见,在mac笔记本上进行了测试

1.写一个发送数据的客户端

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/golang/protobuf/proto"
	"github.com/prometheus/prometheus/prompb"
	"github.com/golang/snappy"
)

var client = &http.Client{
	Transport: &http.Transport{
		Proxy:                  nil,
		DialContext:            nil,
		Dial:                   nil,
		DialTLSContext:         nil,
		DialTLS:                nil,
		TLSClientConfig:        nil,
		TLSHandshakeTimeout:    0,
		DisableKeepAlives:      false,
		DisableCompression:     false,
		MaxIdleConns:           100,
		MaxIdleConnsPerHost:    0,
		MaxConnsPerHost:        0,
		IdleConnTimeout:        0,
		ResponseHeaderTimeout:  0,
		ExpectContinueTimeout:  0,
		TLSNextProto:           nil,
		ProxyConnectHeader:     nil,
		MaxResponseHeaderBytes: 0,
		WriteBufferSize:        0,
		ReadBufferSize:         0,
		ForceAttemptHTTP2:      false,
	},
	CheckRedirect: nil,
	Jar:           nil,
	Timeout:       time.Duration(1000) * time.Millisecond,
}

//Post POST数据
func Post(c *http.Client, url string, postData string, timeoutMs int, headers map[string]string) (int, []byte, error) {
	req, err := http.NewRequest("POST", url, strings.NewReader(postData))
	if err != nil {
		return 0, nil, err
	}
	for k, v := range headers {
		req.Header.Set(k, v)
	}
	c.Timeout = time.Duration(timeoutMs) * time.Millisecond
	rsp, err := c.Do(req)
	if err != nil {
		return 0, nil, err
	}
	respData, err := ioutil.ReadAll(rsp.Body)
	rsp.Body.Close()
	if err != nil {
		return rsp.StatusCode, nil, err
	}
	return rsp.StatusCode, respData, nil
}

func getReq(cnt int) *prompb.WriteRequest {
	req := &prompb.WriteRequest{
		Timeseries: []prompb.TimeSeries{
			prompb.TimeSeries{
				Labels: []prompb.Label{
					prompb.Label{
						Name:  "__name__",
						Value: "metric_of_ahfu_1",
					},
					prompb.Label{
						Name:  "container",
						Value: "cls-xxxxx-111",
					},
					{Name: "instance", Value: "localhost:9090"},
					{Name: "job", Value: "prometheus"},
				},
				Samples: []prompb.Sample{
					prompb.Sample{
						Value:     float64(1002),
						Timestamp: time.Now().UnixNano() / 1000000,
					},
				},
				Exemplars: nil,
			},
		},
		Metadata: []prompb.MetricMetadata{},
	}
	if cnt > 1 {
		for i := 1; i < cnt; i++ {
			req.Timeseries = append(req.Timeseries, prompb.TimeSeries{
				Labels: []prompb.Label{
					prompb.Label{
						Name:  "__name__",
						Value: fmt.Sprintf("metric_of_ahfu_%d", i+1),
					},
					prompb.Label{
						Name:  "container",
						Value: "cls-xxxxx-111",
					},
					{Name: "instance", Value: "localhost:9090"},
					{Name: "job", Value: "prometheus"},
				},
				Samples: []prompb.Sample{
					prompb.Sample{
						Value:     float64(rand.Intn(2000)),
						Timestamp: time.Now().UnixNano() / 1000000,
					},
				},
				Exemplars: nil,
			})
		}
	}
	return req
}

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)

	runtimes := 1
	if len(os.Args) >= 4 {
		runtimes, _ = strconv.Atoi(os.Args[3])
	}
	for r := 0; r < runtimes; r++ {
		cnt := 1
		if len(os.Args) >= 3 {
			cnt, _ = strconv.Atoi(os.Args[2])
		}
		req := getReq(cnt)

		log.Println(req)
		buf, _ := proto.Marshal(req)
		dst := make([]byte, 0, len(buf))
		dst = snappy.Encode(dst, buf)
		//
		url := fmt.Sprintf("http://%s/api/v1/receive", os.Args[1])
		_, rsp, err := Post(client, url, string(dst), 1000,
			map[string]string{
				"Content-Encoding":                  "snappy",
				"Content-Type":                      "application/x-protobuf",
				"User-Agent":                        "ahfu-test-client",
				"X-Prometheus-Remote-Write-Version": "0.1.0",
			})
		if err != nil {
			log.Println("Post error:", err.Error())
			return
		}
		log.Println("url:", url)
		log.Println("rsp:", string(rsp))
		time.Sleep(time.Duration(10) * time.Second)
	}
}

           
  • 执行命令行:

    ./remote_write_client_macos 127.0.0.1:10908 30 1000

    • 每次发送30个监控项
    • 连续发送1000次,中间间隔10秒
  • instance和job这两个label一定要加,否则thanos receiver会丢弃。

2.部署thanos receiver:

thanos  receive \
    --tsdb.path "./ahfu_dir/" \
    --grpc-address 0.0.0.0:10907 \
    --http-address 0.0.0.0:10909 \
    --receive.replication-factor 1 \
    --label "receive_replica=\"0\"" \
    --label "receive_cluster=\"eu1\"" \
    --remote-write.address 0.0.0.0:10908 \
    --log.level=debug \
    --log.format=logfmt
           
  • 10908端口是http协议,用于post监控数据到receiver上
  • 10907端口是grpc协议,用于给thanos query来查询
  • 10909端口是自身的监控数据的expoter
    • 浏览器输入:http://127.0.0.1:10909/metrics可以看见thanos receiver自身的监控数据
    • 搜索:

      http_requests_total{code="200",handler="receive",method="post"}

      可以看见推送的请求量
  • 到TSDB目录:
    • 执行:

      promtool tsdb list ./

    • 启动后两分钟以后,可以看见如下信息:
promtool tsdb list ./
BLOCK ULID                  MIN TIME       MAX TIME       DURATION     NUM SAMPLES  NUM CHUNKS   NUM SERIES   SIZE
01FD7J9QW40GF1YSSZR8BTBJV6  1629115842635  1629116635334  13m12.699s   2370         30           30           13931
           

3.部署thanos query

thanos query \
  --http-address "127.0.0.1:9091" \
  --store "127.0.0.1:10907"
           
  • 浏览器访问:127.0.0.1:9091 可以看见查询界面
  • 注意:

    神坑

    ——
    • 发送的数据要足够多
    • 发送的时间要足够长
    • 我的客户端发送了约两分钟后,才看见数据
  • 输入:

    metric_of_ahfu_1

    , 可以看见客户端工具上报的数据。