用到的库 https://github.com/knyar/nginx-lua-prometheus
apisix/prometheus/exporter.lua
变量 metrics 用来定义指标,
prmetheus_keys
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| KeyIndex.new(shared_dict, prefix) self.dict = shared_dict self.key_prefix = prefix .. "key_" self.delete_count = prefix .. "delete_count" self.key_count = prefix .. "key_count" self.last = 0 self.deleted = 0 self.keys = {} self.index = {}
KeyIndex:sync() 获取 dict delete_count 和 dict key数量 N 如果本地的 delete 和 delete_count 不同,说明有删除 执行 sync_range(0,N) 如果当前的 last 和 N 不同说明有更新,那么执行 sync_reange(N,last) 并返回 N
KeyIndex:sync_range(first, last) 从 dict 同步 first 到 last 区间的内容到当前对象 从 dict 获取 keyi 记录映射关系 keys[i] = key ,index[key]=i 如果 keyi 是不存在的,从映射关系删除内容
KeyIndex:list() 执行同步 sync() 并返回 keys 的 copy
KeyIndex:add(key_or_keys, err_msg_lru_eviction) 对每一个 key 执行: 同步并获取N 如果 key 存在,就跳过 如果 key 不存在就设置 dict N+1 为 key key_count ++ 设置 keys 和 index KeyIndex:remove(key, err_msg_lru_eviction)
总结: 利用 dict 存储数据,利用 sync 将数据同步到 worker 进程的函数
|
prometheus
ngx.sleep(0)
OpenResty 中的 ngx.sleep(0) 调用会主动放弃当前的 CPU 执行权,而把执行权交还给 nginx 事件循环和其他并发请求。当前
yield 了的 Lua 协程会在下一个 nginx 事件处理周期里接着继续运行。
一个典型应用:
shared-dict怎样实现不阻塞nginx进程?每分钟刷新一次缓存,刷新的时候,几十秒,nginx无反应,单个进程100%,其他进程没事,但是也无反应,好像访问的时候也到这个100%的进程了,导致无反应。
解决方法是:可以在操作中穿插一些 ngx.sleep(0) 用来让其他协程获得运行机会。
prometheus 里有大量的调用 dict ,执行 reload 后大量的同步会导致阻塞。
init:
dict : 原始全局字典
_counter : 用来记录 worker 计数器,并同步到dict
key_index: 用来将dict key 同步到 worker 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| register(self, name, help, label_names, buckets, TYPE_HISTOGRAM) 构建指标需要的数据,对传入的name 去掉 _bucket _sum _count 的后缀 当为 historgram 时 name 或 name_maybe_historgram 存在 当为其他时, name 或者加入了后缀的存在都认为是指标存在,返回错误。 label_names :label 名列表 label_count: label 数量 lookup = {} :用table 来存储指标树 例如 ['me.com']['200'][LEAF_KEY] = 'http_count{host="me.com",status="200"}' yield :执行读写 dict 次数 200 次就释放一次 cpu 时间片占用
lookup_or_create(self, label_values) 返回完整的指标名 counter 和 gauge 直接返回字符串 histogram 返回 list 如果 lookup_size > lookup_max_size ,清空 lookup inc_gauge: dict incr
|
用特权进程来提供服务
想办法让指标就是排好序
https://mp.weixin.qq.com/s/guR77q6kXxpGfKzT46GYsg
- 指标名存储到对应的 table 树里面,定时同步
- 输出只有循环和取 dict