Prometheus nacos服务发现监控 服务自定义指标
·
一、服务部分
1.添加依赖
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.spring-boot application.yaml中配置
management:
endpoint:
prometheus:
enabled: true
endpoints:
web:
exposure:
include: 'prometheus'
3. 注册bean,修改可见指标
@Bean
MeterRegistryCustomizer<MeterRegistry> metricsConfig() {
return registry -> registry.config().meterFilter(new PrometheusMeterFilter());
}
static class PrometheusMeterFilter implements MeterFilter {
@Override
public MeterFilterReply accept(Meter.Id id) {
//此判断条件自定义,可用name来标识,如果不自定义,会将一些spring的指标给返回
if (id.getName().contains("")) {
return MeterFilterReply.NEUTRAL;
}
return MeterFilterReply.DENY;
}
}
4.注册指标
@Autowired
private MeterRegistry registry;
public void regist(){
//ToDoubleFunction 中泛型可以自定义,对应第二个参数的类型
Gauge.builder("name", "", value -> {
//此方法在每次prometheus主动调用该服务的指标接口时调用, /actuator/prometheus
return 0;
}).tags(Tags.empty()).register(registry);
}
二、自定义prometheus容器镜像
1.编写代码实现nacos服务发现文件刷盘
(1)刷盘的json格式
[
{
"targets": [
"192.168.0.002:8080"
],
"labels": {}
},
{
"targets": [
"192.168.0.001:8080"
],
"labels": {}
}
]
(2)代码(此处实现使用go语言,15s每次)
package main
import (
"encoding/json"
"fmt"
"github.com/nacos-group/nacos-sdk-go/v2/clients"
"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
"github.com/nacos-group/nacos-sdk-go/v2/vo"
"os"
"strconv"
"strings"
"time"
)
type NacosEntity struct {
Targets []string `json:"targets"`
Labels map[string]string `json:"labels"`
}
//代码可以用任何语言实现,需刷盘到指定文件,以便prometheus读取到
func main() {
nacos_address := os.Getenv("NACOS_SERVER_ADDRESS")
namespace := os.Getenv("NACOS_NAMESPACE")
username := os.Getenv("NACOS_USER")
password := os.Getenv("NACOS_PASSWORD")
service_name := os.Getenv("SERVICE_NAME")
group_name := os.Getenv("GROUP_NAME")
refresh_rate_str := os.Getenv("REFRESH_RATE")
if username == "" {
username = "nacos"
}
if password == "" {
password = "nacos"
}
if group_name == "" {
group_name = "DEFAULT_GROUP"
}
if refresh_rate_str == "" {
refresh_rate_str = "15"
}
refresh_rate, err9 := strconv.Atoi(refresh_rate_str)
if err9 != nil {
refresh_rate = 15
fmt.Println("refresh_rate err:", err9)
}
clientConfig := constant.ClientConfig{
NamespaceId: namespace,
TimeoutMs: 5000,
NotLoadCacheAtStart: true,
LogDir: "/tmp/nacos/log",
CacheDir: "/tmp/nacos/cache",
LogLevel: "debug",
Password: username,
Username: password,
}
serverConfigs := make([]constant.ServerConfig, 0)
url_array := strings.Split(nacos_address, ",")
for _, node := range url_array {
ip_port := strings.Split(node, ":")
port, _ := strconv.ParseUint(ip_port[1], 10, 64)
serverConfigs = append(serverConfigs, constant.ServerConfig{
IpAddr: ip_port[0],
ContextPath: "/nacos",
Port: port,
Scheme: "http",
})
}
namingClient, err := clients.NewNamingClient(
vo.NacosClientParam{
ClientConfig: &clientConfig,
ServerConfigs: serverConfigs,
},
)
if err != nil {
fmt.Println(err)
return
}
defer namingClient.CloseClient()
ticker := time.NewTicker(time.Duration(refresh_rate) * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
namingClient.SelectInstances(vo.SelectInstancesParam{})
instances, err2 := namingClient.SelectAllInstances(vo.SelectAllInstancesParam{
ServiceName: service_name,
GroupName: group_name, // default value is DEFAULT_GROUP
})
if err2 != nil {
fmt.Println(err2)
continue
}
target_array := make([]NacosEntity, 0)
for _, instance := range instances {
if instance.Healthy {
var ta NacosEntity
ta.Labels = make(map[string]string)
ip_port := instance.Ip + ":" + strconv.Itoa(int(instance.Port))
ta.Targets = append(ta.Targets, ip_port)
//label中的标签会出现在指标标签中,如果需要,可以自定义添加
//ta.Labels["ip"] = instance.Ip
target_array = append(target_array, ta)
}
}
data, err3 := json.Marshal(target_array)
if err3 != nil {
fmt.Println("error:", err3)
} else {
writeToFile(data)
}
}
}
}
func writeToFile(data []byte) {
f, err := os.OpenFile("/opt/discovery.json", os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm)
if err != nil {
fmt.Println("文件打开失败", err)
}
defer f.Close()
f.Write(data)
}
2.prometheus yml配置
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
rule_files:
scrape_configs:
- job_name: "test-service"
metrics_path: '/actuator/prometheus'
scrape_interval: 15s
file_sd_configs:
- files: ['/opt/discovery.json']
refresh_interval: 15s
3. 打包
(1)Dockerfile
FROM 基础镜像
#此基础镜像中需包含prometheus
ENV RETENTTION_TIME=30d
ENV STORAGE_PATH=/data/prometheus
ENV CONFIG_PATH=/opt/prometheus/prometheus.yml
COPY ./prometheus.yml /opt/prometheus/prometheus.yml
COPY ./nacos-prometheus-load /opt/nacos-prometheus-load
COPY ./run.sh /opt/run.sh
RUN chmod +777 /opt/run.sh
WORKDIR /opt
RUN mkdir -p -m 777 /data/prometheus
RUN mkdir -p -m 777 /opt/prometheus
ENTRYPOINT ["sh", "-c", "/opt/run.sh"]
(2)run.sh
/opt/nacos-prometheus-load & #刷盘程序打包后的程序
/opt/prometheus2481/prometheus --config.file=$CONFIG_PATH --storage.tsdb.retention.time=$RETENTTION_TIME --storage.tsdb.path=$STORAGE_PATH --web.console.libraries=/usr/share/prometheus/console_libraries --web.console.templates=/usr/share/prometheus/consoles --web.enable-lifecycle
更多推荐
所有评论(0)