如何编写一个 Pulsar Broker Interceptor 插件
背景
之前写过一篇文章 VictoriaLogs:一款超低占用的 ElasticSearch 替代方案讲到了我们使用 Victorialogs 来存储 Pulsar 消息队列的消息 trace 信息。

而其中的关键的埋点信息是通过 Pulsar 的 BrokerInterceptor 实现的,后面就有朋友咨询这块代码是否开源,目前是没有开源的,不过借此机会可以聊聊如何实现一个 BrokerInterceptor 插件,当前还没有相关的介绍文档。
其实当时我在找 BrokerInterceptor 的相关资料时就发现官方并没有提供对应的开发文档。
只有一个 additional servlet的开发文档,而 BrokerInterceptor 只在 YouTube 上找到了一个社区分享的视频。

虽说看视频可以跟着实现,但总归是没有文档方便。
在这之前还是先讲讲 BrokerInterceptor 有什么用?

其实从它所提供的接口就能看出,在消息到达 Broker 后的一些关键节点都提供了相关的接口,实现这些接口就能做很多事情了,比如我这里所需要的消息追踪。
创建项目
下面开始如何使用 BrokerInterceptor:
首先是创建一个 Maven 项目,然后引入相关的依赖:
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-broker</artifactId>
<version>${pulsar.version}</version>
<scope>provided</scope>
</dependency>
实现接口
然后我们便可以实现 org.apache.pulsar.broker.intercept.BrokerInterceptor 来完成具体的业务了。
在我们做消息追踪的场景下,我们实现了以下几个接口:
- messageProduced
- messageDispatched
- messageAcked
以 messageProduced 为例,需要解析出消息ID,然后拼接成一个字符串写入 Victorialogs 存储中,其余的两个埋点也是类似的。
@Override
public void messageProduced(ServerCnx cnx, Producer producer, long startTimeNs, long ledgerId, long entryId,
Topic.PublishContext publishContext) {
String ns = getNs(producer.getTopic().getName());
if (!LogSender.checkNamespace(ns)) {
return;
} String topic = producer.getTopic().getName();
String partition = getPartition(topic);
String msgId = String.format("%s:%s:%s", ledgerId, entryId, partition);
String s = new Event.Publish(msgId, producer.getClientAddress(), System.currentTimeMillis(),
producer.getProducerName(), topic).toString();
LogSender.send(s);
}
编写项目描述文件
我们需要创建一个项目描述文件,路径如下:
src/main/resources/META-INF/services/broker_interceptor.yml
名字也是固定的,broker 会在启动的时候读取这个文件,其内容如下:
name: interceptor-name
description: description
interceptorClass: com.xx.CustomInterceptor
重点是填写自定义实现类的全限定名。
配置打包插件
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-nar-maven-plugin</artifactId>
<version>1.2.0</version>
<extensions>true</extensions>
<configuration>
<finalName>${project.artifactId}-${project.version}</finalName>
</configuration>
<executions>
<execution>
<id>default-nar</id>
<phase>package</phase>
<goals>
<goal>nar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
由于 Broker 识别的是 nar 包,所以我们需要配置 nar 包插件,之后使用 mvn package 就会生成出 nar 包。
配置 broker.conf
我们还需要在 broker.conf 中配置:
brokerInterceptors: "interceptor-name"
也就是刚才配置的插件名称。
不过需要注意的是,如果你是使用 helm 安装的 pulsar,在 3.1 版本之前需要手动将brokerInterceptors 写入到 broker.conf 中。
FROM apachepulsar/pulsar-all:3.0.1
COPY target/interceptor-1.0.1.nar /pulsar/interceptors/
RUN echo "\n" >> /pulsar/conf/broker.conf
RUN echo "brokerInterceptors=" >> /pulsar/conf/broker.conf
不然在最终容器中的 broker.conf 中是读取不到这个配置的,导致插件没有生效。
我们是重新基于官方镜像打的一个包含自定义插件的镜像,最终使用这个镜像进行部署。
https://github.com/apache/pulsar/pull/20719
我在这个 PR 中已经将配置加入进去了,但得在 3.1 之后才能生效;也就是在 3.1 之前都得加上加上这行:
RUN echo "\n" >> /pulsar/conf/broker.conf
RUN echo "brokerInterceptors=" >> /pulsar/conf/broker.conf
目前来看 Pulsar 的 BrokerInterceptor 应该使用不多,不然使用 helm 安装时是不可能生效的;而且官方文档也没用相关的描述。
如何编写一个 Pulsar Broker Interceptor 插件的更多相关文章
- 编写一个简单的Jquery插件
1.实现内容 定义一个简单的jquery插件,alert传递进来的参数 2.插件js文件(jquery.showplugin.js) (function ($) { //定义插件中的方法 var me ...
- 如何自己编写一个easyui插件续
接着如何自己编写一个easyui插件继续分享一下如何从上一节写的“hello”插件继承出一个“hello2”. 参考了combobox的源码中继承combo,当然我这个简单很多了.都是根据自己的理解来 ...
- 如何自己编写一个easyui插件
本文介绍如何通过参考1.4.2版本的progressbar的源码自己编写一个HelloWorld级别的easyui插件,以及如何拓展插件的功能. 有利于我们理解easyui插件的实现,以及了解如何对e ...
- 如何编写一个gulp插件
很久以前,我们在"细说gulp"随笔中,以压缩JavaScript为例,详细地讲解了如何利用gulp来完成前端自动化. 再来短暂回顾下,当时除了借助gulp之外,我们还利用了第三方 ...
- 从零开始编写一个vue插件
title: 从零开始编写一个vue插件 toc: true date: 2018-12-17 10:54:29 categories: Web tags: vue mathjax 写毕设的时候需要一 ...
- 自己动手编写一个VS插件(五)
作者:朱金灿 来源:http://blog.csdn.net/clever101 继续编写VisualStudio插件.这次我编写的插件叫DevAssist(意思是开发助手).在看了前面的文章之后你知 ...
- Hexo+NexT(六):手把手教你编写一个Hexo过滤器插件
Hexo+NexT介绍到这里,我认为已经可以很好地完成任务了.它所提供的一些基础功能及配置,都已经进行了讲解.你已经可以随心所欲地配置一个自己的博客环境,然后享受码字的乐趣. 把博客托管到Github ...
- 如何编写一个WebPack的插件原理及实践
_ 阅读目录 一:webpack插件的基本原理 二:理解 Compiler对象 和 Compilation 对象 三:插件中常用的API 四:编写插件实战 回到顶部 一:webpack插件的基本原理 ...
- Viper 微服务框架 编写一个hello world 插件-02
1.Viper是什么? Viper 是.NET平台下的Anno微服务框架的一个示例项目.入门简单.安全.稳定.高可用.全平台可监控.底层通讯可以随意切换thrift grpc. 自带服务发现.调用链追 ...
- WordPress插件制作教程(二): 编写一个简单的插件
上一篇说到了如何创建一个插件,我想大家看了之后一定会有所收获,这一篇简单给大家写一个插件样例,让大家有一个基本的印象.这个插件的样例就是当你激活这个插件后会在你的每篇文章中插入一段自己定义好的内容,比 ...
随机推荐
- P1830题解
思路: 利用桶存储轰炸区域,双重循环. 在存储轰炸区域时将次数刷新,也就是pos[j][k]=i;. 下面是核心代码: for(int i=1;i<=x;i++) { int x1,x2,y1, ...
- vscod 配置 morkdown 快捷键
vscod 配置 morkdown 快捷键 1.首先在根目录添加.vscode 文件夹 ️1.1 新建一个 settings.json 文件 { "[markdown]": { & ...
- 两种方式,创建有返回值的DB2函数
函数场景:路径信息由若干个机构编码组成,且一个机构编码是9位字符. 要求:获取路径信息,并且删除路径中包含'99'开头的机构编码. 从客户端及服务器端分别创建ignore99(pathinfo var ...
- 各种SQL连接符Join
一.连接符分类,内连接,外连接 1.内连接:Inner Join简写Join. 2.外连接:Left Outer Join 简写Left Join:Right Outer Join 简写Right J ...
- WEB项目开发流程介绍
web开发流程 web开发流程图 一.需求分析阶段 在需求分析阶段,即上图所述 "需求明确"之前的阶段 产品经理PM召集需要项目相关人员,开需求讨论会.讲解原型 相关人员需要以此了 ...
- 【前端小技巧】如何使用 Eolink Apilkit 调用 Mock ?
在开发过程中,进度比较赶的情况下,前端人员当页面写完时,后台的接口还没写完,等要交付的时候后端才把接口给你,这个时候就很尴尬. 这个时候 Mock 就可以很好的解决这个问题,前端团队可以在 API 还 ...
- Chromium Mojo通信
Mojo 是一个跨平台 IPC 框架,它诞生于 chromium ,用来实现 chromium 进程内/进程间的通信.目前,它也被用于 ChromeOS. 在我们代码应用中,如何使用Mojo来作进程间 ...
- 安装 Android x86 并开启 arm 兼容
安装 Android x86 并开启 arm 兼容 Win 11 下开启了 Hyper-v,尝试了各种安卓模拟器,要么不能设置代理(BlueStacks),要么/system目录没办法设置. 获取 A ...
- 针对Jupter Kernel error的问题解决
首先打开Anaconda Prompt 输入jupyter kernelspec list查看安装的内核和位置 到显示的的目录下面找到 kernel.josn这个文件 修改为现在的python环境路径 ...
- 1.参考例5.2.1,设计一个序列检测器。功能是检测出串行输入数据Sin中的4位二进制序列0101(自左至右输入),当检测到该序列时,输入Out=1;没有检测到该序列时,输入Out=0。要求不考虑序列重叠,如010101的序列中只包含一个0101序列。
设计块: module Detector2 ( input CP,Sin,nCR, output reg Out ); reg [1:0] Current_state,Next_state; para ...