Distributed Tracing System Preface Trace有什么用 从最早期的巨石单体(Monolithic)到分布式(Distributed),再到微服务(Microservices)、容器化(Containerization)、容器编排(Container Orchestration),最后到服务网格(Service Mesh)、无服务器(Serverless),复杂度不断提升,问题定位越来越复杂
Trace可以快速定位问题 + 理清网络拓扑 OpenTracing OpenTracing是业务、框架等代码与分布式追踪实现厂商(如jaeger、zipkin、skywalking)之间的一层标准层。OpenTracing通过提供平台无关、厂商无关的API,使得开发人员能够方便的添加(或更换)追踪系统的实现。
基于antlr4构建规则引擎简介 1.什么是antlr ANTLR (ANother Tool for Language Recognition) 是一个强大的文本或者二进制文件解析工具,被广泛应用于构建语法以及各种工具和框架。如
Twitter’s search query language MySQL Workbench Hibernate Trino (SQL query engine) … antlr可以对某一种语言描述,根据对应的语法,生成一颗语法树,在这颗语法树中包含了语言描述与对应语法规则的关系。当你去遍历这颗语法树时,可以灵活处理遍历前和遍历后的规则,实现某种效果。(可以理解为根据一组确定的语法规则,处理一段数据,如实现某种声明、运算、调用等,从而得到某种结果)
以container_memory_usage_bytes作为memory指标 过去的一段时间内,xxx服务在prometheus上面用来监控内存的指标是以容器内存使用量(率)来衡量的,如下:
container_memory_usage_bytes{pod=~"xxx.*-[^-]*-[^-]*$", image!="", container!="POD"}*100/container_spec_memory_limit_bytes{pod=~"xxx.*-[^-]*-[^-]*$", image!="", container!="POD"} > 80.0 xxx服务在kubernetes中的资源配置情况如下,
resources: limits: cpu: "2" memory: "4Gi" requests: cpu: "100m" memory: "512Mi" 在这样的配置下,上面监控rule的语义就是,当容器内使用内存量达到容器最大内存(4G)的80%时发出告警。
优雅退出 这一篇是为了解决引入buffer后,如何保证数据不丢失?
简单介绍一下问题,如下图,通过open api传入的message会在buffer中囤积到一定量后进行处理,引入buffer是为了减少mysql的压力,减少对于数据库的频繁读写。但是由于buffer是内存中的一个数据结构,那么如何保证数据不丢失呢?
数据丢失的情况可能发生于:(1)升级部署时;(2)pod重启时;(3)极端情况,如断电等。
在公有云情况下,可以先忽略极端情况,云服务商会有一定的保障策略。因此只需要把目光聚集到(1)和(2)两点。 其实可以业界有很多可以参考的例子,比如mysql的redo log和redis的aof都可以一定程度保证在发生问题的时候数据的完整性,但是如果在我们的服务中实现这样的东西太重了,个人认为其实保障数据完整性是一个很通用的需求,应该会有一些开源的项目支持(但是没有找到,不过我认为这是一个赚star的好机会)。
回到主要问题,考虑到我们的服务都是java的服务,有一种简单的方法可以实现在应用退出的时候优雅停机:使用java提供的shutdown hook来做这个事情(在spring boot中也有类似的东西,通过@PreDestroy注解来实现,不过追到底还是shutdown hook),当jvm收到退出的信号时,调用shutdown hook内的方法,完成清理操作。
shutdown hook可以保证在应用主动关闭、代码中调用System#exit、OOM、终端Ctrl+C等情况下被调用,对于我们看重的(1)(2)来说,可以很好的解决问题,举个例子增加如下hook:
Eviction Policy 在caffeine中缓存的管理使用的是Window TinyLFU(W-TinyLFU)的技术,结构如下图
先来解释一下各个部分:
window cache(绿色部分): 新对象存入的区域;考虑到缓存的驱逐策略是基于类似LFU的粗略,这里的window cache是对新加入对象的一个保护策略,这些对象会现在window cache中呆一段时间,然后累积一定的frequency之后(LRU策略将其淘汰的时候)才会到TinyLFU中与其他缓存进行frequency的battle,决定去留; main cache (红色和蓝色部分):大部分缓存所在的区域; TinyLFU (紫色部分,一个admission filter):当window cache空间存满之后,来自window cache区域的victim将会和来自main cache区域的victim进行比较,判断二者出现频率的大小,如果前者更大,那么将会将前者插入main cache,淘汰掉后者;反之,淘汰掉前者;