背景
之前寫過一篇文章 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 安裝時是不可能生效的;而且官方文件也沒用相關的描述。