Zookeeper客户端Curator的事件监听详解
0x00 Curator 事件监听
Curator 事件有两种模式,一种是标准的观察模式,一种是缓存监听模式。标准的监听模式是使用Watcher监听器。缓存监听模式引入了一种本地缓存视图的Cache机制,来实现对Zookeeper服务端事件监听。
Cache事件监听可以理解为一个本地缓存视图与远程Zookeeper视图的对比过程。Cache提供了反复注册的功能。Cache是一种缓存机制,可以借助Cache实现监听。简单来说,Cache在客户端缓存了znode的各种状态,当感知到zk集群的znode状态变化,会触发event事件,注册的监听器会处理这些事件。
Watcher监听器比较简单,只有一种。Cache 事件监听的种类有3种Path Cache,Node Cache,Tree Cache。
0x01 Watcher 标准的事件处理器
在ZooKeeper中,接口类Watcher用于表示一个标准的事件处理器,其定义了事件通知相关的逻辑,包含KeeperState和EventType两个枚举类,分别代表了通知状态和事件类型。
Watcher接口定义了事件的回调方法:process(WatchedEvent event)。定义一个Watcher的实例很简单,代码如下:
123456Watcher w = new Watcher() { @Override public void process(WatchedEvent watchedEvent) { log.info("监听器watchedEvent:" + watchedEvent); }};
使用Watcher监听器实例的方式也很简单,在Curator的调用链上,加上usingWatcher方法即可,代码如下:
12byte[] ...
Springboot应用打包和部署脚本
除了常规的CICD打包部署,有时候不得不自己写脚本打包部署应用,这两个脚本作为记录,避免后续需要时候重复编写shell脚本,浪费时间。
打包
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485#!/bin/bash -xAPP_NAME=demoCODE_BASE=$(cd "$(dirname "$0")";pwd)TEMP_DIR=./targetTAR_NAME=${APP_NAME}.tar.gzJAR_NAME=${APP_NAME}.jarclean(){ if [[ -d $TEMP_DIR ]]; then echo "[$(color 'blue' 'INFO')] $(color 'cyan' '1. Delete target directory')" rm -rf $TEMP_DIR fi if [[ -a $TAR_NAME ]]; then echo "[$(color 'blue' 'INFO')] $(color 'cyan' '2. Delete tar file')" rm $TAR_NAME ...
Zookeeper Curator处理会话过期Session Expired
什么是zookeeper的会话过期?
一般来说,我们使用zookeeper是集群形式,如下图,client和zookeeper集群(3个实例)建立一个会话session。
在这个会话session当中,client其实是随机与其中一个zk provider建立的链接,并且互发心跳heartbeat。zk集群负责管理这个session,并且在所有的provider上维护这个session的信息,包括这个session中定义的临时数据和监视点watcher。
如果再网络不佳或者zk集群中某一台provider挂掉的情况下,有可能出现connection loss的情况,例如client和zk provider1连接断开,这时候client不需要任何的操作(zookeeper api已经给我们做好了),只需要等待client与其他provider重新连接即可。这个过程可能导致两个结果:
在session timeout之内连接成功
这个时候client成功切换到连接另一个provider例如是provider2,由于zk在所有的provider上同步了session相关的数据,此时可以认为无缝迁移了。
在session timeout之内没有重新连接
这就是session expire的情况,这时候zookeeper集群会任务会话已经结束,并清除和这个session有关的所有数据,包括临时节点和注册的监视点 Watcher。
在session超时之后,如果client重新连接上了zookeeper集群,很不幸,zookeeper会发出session expired异常,且不会重建session,也就是不会重建临时数据和watcher。
如何使用curator实现session expired异常的捕获和处理?
首先我们先创建一个链接
这里设置了重试策略retryPolicy和会 ...
Zookeeper注册节点断掉后自动重新注册
熟悉的配方——dubbo注册原理
了解Zookeeper注册节点的之前,我们先看看我们熟悉的dubbo是如何利用Zookeeper做服务的注册和订阅的。
在dubbo的整体架构设计中,注册中心的节点结构示意图如图1。图中各个圆代表一个节点path。
/dubbo:这是Dubbo在Zookeeper上创建的根节点。
/dubbo/com.foo.barService:这是服务节点,代表了Dubbo的一个服务。
/dubbo/com.foo.barService/providers:这是服务提供者的根节点,其子节点代表了每一个服务的真正提供者。
/dubbo/com.foo.barService/consumers:这是服务消费者的根节点,其子节点代表了每一个服务的真正消费者。
/dubbo/com.foo.barService/providers/192.168.6.148:这是服务真正的提供者。
服务提供者
服务提供者在服务初始化的时候,首先会在Zookeeper的/dubbo/com.foo.barService/providers节点下创建一个子节点,并写入自己的URL地址,这就代表了com.foo.barService的一个服务提供者。
服务消费者
服务消费者会在服务启动的时候,读取并订阅Zookeeper上/dubbo/com.foo.barService/providers节点下所有的子节点,并解析出所有服务提供者的地址来作为服务地址列表,然后发起正常调用。
同时,服务消费者还会在Zookeeper的/dubbo/com.foo.barService/consumers节点下创建一个临时节点,并写入自己的URL地址,这就代表com.foo.barService的一个服务消费者。
监控中心
监控中心是Dubbo服务治理中的重要一部分,其需要知道一个服务的所有提 ...
批量删除redis数据库中的key
线下环境测试时,由于配置的命名空间未做隔离,造成开发环境和测试环境中的数据污染,现需要批量删除两个命名空间下的数据:nlas和nlas-test。
特别说明:redis中命名空间,只是一种叫法,其实就是固定的key前缀,且以冒号:做分隔(当然也可以是其他分隔符,只要符合key命名规范)。
redis客户端本身不支持指定固定key前缀的批量删除操作,但我们可以借助linux的管道符处理工具对其操作。redis-cli是redis的命令行客户端,可以通过命令的方式执行redis的命令,此处我们要执行keys和del命令。xargs是linux的管道符命令。
下面就以删除nlas:命令空间为例:
1redis-cli -h 10.59.6.54 -p 6379 -a B213547b69b13224 -n 0 keys "nlas:*" | xargs -r -t -n1 redis-cli -h 10.59.6.54 -p 6379 -a B213547b69b13224 -n 0 del
执行,删除成功!
本质上,上面命令分为两个部分执行:1、先登录查出需要删掉的key;2、把1中结果当成删除命令的参数,这个参数用xrgs接收,并给删除指令。
redis-cli命令解释:
-h host
-p port
-a auth
-n 选择库,-n 1相当于select 1
这就登录了,然后执行keys "nlas:*"查询符合条件的key。
xargs命令参数解释:
-r no-run-if-empty,如果参数为空不执行后面的命令。
-t 先打印执行命令,然后再执行。
-n1 传入的参数没批执行几条,-n1,1就是每次传入1个值执行一次。
Aerospike客户端常用命令
Aerospike提供一套类SQL操作,和Mysql语法极其相似(命令解析参考注释),在安装aerospike的服务器上,通过aql --help 可以查看系统提供的帮助文档,里面还有很多DEMO语句。然后通过aql -h ip -p port 连上服务器(直接aql默认连接127.0.0.1 3000)。
AS常用命令
登录AS:先登录到服务器上,然后直接输入命令:aql
连接:aql -p 3000 -h 192.168.0.1
显示所有命名空间:show namespaces(namespace类似mysql的db)
12345678910aql> show namespaces+------------+| namespaces |+------------+| "ns1" || "ns11" |+------------+[127.0.0.1:3000] 2 rows in set (0.002 secs)OK
显示所有表(集合):show sets(sets类似mysql中的table,相当于mysql中的show tables)
12345678910111213aql> show sets+-------------+--------+--------------+------+------+-------------+--------+-----------+------+| disable-eviction | ns | set-enable-xdr | objects | stop-writes-count | set | memory_data_bytes | truncate_lut | tombstones |+---------- ...
GrayLog日志分析脚本
日志聚合工具中的后起之秀-GrayLog,是一个开源的日志聚合、分析、审计、展现和预警工具。在功能上来说,和 ELK 类似,但又比 ELK 要简单很多。依靠着更加简洁,高效,部署使用简单的优势很快受到许多人的青睐。
本文不涉及graylog的工作流程以及架构设计的介绍,只介绍其三个查询数据的接口。
接口介绍
查询结束时间点的日志
api/load_logs_with_time接口查询当前时间最新的日志(如果查询条件中给定了end_time,最新的日志则是end_time之前的400条数据)。该接口时GET方式,写脚本的时候需要将将查询参数经过URLENCODE编码才可以使用。
三个参数:
start_time: 开始时间,非必须
end_time: 结束时间,非必须
query: 查询条件,非必须,查询条件支持字段A:值1 AND 字段B:值2的方式表示查询字段A包含值1并且字段B包含值2,其中AND也可以用OR,表示或。字段A和字段B也可以相同。举个例子:app:demo AND message:“测试” AND message:“youzan”,表示查询应用为deme,并且日志消息包含测试以及youzan。
向前查询日志
api/load_older_logs接口是向前查询数据,从什么时候开始向前,这个参数用end_time限定,end_time一般是load_logs_with_time接口的第一调用之后返回的第一条数据的时间戳,也就是load_logs_with_time接口的起始时间戳。不过,需要注意的是,可能返回的时间戳是UTC时间,比北京时间晚8个小时。
该接口是POST方法。
查询最新日志
api/load_newer_logs接口是向后查询最新的数据,查询方法和api/load_older_logs相似。
自动化脚本
脚本的作用是检索请求接口的耗时,我 ...
maven编译jmc缺少javax.mail:dsn:1.4依赖包的解决方法
0x00 记录病例
在本地编译 jmc(JDK Mission Control)7.1 时,需要构建releng/third-party,由于某些条件的约束限制,不能在 maven 公共仓库中下载javax.mail:dsn:jar:1.4的jar包。
错误信息如下:
1234567891011121314151617181920212223$ mvn p2:site...[info] [JAR] jakarta.activation-1.2.1.jar[info] Resolving artifact=[javax.mail:dsn:1.4] transitive=[true] source=[false]Downloading: http://maven.aliyun.com/nexus/content/groups/public/javax/mail/dsn/1.4/dsn-1.4.pomDownloading: http://repository.ops4j.org/maven2/javax/mail/dsn/1.4/dsn-1.4.pom[WARNING] The POM for javax.mail:dsn:jar:1.4 is missing, no dependency information availableDownloading: http://maven.aliyun.com/nexus/content/groups/public/javax/mail/dsn/1.4/dsn-1.4.jarDownloading: http://repository.ops4j.org/maven2/javax/mail/dsn/1.4/dsn-1.4.jar[INFO] --------------------------------------------- ...
离线安装OpenSearch和k-NN插件
Open Distro 项目将 Elasticsearch 和 Kibana 的开源发行版与 Apache-2.0 许可插件捆绑在一起,为用户提供企业级功能、安全性和分析工具。自推出以来的两年中,世界各地的开发者都使用 Open Distro 来支持他们的应用程序。
开源 Elasticsearch 和 Kibana 7.10.2 即将结束生命周期,不再接受积极的开发、安全补丁或错误修复。所有用户都应该运行能够及时收到安全补丁的软件。启动 OpenSearch 项目的目的是为开源 Elasticsearch 和 Open Distro 用户提供一条前进的道路,以确保他们始终能够获得安全性和新的创新。
以上引用官网文档《https://opendistro.github.io/for-elasticsearch/#prod》
x000 下载软件包
K-NN是Amazon公司开发并开源的一款支持ElasticSearch的相似向量检索插件,而且搜索速度和效果比ElasticSearch原生的插件更好,为产品推荐、欺诈检测、图像和视频搜索、相关文档搜索等场景提供支持。
根据官方的描述,k-NN非常符合我们的业务场景——图像的黑样本检测。离线或者在线黑样本图像入库并打标签属性,入库时提取图像特征(256维度)并将其和标签属性一起保存到ElasticSearch中,业务的每一笔调用(调用ES检索之前先通过算法提取特诊,实际上是特征维度的向量检索)通过检索ES黑样本库,判定检索的图像是否在黑样本中。
和k-NN插件能够配套的ElasticSearch是社区版,由Amazon维护,属于Open Dist ...
JFR(Java Flight Recorder)使用教程
0x00 概念
JFR,全称为Java Flight Recorder,简称JFR,是Oracle JDK的商业特性,JFR数据是JVM的历史事件,用来诊断JVM的历史性能和操作,该数据是作为时间上的数据点(称为事件)记录的。是一种监控工具,可以在Java应用程序执行期间收集有关JVM事件的信息。JFR会开启一组事件,当有对应的事件发生时,就会保留相应的数据到文件中或者内存中(假如有开启缓存池),JMC可以显示这些事件——实时从JVM获取或者从文件中获取,JMC可以展示详细的JFR记录的数据。JFR对于被监控的应用程序来说,默认设置的性能开销很低:程序性能的1%以下,但是随着开始的事件或者记录线程增多,性能开销也会随之增多。
JFR有两种主要的概念:事件和数据流。
0x00_01 事件
JFR在Java应用运行时收集对应发生的事件,主要有三种类型的事件提供给JFR收集:
即时事件:一旦事件发生会立即进行数据记录
持续事件:如果持续时间超过指定阈值则进行数据记录
简单事件:用于记录应用所在系统的活跃指标(例如CPU,内存等)
0x00_02 数据流
JFR收集的事件包含大量数据,将这些数据保存在filename.jfr中,众所周知,磁盘I/O操作非常昂贵。因此,在将数据块刷新到磁盘之前,JFR使用各种缓存来存储收集的数据。因为加入缓存的原因,在某些情况下,JFR的数据存在丢失的可能性。如果发生丢失数据的情况,JFR会尝试通知输出文件,丢失了一部分的信息。
0x01 使用
0x01_01 开启配置
在应用启动配置的JVM参数中,增加以下两个配置参数开启JFR:
12# 加上以下的这两个参数即可开启对应的JFR功能-XX:+UnlockCommercialFeatures -XX:+FlightRecorder
0x01_02 解锁JFR特征
12#解锁JFR记录功能权限jc ...