版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1.引言 前段时间利用grafana/grafana-image-renderer 做了一个自动截图服务。 见萌叔的文章抓取GRAFANA PANEL视图。但是我发现了一个问题(grafana版本v6.0.1),如果grafana的实例数量超过1个,在grafana中访问grafana render link时,就会有一定的概率失败,图片无法成功渲染。这到底是是为什么? 本文将给出完整的问题排查和解决过程,希望读者可以从中汲取一些养分,为以后排查其它问题提供一些思路。 2. 日志,一切从日志开始 看到这种问题,首先看看日志中是否有线索 2.1 首先看grafana的日志 只能了解到点击grafana render link之后,会触发一个GET请求,访问grafana服务的 /render/d-solo/P3a2p0cZz/redis-and-mysql-and-cache,然后引起一个内部错误 2.2 看看grafana-image-renderer的日志 我们已经知道,图片渲染的过程,grafana要调用grafana-image-renderer,让我们来看下grafana-image-renderer的日志。 需要注意,grafana-image-renderer的日志默认是打印在标准输出和标准错误输出里的。 对比成功和失败的case我发现,在失败的case中,日志中会多了一条401 (Unauthorized)的日志 对应的链接,就是我们要渲染成图片的panel所对应的网页地址 猜测1 现在我们可以猜测grafana-image-renderer可能是请求grafana服务对应的网页资源失败,然后导致图片渲染失败。 2.3 抓包,需要API入口 2.3.1 对grafana-image-renderer抓包 为了进一步验证这个上面的猜测,抓包看一下,grafana-image-renderer所收到的请求 萌叔抓包使用的是buger/goreplay ./gor –input-raw :8081 –output-stdout 1 1a1a5c7c2e733bf0ed41f7ce35bee28da845ab49 1616730655714291898 2541293 GET… 继续阅读 由grafana-image-renderer引出的一个问题

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1.引言 最近萌叔在做监控系统的改造,其中一个目标是,当Prometheus触发告警之后需要将Alert Rule对应的grafana图表以邮件的形式发送给处理人员。 2. grafana/grafana-image-renderer 经过搜索资料,萌叔发现grafana官方出了一个插件,可以直接用于抓取grafana的Panel图表。 传送门: grafana/grafana-image-renderer 它有2种运行方式 以grafana的插件方式运行 以外部服务的形式运行 这里以第2种方式展开。 2.1 docker模式运行 这个外部服务是一个nodejs的程序 node build/app.js server –config=config.json puppeteer很像,它接收一个URL地址作为参数,然后运行Headless Chrome,向目标地址发起请求,解析并渲染网页,最后截图。 Headless Chrome可以这样理解,无需显卡、显示器,Chrome以命令行程序的方式运行对网页的请求、渲染、截图等工作。详见参考资料4 Grafana官方提供了docker镜像 grafana/grafana-image-renderer 直接运行即可 2.2 Grafana配置 [rendering] # grafana image renderer服务地址 server_url = http://grafana-image-renderer.example.com:8081/render # grafana服务地址 callback_url = http://grafana.example.com:3000/… 继续阅读 抓取Grafana Panel视图

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1.前言 xuxueli/xxl-job是一个分布式任务调度平台。它在github上有1w多个star,有多家公司都已经用在生产实践中。 在萌叔看来这是一个”Less is more”的典型。它的设计的非常简单,最大的优点是实用。 2.主要结构和逻辑 XXL-JOB任务调度平台分为2个部分,Scheduler和Executor。具体的实现Scheduler对应是xxl-job-admin,同时xxl-job-admin还配有web UI,可以配置管理任务。 Scheduler和Executor之间通过HTTP API交互,因此Executor可以通过各种语言实现。比如Golang的 xxl-job/xxl-job-executor-go 以上图为例,scheduleThread将任务通过Executor是的/run api推送给Executor { “jobId”: 3, “executorHandler”: “task.test”, “executorParams”: “x=100”, “executorBlockStrategy”: “SERIAL_EXECUTION”, “executorTimeout”: 0, “logId”: 17, “logDateTime”: 1606100913829, “glueType”: “BEAN”, “glueSource”: “”, “glueUpdatetime”: 1606099566000, “broadcastIndex”: 0, “broadcastTotal”: 1 } Executor会根据executorHandler找到对应的handler,执行完之后,又会调用xxl-job-admin的/xxl-job-admin/api/callback回报任务的执行结果。从上面的描述我们可以知道,xxl-job-admin和excutor都必须暴露出api服务(都是HTTP接口)。 Scheduler可以有多个。它们之间通过MySQL进行同步。… 继续阅读 分布式任务调度平台xxl-job

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 警告:本文仅用于萌叔自己总结之用,对其它人而言可能毫无营养,没有阅读价值。 Dashboard 是基于网页的 Kubernetes 用户界面。 你可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群资源。 你可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源 (如 Deployment,Job,DaemonSet 等等)。 通过一段时间的使用感受而言,Dashboard虽然做的差强人意,但聊胜于无。 2. 安装&配置 wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml 建议脚本下载以后,先大致阅读以下 2.1 修改yaml kind: Service apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard spec:… 继续阅读 k8s学习笔记(1)-安装dashboard

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 prometheus的官方和社区为了我们提供了丰富的exporter。对常见的硬件设备、数据库、消息队列以及常见的软件进行监控。另外官方还为我们提供了4种指标类型方便我们自定义exporter Counter Counter代表累计指标,它表示单调递增的计数器,通常用于表示服务请求数,完成的任务数,错误的数量。 Gauge Gauge表示某种瞬时状态,某一时刻的内存使用率、消息队列中的消息数量等等。它的值既可以增大,也可以减小。 Histogram 通常用于top percentile,比如请求耗时的TP90、TP99等 Summary 类似于Histogram 我们回顾一下prometheus的指标采集的一般过程 1) 创建指标 HTTPReqTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ Name: “http_requests_total”, Help: “Total number of HTTP requests made.”, }, []string{“method”, “path”, “status”}) 2) 指标注册到 DefaultRegisterer prometheus.MustRegister( HTTPReqTotal, ) 3) 指标和对应的值通过HTTP API暴露出来 The… 继续阅读 玩转PROMETHEUS(6) 实现自定义的Collector

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 引言 前段时间接手了一个前端项目。这个前端项目采用docker方式部署。有3套不同的环境,开发联调、测试、生产分别指向不同的后端API服务。 项目目录结构如下 ├── DockerfileDev ├── DockerfileProd ├── DockerfileTest ├── Makefile ├── README.md ├── config │   ├── api.dev.conf │   ├── api.prod.conf │   ├── api.test.conf │   └── nginx.conf ├── package.json ├── src ├── tsconfig.json └── yarn.lock config目录中是nginx相关的配置文件, 仅仅因为后端API服务地址不同,Dockerfile就有3个,对于开发联调、测试和生产环境的docker镜像也需要分别build,显然是非常低效的。 2. 改造 2.1… 继续阅读 动态修改容器中的配置文件

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 本文基于Consul v1.6.2 这篇文章并不是consul ACL的完全配置手册,感兴趣的读者请阅读参考资料1 2. Token存在的意义 Token其实用于权限控制中,表征使用者的身份 Consul的ACL中重要的3个实体 Token最终与一组Policy关联, 可以理解为RBAC(基于角色的访问控制)中的权限。 3. 能够细粒度控制的权限有哪些? 4. 如何使用Token 详见参考资料2 curl \ –header “X-Consul-Token: <consul token>” \ http://127.0.0.1:8500/v1/agent/members 其实也可以附加在Query中,但官方不推荐 5. 配置文件示例 5.1 server模式 { “acl”: { “enabled”: true, “default_policy”: “deny”, “enable_token_persistence”: true }, “datacenter”:… 继续阅读 玩转consul(4)-ACL机制要点

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 在复杂的业务逻辑中,一个请求就有可能带来10 ~ 30条日志的写入。打日志造成的开销很大,是无法被忽略的一环。怎样才能提高日志的写入速度? 2. 实验 首先来看几个实验 完整程序见 vearne/golab/zaplog 中的log.go log2.go log3.go 2.1 打印到文件 打印到指定文件中,并做归档 package zaplog import ( “go.uber.org/zap” “go.uber.org/zap/zapcore” “gopkg.in/natefinch/lumberjack.v2” ) func InitLogger() *zap.Logger { // 动态调整日志级别 alevel := zap.NewAtomicLevel() hook := lumberjack.Logger{ Filename: “/tmp/tt1.log”, MaxSize: 1024, //… 继续阅读 玩转高性能日志库ZAP(5)-异步写日志

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 前言 因为一直对IM的实现非常感兴趣,前段时间也自己手撸了一个。 萌叔觉得,这个版本实现比较简单,但能够从部分反映出IM的概貌,可能会其他的朋友有所帮助, 因此决定分享出来。 1. 功能说明 这个聊天系统被设计为陌生人自动匹配进行聊天,因此不需要注册。分为2个模块,在线体验地址 chat.vearne.cc 备注:如果匹配不上,可以多开几个窗口,自己和自己聊 1.1 客户端 vearne/chat-ui 客户端采用Vue开发 依赖组件 MatheusrdSantos/vue-quick-chat 1.2 服务端 vearne/chat 采用golang开发 重要框架 olahol/melody — websocket框架 grpc/grpc-go — grpc框架 架构图 客户与接入层的通讯采用websocket + 自定义的文本协议实现。 自定义的协议其实都是携带着各种命令的JSON字符串,很容易看懂 比如 创建一个新的账号(由客户端发出) request { “cmd”: “CRT_ACCOUNT”, “nickName”: “XXXX” } response… 继续阅读 一个简单的陌生人聊天系统

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 一个长URL地址,形如 “https://www.google.com.hk/search?q=%E7%9F%AD%E5%9C%B0%E5%9D%80%E6%9C%8D%E5%8A%A1&oq=%E7%9F%AD%E5%9C%B0%E5%9D%80%E6%9C%8D%E5%8A%A1&aqs=chrome..69i57j69i61.4824j1j7&sourceid=chrome&ie=UTF-8” , 由于不可避免的带有PATH、各种参数和追踪标识,这导致URL往往很长。当你要把这个URL发送给其它人时,可能会变得很不方便。比如短信/微博有字数限制。或者对方将链接粘贴到浏览器时,容易漏掉部分数据。 因此短链接服务就显得非常重要。(短链接还可以使的生成的二维码色块更大,提高识别速度) 国内常见的短地址服务有新浪 百度 那么他们是怎么实现的呢? 建议先阅读参考资料1 2. 实现&原理 2.1 实现 萌叔受到参考资料1的启发也实现了一版。 vearne/tinyurl 代码及使用步骤见README 你也可以 在线尝试 2.2 生成短地址 1) 将长地址与一个整数建立映射(一对多) 这里整数使用int64,保存映射关系。笔者为了简单使用是MySQL数据库,如果为了更好的并发存储,还可以NoSQL数据库或者数据分分库分表。 “https://github.com/vearne/tinyurl” -> 10363 这里主键id就是整数值 长地址存储在url字段中 +——-+———————————+———————+ | id | url | created_at | +——-+———————————+———————+ | 10000… 继续阅读 聊聊短地址服务的实现