blob: 7fd208fbd071c9545c3c7b533c9157b5b1b73cce [file] [log] [blame]
import{_ as c,r as e,o as l,c as i,b as s,d as n,a,w as u,e as p}from"./app-Bx8hKGcu.js";const k={},r=p('<h2 id="触发器" tabindex="-1"><a class="header-anchor" href="#触发器"><span>触发器</span></a></h2><p>触发器提供了一种侦听序列数据变动的机制。配合用户自定义逻辑,可完成告警、数据清洗、数据转发等功能。</p><p>触发器基于 Java 反射机制实现。用户通过简单实现 Java 接口,即可实现数据侦听。IoTDB 允许用户动态装载、卸载触发器,在装载、卸载期间,无需启停服务器。</p><p>根据此文档,您将会很快学会触发器的编写与管理。</p><h3 id="编写触发器" tabindex="-1"><a class="header-anchor" href="#编写触发器"><span>编写触发器</span></a></h3><h4 id="触发器依赖" tabindex="-1"><a class="header-anchor" href="#触发器依赖"><span>触发器依赖</span></a></h4><p>触发器的逻辑需要您编写 Java 类进行实现。</p>',7),d={href:"http://search.maven.org/",target:"_blank",rel:"noopener noreferrer"},v={href:"http://search.maven.org/",target:"_blank",rel:"noopener noreferrer"},m=p(`<div class="language-xml line-numbers-mode" data-ext="xml" data-title="xml"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.apache.iotdb<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>iotdb-server<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>0.13.0-SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>provided<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>请注意选择和目标服务器版本相同的依赖版本。</p><h4 id="用户编程接口" tabindex="-1"><a class="header-anchor" href="#用户编程接口"><span>用户编程接口</span></a></h4><p>编写一个触发器需要实现<code>org.apache.iotdb.db.engine.trigger.api.Trigger</code>类。</p><p>该类提供了两类编程接口:<strong>生命周期钩子</strong>和<strong>数据变动侦听钩子</strong>。该类中所有的接口都不是必须实现的,当您不实现它们时,它们不会对流经的数据操作产生任何响应。您可以根据实际需要,只实现其中若干接口。</p><p>下面是所有可供用户进行实现的接口的说明。</p><h5 id="生命周期钩子" tabindex="-1"><a class="header-anchor" href="#生命周期钩子"><span>生命周期钩子</span></a></h5><table><thead><tr><th style="text-align:left;">接口定义</th><th>描述</th></tr></thead><tbody><tr><td style="text-align:left;"><code>void onCreate(TriggerAttributes attributes) throws Exception</code></td><td>当您使用<code>CREATE TRIGGER</code>语句注册触发器后,该钩子会被调用一次。在每一个实例的生命周期内,该钩子会且仅仅会被调用一次。该钩子主要有如下作用:1. 帮助用户解析 SQL 语句中的自定义属性(使用<code>TriggerAttributes</code>)。 2. 创建或申请资源,如建立外部链接、打开文件等。</td></tr><tr><td style="text-align:left;"><code>void onDrop() throws Exception</code></td><td>当您使用<code>DROP TRIGGER</code>语句删除触发器后,该钩子会被调用。在每一个实例的生命周期内,该钩子会且仅仅会被调用一次。该钩子的主要作用是进行一些资源释放等的操作。</td></tr><tr><td style="text-align:left;"><code>void onStart() throws Exception</code></td><td>当您使用<code>START TRIGGER</code>语句手动启动(被<code>STOP TRIGGER</code>语句停止的)触发器后,该钩子会被调用。</td></tr><tr><td style="text-align:left;"><code>void onStop() throws Exception</code></td><td>当您使用<code>STOP TRIGGER</code>语句手动停止触发器后,该钩子会被调用。</td></tr></tbody></table><h5 id="数据变动侦听钩子" tabindex="-1"><a class="header-anchor" href="#数据变动侦听钩子"><span>数据变动侦听钩子</span></a></h5><p>目前触发器仅能侦听数据插入的操作。</p><p>数据变动侦听钩子的调用时机由<code>CREATE TRIGGER</code>语句显式指定,在编程接口层面不作区分。</p><h6 id="单点数据插入侦听钩子" tabindex="-1"><a class="header-anchor" href="#单点数据插入侦听钩子"><span>单点数据插入侦听钩子</span></a></h6><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token class-name">Integer</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span> timestamp<span class="token punctuation">,</span> <span class="token class-name">Integer</span> value<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
<span class="token class-name">Long</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span> timestamp<span class="token punctuation">,</span> <span class="token class-name">Long</span> value<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
<span class="token class-name">Float</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span> timestamp<span class="token punctuation">,</span> <span class="token class-name">Float</span> value<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
<span class="token class-name">Double</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span> timestamp<span class="token punctuation">,</span> <span class="token class-name">Double</span> value<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
<span class="token class-name">Boolean</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span> timestamp<span class="token punctuation">,</span> <span class="token class-name">Boolean</span> value<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
<span class="token class-name">Binary</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span> timestamp<span class="token punctuation">,</span> <span class="token class-name">Binary</span> value<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>对于注册序列上的每一点数据插入,触发器都会调用<code>fire</code>作为响应,钩子的入参<code>timestamp</code>和<code>value</code>即是这一次插入数据点的时间和数据值。您可以在<code>fire</code>钩子中编写处理数据的任意逻辑。</p><p>注意,目前钩子的返回值是没有任何意义的。</p><h6 id="批量数据插入侦听钩子" tabindex="-1"><a class="header-anchor" href="#批量数据插入侦听钩子"><span>批量数据插入侦听钩子</span></a></h6><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">[</span><span class="token punctuation">]</span> timestamps<span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> values<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
<span class="token keyword">long</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">[</span><span class="token punctuation">]</span> timestamps<span class="token punctuation">,</span> <span class="token keyword">long</span><span class="token punctuation">[</span><span class="token punctuation">]</span> values<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
<span class="token keyword">float</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">[</span><span class="token punctuation">]</span> timestamps<span class="token punctuation">,</span> <span class="token keyword">float</span><span class="token punctuation">[</span><span class="token punctuation">]</span> values<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
<span class="token keyword">double</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">[</span><span class="token punctuation">]</span> timestamps<span class="token punctuation">,</span> <span class="token keyword">double</span><span class="token punctuation">[</span><span class="token punctuation">]</span> values<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
<span class="token keyword">boolean</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">[</span><span class="token punctuation">]</span> timestamps<span class="token punctuation">,</span> <span class="token keyword">boolean</span><span class="token punctuation">[</span><span class="token punctuation">]</span> values<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
<span class="token class-name">Binary</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">[</span><span class="token punctuation">]</span> timestamps<span class="token punctuation">,</span> <span class="token class-name">Binary</span><span class="token punctuation">[</span><span class="token punctuation">]</span> values<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果您需要在业务场景中使用到 Session API 的<code>insertTablet</code>接口或<code>insertTablets</code>接口,那么您可以通过实现上述数据插入的侦听钩子来降低触发器的调用开销。</p><p>推荐您在实现上述批量数据插入的侦听钩子时, 保证批量数据插入侦听钩子与单点数据插入侦听钩子的行为具有一致性。当您不实现批量数据插入的侦听钩子时,它将遵循下面的默认逻辑。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">default</span> <span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">[</span><span class="token punctuation">]</span> timestamps<span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> values<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
<span class="token keyword">int</span> size <span class="token operator">=</span> timestamps<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> size<span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">fire</span><span class="token punctuation">(</span>timestamps<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> values<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> values<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>注意,目前钩子的返回值是没有任何意义的。</p><h5 id="重要注意事项" tabindex="-1"><a class="header-anchor" href="#重要注意事项"><span>重要注意事项</span></a></h5><ul><li>每条序列上注册的触发器都是一个完整的触发器类的实例,因此您可以在触发器中维护一些状态数据。</li><li>触发器维护的状态会在系统停止后被清空(除非您在钩子中主动将状态持久化)。换言之,系统启动后触发器的状态将会默认为初始值。</li><li>一个触发器所有钩子的调用都是串行化的。</li></ul><h3 id="管理触发器" tabindex="-1"><a class="header-anchor" href="#管理触发器"><span>管理触发器</span></a></h3><p>您可以通过 SQL 语句注册、卸载、启动或停止一个触发器实例,您也可以通过 SQL 语句查询到所有已经注册的触发器。</p><h4 id="触发器的状态" tabindex="-1"><a class="header-anchor" href="#触发器的状态"><span>触发器的状态</span></a></h4><p>触发器有两种运行状态:<code>STARTED</code>和<code>STOPPED</code>,您需要执行<code>START TRIGGER</code>或者<code>STOP TRIGGER</code>来启动或者停止一个触发器。</p><p>当一个触发器的状态为<code>STOPPED</code>时,它将不会响应被注册序列上的操作(如插入数据点的操作),对外表现就会像是这个序列没有被注册过触发器一样,但是它会保存所有的状态(触发器类变量)信息,同时也会保存所有的注册信息。</p><p>注意,通过<code>CREATE TRIGGER</code>语句注册的触发器默认是<code>STARTED</code>的。</p><h4 id="注册触发器" tabindex="-1"><a class="header-anchor" href="#注册触发器"><span>注册触发器</span></a></h4><p>触发器只能注册在一个已经存在的时间序列上。任何时间序列只允许注册一个触发器。</p><p>被注册有触发器的序列将会被触发器侦听,当序列上有数据变动时,触发器中对应的钩子将会被调用。</p><p>注册一个触发器可以按如下流程进行:</p><ol><li><p>实现一个完整的 Trigger 类,假定这个类的全类名为<code>org.apache.iotdb.db.engine.trigger.example.AlertListener</code></p></li><li><p>将项目打成 JAR 包,如果您使用 Maven 管理项目,可以参考上述 Maven 项目示例的写法</p></li><li><p>将 JAR 包放置到目录 <code>iotdb-server-0.13.0-SNAPSHOT/ext/trigger</code> (也可以是<code>iotdb-server-0.13.0-SNAPSHOT/ext/trigger</code>的子目录)下。</p><blockquote><p>您可以通过修改配置文件中的<code>trigger_root_dir</code>来指定加载触发器 JAR 包的根路径。</p></blockquote></li><li><p>使用 SQL 语句注册该触发器,假定赋予该触发器的名字为<code>alert-listener-sg1d1s1</code></p></li><li><p>使用<code>CREATE TRIGGER</code>语句注册该触发器</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">CREATE</span> <span class="token keyword">TRIGGER</span> <span class="token identifier"><span class="token punctuation">\`</span>alert-listener-sg1d1s1<span class="token punctuation">\`</span></span>
<span class="token keyword">AFTER</span> <span class="token keyword">INSERT</span>
<span class="token keyword">ON</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">.</span>s1
<span class="token keyword">AS</span> <span class="token string">&#39;org.apache.iotdb.db.engine.trigger.example.AlertListener&#39;</span>
<span class="token keyword">WITH</span> <span class="token punctuation">(</span>
<span class="token string">&#39;lo&#39;</span> <span class="token operator">=</span> <span class="token string">&#39;0&#39;</span><span class="token punctuation">,</span>
<span class="token string">&#39;hi&#39;</span> <span class="token operator">=</span> <span class="token string">&#39;100.0&#39;</span>
<span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li></ol><p>注册触发器的详细 SQL 语法如下:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">CREATE</span> <span class="token keyword">TRIGGER</span> <span class="token operator">&lt;</span><span class="token keyword">TRIGGER</span><span class="token operator">-</span>NAME<span class="token operator">&gt;</span>
<span class="token punctuation">(</span>BEFORE <span class="token operator">|</span> <span class="token keyword">AFTER</span><span class="token punctuation">)</span> <span class="token keyword">INSERT</span>
<span class="token keyword">ON</span> <span class="token operator">&lt;</span><span class="token keyword">FULL</span><span class="token operator">-</span>PATH<span class="token operator">&gt;</span>
<span class="token keyword">AS</span> <span class="token operator">&lt;</span>CLASSNAME<span class="token operator">&gt;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>同时,您还可以通过<code>WITH</code>子句传入任意数量的自定义属性值:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">CREATE</span> <span class="token keyword">TRIGGER</span> <span class="token operator">&lt;</span><span class="token keyword">TRIGGER</span><span class="token operator">-</span>NAME<span class="token operator">&gt;</span>
<span class="token punctuation">(</span>BEFORE <span class="token operator">|</span> <span class="token keyword">AFTER</span><span class="token punctuation">)</span> <span class="token keyword">INSERT</span>
<span class="token keyword">ON</span> <span class="token operator">&lt;</span><span class="token keyword">FULL</span><span class="token operator">-</span>PATH<span class="token operator">&gt;</span>
<span class="token keyword">AS</span> <span class="token operator">&lt;</span>CLASSNAME<span class="token operator">&gt;</span>
<span class="token keyword">WITH</span> <span class="token punctuation">(</span>
<span class="token operator">&lt;</span><span class="token keyword">KEY</span><span class="token operator">-</span><span class="token number">1</span><span class="token operator">&gt;=</span><span class="token operator">&lt;</span><span class="token keyword">VALUE</span><span class="token operator">-</span><span class="token number">1</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
<span class="token operator">&lt;</span><span class="token keyword">KEY</span><span class="token operator">-</span><span class="token number">2</span><span class="token operator">&gt;=</span><span class="token operator">&lt;</span><span class="token keyword">VALUE</span><span class="token operator">-</span><span class="token number">2</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code>TRIGGER-NAME</code>是用于标定触发器的全局唯一 ID,它是大小写敏感的。</p><p>目前触发器可以侦听序列上的所有的数据插入操作,触发器可以选择在数据插入前(<code>BEFORE INSERT</code>)或者数据插入后(<code>AFTER INSERT</code>)触发钩子调用。</p><p><code>FULL-PATH</code>是触发器侦听的目标序列名称,这个序列必须是一个测点。</p><p><code>CLASSNAME</code>是触发器类的全类名。</p><p>请注意,<code>CLASSNAME</code>以及属性值中的<code>KEY</code>和<code>VALUE</code>都需要被单引号或者双引号引用起来。</p><h4 id="卸载触发器" tabindex="-1"><a class="header-anchor" href="#卸载触发器"><span>卸载触发器</span></a></h4><p>触发器会在下面几种情景下被卸载:</p><ol><li>用户执行<code>DELETE TIMESERIES</code>时,序列上注册的触发器会被卸载</li><li>用户执行<code>DELETE STORAGE GROUP</code>时,对应存储组下注册的触发器会全部被卸载</li><li>用户使用<code>DROP TRIGGER</code>语句主动卸载</li></ol><p>卸载触发器的 SQL 语法如下:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">DROP</span> <span class="token keyword">TRIGGER</span> <span class="token operator">&lt;</span><span class="token keyword">TRIGGER</span><span class="token operator">-</span>NAME<span class="token operator">&gt;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p><code>TRIGGER-NAME</code>是用于标定触发器的全局唯一 ID。</p><p>下面是一个<code>DROP TRIGGER</code>语句的例子:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">DROP</span> <span class="token keyword">TRIGGER</span> <span class="token identifier"><span class="token punctuation">\`</span>alert-listener-sg1d1s1<span class="token punctuation">\`</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h4 id="启动触发器" tabindex="-1"><a class="header-anchor" href="#启动触发器"><span>启动触发器</span></a></h4><p>该操作是“停止触发器”的逆操作。它将运行状态为<code>STOPPED</code>的触发器的运行状态变更为<code>STARTED</code>,这会使得触发器重新侦听被注册序列上的操作,并对数据变动产生响应。</p><p>启动触发器的 SQL 语法如下:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">START</span> <span class="token keyword">TRIGGER</span> <span class="token operator">&lt;</span><span class="token keyword">TRIGGER</span><span class="token operator">-</span>NAME<span class="token operator">&gt;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p><code>TRIGGER-NAME</code>是用于标定触发器的全局唯一 ID。</p><p>下面是一个<code>START TRIGGER</code>语句的例子:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">START</span> <span class="token keyword">TRIGGER</span> <span class="token identifier"><span class="token punctuation">\`</span>alert-listener-sg1d1s1<span class="token punctuation">\`</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>注意,通过<code>CREATE TRIGGER</code>语句注册的触发器默认是<code>STARTED</code>的。</p><h4 id="停止触发器" tabindex="-1"><a class="header-anchor" href="#停止触发器"><span>停止触发器</span></a></h4><p>该操作将触发器的状态由<code>STARTED</code>变为<code>STOPPED</code>。当一个触发器的状态为<code>STOPPED</code>时,它将不会响应被注册序列上的操作(如插入数据点的操作),对外表现就会像是这个序列没有被注册过触发器一样。您可以使用<code>START TRIGGER</code>语句重新启动一个触发器。</p><p>停止触发器的 SQL 语法如下:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code>STOP <span class="token keyword">TRIGGER</span> <span class="token operator">&lt;</span><span class="token keyword">TRIGGER</span><span class="token operator">-</span>NAME<span class="token operator">&gt;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p><code>TRIGGER-NAME</code>是用于标定触发器的全局唯一 ID。</p><p>下面是一个<code>STOP TRIGGER</code>语句的例子:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code>STOP <span class="token keyword">TRIGGER</span> <span class="token identifier"><span class="token punctuation">\`</span>alert-listener-sg1d1s1<span class="token punctuation">\`</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h4 id="查询所有注册的触发器" tabindex="-1"><a class="header-anchor" href="#查询所有注册的触发器"><span>查询所有注册的触发器</span></a></h4><p>查询触发器的 SQL 语句如下:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">SHOW</span> TRIGGERS
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>该语句展示已注册触发器的 ID、运行状态、触发时机、被注册的序列、触发器实例的全类名和注册触发器时用到的自定义属性。</p><h4 id="用户权限管理" tabindex="-1"><a class="header-anchor" href="#用户权限管理"><span>用户权限管理</span></a></h4><p>用户在使用触发器时会涉及到 4 种权限:</p><ul><li><code>CREATE_TRIGGER</code>:具备该权限的用户才被允许注册触发器操作。该权限需要与触发器的路径绑定。</li><li><code>DROP_TRIGGER</code>:具备该权限的用户才被允许卸载触发器操作。该权限需要与触发器的路径绑定。</li><li><code>START_TRIGGER</code>:具备该权限的用户才被允许启动已被停止的触发器。该权限需要与触发器的路径绑定。</li><li><code>STOP_TRIGGER</code>:具备该权限的用户才被允许停止正在运行的触发器。该权限需要与触发器的路径绑定。</li></ul>`,73),g=p(`<h3 id="实用工具类" tabindex="-1"><a class="header-anchor" href="#实用工具类"><span>实用工具类</span></a></h3><p>实用工具类为常见的需求提供了编程范式和执行框架,它能够简化您编写触发器的一部分工作。</p><h4 id="窗口工具类" tabindex="-1"><a class="header-anchor" href="#窗口工具类"><span>窗口工具类</span></a></h4><p>窗口工具类能够辅助您定义滑动窗口以及窗口上的数据处理逻辑。它能够构造两类滑动窗口:一种滑动窗口是固定窗口内时间长度的(<code>SlidingTimeWindowEvaluationHandler</code>),另一种滑动窗口是固定窗口内数据点数的(<code>SlidingSizeWindowEvaluationHandler</code>)。</p><p>窗口工具类允许您在窗口(<code>Window</code>)上定义侦听钩子(<code>Evaluator</code>)。每当一个新的窗口形成,您定义的侦听钩子就会被调用一次。您可以在这个侦听钩子内定义任何数据处理相关的逻辑。侦听钩子的调用是异步的,因此,在执行钩子内窗口处理逻辑的时候,是不会阻塞当前线程的。</p><p>值得注意的是,不论是<code>SlidingTimeWindowEvaluationHandler</code>还是<code>SlidingSizeWindowEvaluationHandler</code>,他们都<strong>只能够处理时间戳严格单调递增的序列</strong>,传入的不符合要求的数据点会被工具类抛弃。</p><p><code>Window</code>与<code>Evaluator</code>接口的定义见<code>org.apache.iotdb.db.utils.windowing.api</code>包。</p><h5 id="固定窗口内数据点数的滑动窗口" tabindex="-1"><a class="header-anchor" href="#固定窗口内数据点数的滑动窗口"><span>固定窗口内数据点数的滑动窗口</span></a></h5><h6 id="窗口构造" tabindex="-1"><a class="header-anchor" href="#窗口构造"><span>窗口构造</span></a></h6><p>共两种构造方法。</p><p>第一种方法需要您提供窗口接受数据点的类型、窗口大小、滑动步长和一个侦听钩子(<code>Evaluator</code>)。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">final</span> <span class="token class-name">TSDataType</span> dataType <span class="token operator">=</span> <span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">INT32</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">int</span> windowSize <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">int</span> slidingStep <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span>
<span class="token class-name">SlidingSizeWindowEvaluationHandler</span> handler <span class="token operator">=</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingSizeWindowEvaluationHandler</span><span class="token punctuation">(</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingSizeWindowConfiguration</span><span class="token punctuation">(</span>dataType<span class="token punctuation">,</span> windowSize<span class="token punctuation">,</span> slidingStep<span class="token punctuation">)</span><span class="token punctuation">,</span>
window <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>第二种方法需要您提供窗口接受数据点的类型、窗口大小和一个侦听钩子(<code>Evaluator</code>)。这种构造方法下的窗口滑动步长等于窗口大小。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">final</span> <span class="token class-name">TSDataType</span> dataType <span class="token operator">=</span> <span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">INT32</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">int</span> windowSize <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token class-name">SlidingSizeWindowEvaluationHandler</span> handler <span class="token operator">=</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingSizeWindowEvaluationHandler</span><span class="token punctuation">(</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingSizeWindowConfiguration</span><span class="token punctuation">(</span>dataType<span class="token punctuation">,</span> windowSize<span class="token punctuation">)</span><span class="token punctuation">,</span>
window <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>窗口大小、滑动步长必须为正数。</p><h6 id="数据接收" tabindex="-1"><a class="header-anchor" href="#数据接收"><span>数据接收</span></a></h6><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">final</span> <span class="token keyword">long</span> timestamp <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">int</span> value <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
hander<span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">(</span>timestamp<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>注意,<code>collect</code>方法接受的第二个参数类型需要与构造时传入的<code>dataType</code>声明一致。</p><p>此外,<code>collect</code>方法只会对时间戳是单调递增的数据点产生响应。如果某一次<code>collect</code>方法采集到的数据点的时间戳小于等于上一次<code>collect</code>方法采集到的数据点时间戳,那么这一次采集的数据点将会被抛弃。</p><p>还需要注意的是,<code>collect</code>方法不是线程安全的。</p><h5 id="固定窗口内时间长度的滑动窗口" tabindex="-1"><a class="header-anchor" href="#固定窗口内时间长度的滑动窗口"><span>固定窗口内时间长度的滑动窗口</span></a></h5><h6 id="窗口构造-1" tabindex="-1"><a class="header-anchor" href="#窗口构造-1"><span>窗口构造</span></a></h6><p>共两种构造方法。</p><p>第一种方法需要您提供窗口接受数据点的类型、窗口内时间长度、滑动步长和一个侦听钩子(<code>Evaluator</code>)。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">final</span> <span class="token class-name">TSDataType</span> dataType <span class="token operator">=</span> <span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">INT32</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">long</span> timeInterval <span class="token operator">=</span> <span class="token number">1000</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">long</span> slidingStep <span class="token operator">=</span> <span class="token number">500</span><span class="token punctuation">;</span>
<span class="token class-name">SlidingTimeWindowEvaluationHandler</span> handler <span class="token operator">=</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingTimeWindowEvaluationHandler</span><span class="token punctuation">(</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingTimeWindowConfiguration</span><span class="token punctuation">(</span>dataType<span class="token punctuation">,</span> timeInterval<span class="token punctuation">,</span> slidingStep<span class="token punctuation">)</span><span class="token punctuation">,</span>
window <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>第二种方法需要您提供窗口接受数据点的类型、窗口内时间长度和一个侦听钩子(<code>Evaluator</code>)。这种构造方法下的窗口滑动步长等于窗口内时间长度。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">final</span> <span class="token class-name">TSDataType</span> dataType <span class="token operator">=</span> <span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">INT32</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">long</span> timeInterval <span class="token operator">=</span> <span class="token number">1000</span><span class="token punctuation">;</span>
<span class="token class-name">SlidingTimeWindowEvaluationHandler</span> handler <span class="token operator">=</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingTimeWindowEvaluationHandler</span><span class="token punctuation">(</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingTimeWindowConfiguration</span><span class="token punctuation">(</span>dataType<span class="token punctuation">,</span> timeInterval<span class="token punctuation">)</span><span class="token punctuation">,</span>
window <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>窗口内时间长度、滑动步长必须为正数。</p><h6 id="数据接收-1" tabindex="-1"><a class="header-anchor" href="#数据接收-1"><span>数据接收</span></a></h6><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">final</span> <span class="token keyword">long</span> timestamp <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">int</span> value <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
hander<span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">(</span>timestamp<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>注意,<code>collect</code>方法接受的第二个参数类型需要与构造时传入的<code>dataType</code>声明一致。</p><p>此外,<code>collect</code>方法只会对时间戳是单调递增的数据点产生响应。如果某一次<code>collect</code>方法采集到的数据点的时间戳小于等于上一次<code>collect</code>方法采集到的数据点时间戳,那么这一次采集的数据点将会被抛弃。</p><p>还需要注意的是,<code>collect</code>方法不是线程安全的。</p><h5 id="拒绝策略" tabindex="-1"><a class="header-anchor" href="#拒绝策略"><span>拒绝策略</span></a></h5><p>窗口计算的任务执行是异步的。</p><p>当异步任务无法被执行线程池及时消费时,会产生任务堆积。在极端情况下,异步任务的堆积会导致系统 OOM。因此,窗口计算线程池允许堆积的任务数量被设定为有限值。</p><p>当堆积的任务数量超出限值时,新提交的任务将无法进入线程池执行,此时,系统会调用您在侦听钩子(<code>Evaluator</code>)中制定的拒绝策略钩子<code>onRejection</code>进行处理。</p><p><code>onRejection</code>的默认行为如下。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">default</span> <span class="token keyword">void</span> <span class="token function">onRejection</span><span class="token punctuation">(</span><span class="token class-name">Window</span> window<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">RejectedExecutionException</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>制定拒绝策略钩子的方式如下。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token class-name">SlidingTimeWindowEvaluationHandler</span> handler <span class="token operator">=</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingTimeWindowEvaluationHandler</span><span class="token punctuation">(</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingTimeWindowConfiguration</span><span class="token punctuation">(</span><span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">INT32</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token keyword">new</span> <span class="token class-name">Evaluator</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">evaluate</span><span class="token punctuation">(</span><span class="token class-name">Window</span> window<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">onRejection</span><span class="token punctuation">(</span><span class="token class-name">Window</span> window<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h5 id="配置参数" tabindex="-1"><a class="header-anchor" href="#配置参数"><span>配置参数</span></a></h5><h6 id="concurrent-window-evaluation-thread" tabindex="-1"><a class="header-anchor" href="#concurrent-window-evaluation-thread"><span>concurrent_window_evaluation_thread</span></a></h6><p>窗口计算线程池的默认线程数。默认为 CPU 核数。</p><h6 id="max-pending-window-evaluation-tasks" tabindex="-1"><a class="header-anchor" href="#max-pending-window-evaluation-tasks"><span>max_pending_window_evaluation_tasks</span></a></h6><p>最多允许堆积的窗口计算任务。默认为 64 个。</p><h4 id="sink-工具类" tabindex="-1"><a class="header-anchor" href="#sink-工具类"><span>Sink 工具类</span></a></h4><p>Sink 工具类为触发器提供了连接外部系统的能力。</p><p>它提供了一套编程范式。每一个 Sink 工具都包含一个用于处理数据发送的<code>Handler</code>、一个用于配置<code>Handler</code>的<code>Configuration</code>,还有一个用于描述发送数据的<code>Event</code>。</p><h5 id="localiotdbsink" tabindex="-1"><a class="header-anchor" href="#localiotdbsink"><span>LocalIoTDBSink</span></a></h5><p><code>LocalIoTDBSink</code>用于向本地序列写入数据点。</p><p>在写入数据前,不要求时间序列已被创建。</p><p><strong>注意</strong>,在触发器场景中,侦听的时间序列和写入的目标时间序列不要在同一个存储组下。</p><p>使用示例:</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">final</span> <span class="token class-name">String</span> device <span class="token operator">=</span> <span class="token string">&quot;root.alerting&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> measurements <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">{</span><span class="token string">&quot;local&quot;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">TSDataType</span><span class="token punctuation">[</span><span class="token punctuation">]</span> dataTypes <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TSDataType</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">{</span><span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">DOUBLE</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token class-name">LocalIoTDBHandler</span> localIoTDBHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LocalIoTDBHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
localIoTDBHandler<span class="token punctuation">.</span><span class="token keyword">open</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">LocalIoTDBConfiguration</span><span class="token punctuation">(</span>device<span class="token punctuation">,</span> measurements<span class="token punctuation">,</span> dataTypes<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// insert 100 data points</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">final</span> <span class="token keyword">long</span> timestamp <span class="token operator">=</span> i<span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">double</span> value <span class="token operator">=</span> i<span class="token punctuation">;</span>
localIoTDBHandler<span class="token punctuation">.</span><span class="token function">onEvent</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">LocalIoTDBEvent</span><span class="token punctuation">(</span>timestamp<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>注意,当您需要向某个<code>TEXT</code>类型的序列写入数据时,您需要借助<code>org.apache.iotdb.tsfile.utils.Binary</code>:</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token comment">// insert 100 data points</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">final</span> <span class="token keyword">long</span> timestamp <span class="token operator">=</span> i<span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">String</span> value <span class="token operator">=</span> <span class="token string">&quot;&quot;</span> <span class="token operator">+</span> i<span class="token punctuation">;</span>
localIoTDBHandler<span class="token punctuation">.</span><span class="token function">onEvent</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">LocalIoTDBEvent</span><span class="token punctuation">(</span>timestamp<span class="token punctuation">,</span> <span class="token class-name">Binary</span><span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h5 id="mqttsink" tabindex="-1"><a class="header-anchor" href="#mqttsink"><span>MQTTSink</span></a></h5><p>触发器可以使用<code>MQTTSink</code>向其他的 IoTDB 实例发送数据点。</p><p>在发送数据前,不要求时间序列已被创建。</p><p>使用示例:</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">final</span> <span class="token class-name">String</span> host <span class="token operator">=</span> <span class="token string">&quot;127.0.0.1&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">int</span> port <span class="token operator">=</span> <span class="token number">1883</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">String</span> username <span class="token operator">=</span> <span class="token string">&quot;root&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">String</span> password <span class="token operator">=</span> <span class="token string">&quot;root&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">PartialPath</span> device <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">PartialPath</span><span class="token punctuation">(</span><span class="token string">&quot;root.alerting&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> measurements <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">{</span><span class="token string">&quot;remote&quot;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token class-name">MQTTHandler</span> mqttHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MQTTHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
mqttHandler<span class="token punctuation">.</span><span class="token keyword">open</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">MQTTConfiguration</span><span class="token punctuation">(</span>host<span class="token punctuation">,</span> port<span class="token punctuation">,</span> username<span class="token punctuation">,</span> password<span class="token punctuation">,</span> device<span class="token punctuation">,</span> measurements<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">String</span> topic <span class="token operator">=</span> <span class="token string">&quot;test&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">QoS</span> qos <span class="token operator">=</span> <span class="token class-name">QoS</span><span class="token punctuation">.</span><span class="token constant">EXACTLY_ONCE</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">boolean</span> retain <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token comment">// send 100 data points</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">final</span> <span class="token keyword">long</span> timestamp <span class="token operator">=</span> i<span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token keyword">double</span> value <span class="token operator">=</span> i<span class="token punctuation">;</span>
mqttHandler<span class="token punctuation">.</span><span class="token function">onEvent</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">MQTTEvent</span><span class="token punctuation">(</span>topic<span class="token punctuation">,</span> qos<span class="token punctuation">,</span> retain<span class="token punctuation">,</span> timestamp<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h5 id="alertmanagersink" tabindex="-1"><a class="header-anchor" href="#alertmanagersink"><span>AlertManagerSink</span></a></h5><p>触发器可以使用<code>AlertManagerSink</code> 向 AlertManager 发送消息。</p><p><code>AlertManagerConfiguration</code> 的构造需传入 AlertManager 的发送告警的 endpoint。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token class-name">AlertManagerConfiguration</span><span class="token punctuation">(</span><span class="token class-name">String</span> endpoint<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p><code>AlertManagerEvent</code> 提供三种构造函数:</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token class-name">AlertManagerEvent</span><span class="token punctuation">(</span><span class="token class-name">String</span> alertname<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">AlertManagerEvent</span><span class="token punctuation">(</span><span class="token class-name">String</span> alertname<span class="token punctuation">,</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> extraLabels<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">AlertManagerEvent</span><span class="token punctuation">(</span><span class="token class-name">String</span> alertname<span class="token punctuation">,</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> extraLabels<span class="token punctuation">,</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> annotations<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>其中:</p><ul><li><code>alertname</code> 是必传参数,用于标识一个 <code>alert</code>,<code>alertname</code> 字段可用于 <code>AlertManager</code> 发送告警时的分组和消重。</li><li><code>extraLabels</code> 可选传,在后台与 <code>alertname</code> 组合成 <code>labels</code> 一起标识一个 <code>alert</code>,可用于 <code>AlertManager</code> 发送告警时的分组和消重。</li><li><code>annotations</code> 可选传,它的 value 值可使用 Go 语言模板风格的<div class="language-text line-numbers-mode" data-ext="text" data-title="text"><pre class="language-text"><code>{{.&lt;label_key&gt;}}
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div>它在最终生成消息时会被替换为 <code>labels[&lt;label_key&gt;]</code>。</li><li><code>labels</code> <code>annotations</code> 会被解析成 json 字符串发送给 <code>AlertManager</code>:</li></ul><div class="language-json line-numbers-mode" data-ext="json" data-title="json"><pre class="language-json"><code><span class="token punctuation">{</span>
<span class="token property">&quot;labels&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token property">&quot;alertname&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&lt;requiredAlertName&gt;&quot;</span><span class="token punctuation">,</span>
<span class="token property">&quot;&lt;labelname&gt;&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&lt;labelvalue&gt;&quot;</span><span class="token punctuation">,</span>
...
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token property">&quot;annotations&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token property">&quot;&lt;labelname&gt;&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&lt;labelvalue&gt;&quot;</span><span class="token punctuation">,</span>
...
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>调用 <code>AlertManagerHandler</code> <code>onEvent(AlertManagerEvent event)</code> 方法发送一个告警。</p><p><strong>使用示例 1:</strong></p><p>只传 <code>alertname</code>。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token class-name">AlertManagerHandler</span> alertManagerHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AlertManagerHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
alertManagerHandler<span class="token punctuation">.</span><span class="token keyword">open</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">AlertManagerConfiguration</span><span class="token punctuation">(</span><span class="token string">&quot;http://127.0.0.1:9093/api/v1/alerts&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">String</span> alertName <span class="token operator">=</span> <span class="token string">&quot;test0&quot;</span><span class="token punctuation">;</span>
<span class="token class-name">AlertManagerEvent</span> alertManagerEvent <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AlertManagerEvent</span><span class="token punctuation">(</span>alertName<span class="token punctuation">)</span><span class="token punctuation">;</span>
alertManagerHandler<span class="token punctuation">.</span><span class="token function">onEvent</span><span class="token punctuation">(</span>alertManagerEvent<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>使用示例 2:</strong></p><p>传入 <code>alertname</code> <code>extraLabels</code>。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token class-name">AlertManagerHandler</span> alertManagerHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AlertManagerHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
alertManagerHandler<span class="token punctuation">.</span><span class="token keyword">open</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">AlertManagerConfiguration</span><span class="token punctuation">(</span><span class="token string">&quot;http://127.0.0.1:9093/api/v1/alerts&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">String</span> alertName <span class="token operator">=</span> <span class="token string">&quot;test1&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> extraLabels <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
extraLabels<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;severity&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;critical&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
extraLabels<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;series&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;root.ln.wt01.wf01.temperature&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
extraLabels<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;value&quot;</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span><span class="token number">100.0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">AlertManagerEvent</span> alertManagerEvent <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AlertManagerEvent</span><span class="token punctuation">(</span>alertName<span class="token punctuation">,</span> extraLabels<span class="token punctuation">)</span><span class="token punctuation">;</span>
alertManagerHandler<span class="token punctuation">.</span><span class="token function">onEvent</span><span class="token punctuation">(</span>alertManagerEvent<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>使用示例 3:</strong></p><p>传入 <code>alertname</code>, <code>extraLabels</code> <code>annotations</code> 。</p><p>最终 <code>description</code> 字段的值会被解析为 <code>test2: root.ln.wt01.wf01.temperature is 100.0</code>。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token class-name">AlertManagerHandler</span> alertManagerHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AlertManagerHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
alertManagerHandler<span class="token punctuation">.</span><span class="token keyword">open</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">AlertManagerConfiguration</span><span class="token punctuation">(</span><span class="token string">&quot;http://127.0.0.1:9093/api/v1/alerts&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">String</span> alertName <span class="token operator">=</span> <span class="token string">&quot;test2&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> extraLabels <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
extraLabels<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;severity&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;critical&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
extraLabels<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;series&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;root.ln.wt01.wf01.temperature&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
extraLabels<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;value&quot;</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span><span class="token number">100.0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> annotations <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
annotations<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;summary&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;high temperature&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
annotations<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;description&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;{{.alertname}}: {{.series}} is {{.value}}&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
alertManagerHandler<span class="token punctuation">.</span><span class="token function">onEvent</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">AlertManagerEvent</span><span class="token punctuation">(</span>alertName<span class="token punctuation">,</span> extraLabels<span class="token punctuation">,</span> annotations<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="完整的-maven-示例项目" tabindex="-1"><a class="header-anchor" href="#完整的-maven-示例项目"><span>完整的 Maven 示例项目</span></a></h3>`,83),b={href:"http://search.maven.org/",target:"_blank",rel:"noopener noreferrer"},w=s("strong",null,"trigger-example",-1),y={href:"https://github.com/apache/iotdb/tree/master/example/trigger",target:"_blank",rel:"noopener noreferrer"},h=p(`<p>它展示了:</p><ul><li>如何使用 Maven 管理您的 trigger 项目</li><li>如何基于触发器的用户编程接口实现数据侦听</li><li>如何使用窗口工具类</li><li>如何使用 Sink 工具类</li></ul><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">package</span> <span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>trigger</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>engine<span class="token punctuation">.</span>trigger<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">Trigger</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>engine<span class="token punctuation">.</span>trigger<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">TriggerAttributes</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>path<span class="token punctuation">.</span></span><span class="token class-name">PartialPath</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>engine<span class="token punctuation">.</span>trigger<span class="token punctuation">.</span>sink<span class="token punctuation">.</span>mqtt<span class="token punctuation">.</span></span><span class="token class-name">MQTTConfiguration</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>engine<span class="token punctuation">.</span>trigger<span class="token punctuation">.</span>sink<span class="token punctuation">.</span>mqtt<span class="token punctuation">.</span></span><span class="token class-name">MQTTEvent</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>engine<span class="token punctuation">.</span>trigger<span class="token punctuation">.</span>sink<span class="token punctuation">.</span>mqtt<span class="token punctuation">.</span></span><span class="token class-name">MQTTHandler</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>engine<span class="token punctuation">.</span>trigger<span class="token punctuation">.</span>sink<span class="token punctuation">.</span>local<span class="token punctuation">.</span></span><span class="token class-name">LocalIoTDBConfiguration</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>engine<span class="token punctuation">.</span>trigger<span class="token punctuation">.</span>sink<span class="token punctuation">.</span>local<span class="token punctuation">.</span></span><span class="token class-name">LocalIoTDBEvent</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>engine<span class="token punctuation">.</span>trigger<span class="token punctuation">.</span>sink<span class="token punctuation">.</span>local<span class="token punctuation">.</span></span><span class="token class-name">LocalIoTDBHandler</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>utils<span class="token punctuation">.</span>windowing<span class="token punctuation">.</span>configuration<span class="token punctuation">.</span></span><span class="token class-name">SlidingSizeWindowConfiguration</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>utils<span class="token punctuation">.</span>windowing<span class="token punctuation">.</span>handler<span class="token punctuation">.</span></span><span class="token class-name">SlidingSizeWindowEvaluationHandler</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>tsfile<span class="token punctuation">.</span>file<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>enums<span class="token punctuation">.</span></span><span class="token class-name">TSDataType</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>fusesource<span class="token punctuation">.</span>mqtt<span class="token punctuation">.</span>client<span class="token punctuation">.</span></span><span class="token class-name">QoS</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>slf4j<span class="token punctuation">.</span></span><span class="token class-name">Logger</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>slf4j<span class="token punctuation">.</span></span><span class="token class-name">LoggerFactory</span></span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">TriggerExample</span> <span class="token keyword">implements</span> <span class="token class-name">Trigger</span> <span class="token punctuation">{</span>
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">Logger</span> <span class="token constant">LOGGER</span> <span class="token operator">=</span> <span class="token class-name">LoggerFactory</span><span class="token punctuation">.</span><span class="token function">getLogger</span><span class="token punctuation">(</span><span class="token class-name">TriggerExample</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> <span class="token constant">TARGET_DEVICE</span> <span class="token operator">=</span> <span class="token string">&quot;root.alerting&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">LocalIoTDBHandler</span> localIoTDBHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LocalIoTDBHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">MQTTHandler</span> mqttHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MQTTHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token class-name">SlidingSizeWindowEvaluationHandler</span> windowEvaluationHandler<span class="token punctuation">;</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">onCreate</span><span class="token punctuation">(</span><span class="token class-name">TriggerAttributes</span> attributes<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
<span class="token constant">LOGGER</span><span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">&quot;onCreate(TriggerAttributes attributes)&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> lo <span class="token operator">=</span> attributes<span class="token punctuation">.</span><span class="token function">getDouble</span><span class="token punctuation">(</span><span class="token string">&quot;lo&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> hi <span class="token operator">=</span> attributes<span class="token punctuation">.</span><span class="token function">getDouble</span><span class="token punctuation">(</span><span class="token string">&quot;hi&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">openSinkHandlers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
windowEvaluationHandler <span class="token operator">=</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingSizeWindowEvaluationHandler</span><span class="token punctuation">(</span>
<span class="token keyword">new</span> <span class="token class-name">SlidingSizeWindowConfiguration</span><span class="token punctuation">(</span><span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">DOUBLE</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
window <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">double</span> avg <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> window<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
avg <span class="token operator">+=</span> window<span class="token punctuation">.</span><span class="token function">getDouble</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
avg <span class="token operator">/=</span> window<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>avg <span class="token operator">&lt;</span> lo <span class="token operator">||</span> hi <span class="token operator">&lt;</span> avg<span class="token punctuation">)</span> <span class="token punctuation">{</span>
localIoTDBHandler<span class="token punctuation">.</span><span class="token function">onEvent</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">LocalIoTDBEvent</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> avg<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
mqttHandler<span class="token punctuation">.</span><span class="token function">onEvent</span><span class="token punctuation">(</span>
<span class="token keyword">new</span> <span class="token class-name">MQTTEvent</span><span class="token punctuation">(</span><span class="token string">&quot;test&quot;</span><span class="token punctuation">,</span> <span class="token class-name">QoS</span><span class="token punctuation">.</span><span class="token constant">EXACTLY_ONCE</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> window<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> avg<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">onDrop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
<span class="token constant">LOGGER</span><span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">&quot;onDrop()&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">closeSinkHandlers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">onStart</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
<span class="token constant">LOGGER</span><span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">&quot;onStart()&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">openSinkHandlers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">onStop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
<span class="token constant">LOGGER</span><span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">&quot;onStop()&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">closeSinkHandlers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token class-name">Double</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span> timestamp<span class="token punctuation">,</span> <span class="token class-name">Double</span> value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
windowEvaluationHandler<span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">(</span>timestamp<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> value<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">double</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">fire</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">[</span><span class="token punctuation">]</span> timestamps<span class="token punctuation">,</span> <span class="token keyword">double</span><span class="token punctuation">[</span><span class="token punctuation">]</span> values<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> timestamps<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
windowEvaluationHandler<span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">(</span>timestamps<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> values<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> values<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">openSinkHandlers</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
localIoTDBHandler<span class="token punctuation">.</span><span class="token keyword">open</span><span class="token punctuation">(</span>
<span class="token keyword">new</span> <span class="token class-name">LocalIoTDBConfiguration</span><span class="token punctuation">(</span>
<span class="token constant">TARGET_DEVICE</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">{</span><span class="token string">&quot;local&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">TSDataType</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">{</span><span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">DOUBLE</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
mqttHandler<span class="token punctuation">.</span><span class="token keyword">open</span><span class="token punctuation">(</span>
<span class="token keyword">new</span> <span class="token class-name">MQTTConfiguration</span><span class="token punctuation">(</span>
<span class="token string">&quot;127.0.0.1&quot;</span><span class="token punctuation">,</span>
<span class="token number">1883</span><span class="token punctuation">,</span>
<span class="token string">&quot;root&quot;</span><span class="token punctuation">,</span>
<span class="token keyword">new</span> <span class="token class-name">PartialPath</span><span class="token punctuation">(</span><span class="token constant">TARGET_DEVICE</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token keyword">new</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">{</span><span class="token string">&quot;remote&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">closeSinkHandlers</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
localIoTDBHandler<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
mqttHandler<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>您可以按照下面的步骤试用这个触发器:</p><ul><li><p>在<code>iotdb-engine.properties</code>中启用 MQTT 服务</p><div class="language-properties line-numbers-mode" data-ext="properties" data-title="properties"><pre class="language-properties"><code><span class="token comment"># whether to enable the mqtt service.</span>
<span class="token key attr-name">enable_mqtt_service</span><span class="token punctuation">=</span><span class="token value attr-value">true</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div></li><li><p>启动 IoTDB 服务器</p></li><li><p>通过 cli 创建时间序列</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">CREATE</span> TIMESERIES root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">.</span>s1 <span class="token keyword">WITH</span> DATATYPE<span class="token operator">=</span><span class="token keyword">DOUBLE</span><span class="token punctuation">,</span> ENCODING<span class="token operator">=</span>PLAIN<span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div></li><li><p>将 <strong>trigger-example</strong> 中打包好的 JAR(<code>trigger-example-0.13.0-SNAPSHOT.jar</code>)放置到目录 <code>iotdb-server-0.13.0-SNAPSHOT/ext/trigger</code> (也可以是<code>iotdb-server-0.13.0-SNAPSHOT/ext/trigger</code>的子目录)下</p><blockquote><p>您可以通过修改配置文件中的<code>trigger_root_dir</code>来指定加载触发器 JAR 包的根路径。</p></blockquote></li><li><p>使用 SQL 语句注册该触发器,假定赋予该触发器的名字为<code>window-avg-alerter</code></p></li><li><p>使用<code>CREATE TRIGGER</code>语句注册该触发器</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">CREATE</span> <span class="token keyword">TRIGGER</span> <span class="token identifier"><span class="token punctuation">\`</span>window-avg-alerter<span class="token punctuation">\`</span></span>
<span class="token keyword">AFTER</span> <span class="token keyword">INSERT</span>
<span class="token keyword">ON</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">.</span>s1
<span class="token keyword">AS</span> <span class="token string">&#39;org.apache.iotdb.trigger.TriggerExample&#39;</span>
<span class="token keyword">WITH</span> <span class="token punctuation">(</span>
<span class="token string">&#39;lo&#39;</span> <span class="token operator">=</span> <span class="token string">&#39;0&#39;</span><span class="token punctuation">,</span>
<span class="token string">&#39;hi&#39;</span> <span class="token operator">=</span> <span class="token string">&#39;10.0&#39;</span>
<span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li><li><p>使用 cli 插入测试数据</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">(</span><span class="token keyword">timestamp</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">(</span><span class="token keyword">timestamp</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">(</span><span class="token keyword">timestamp</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">(</span><span class="token keyword">timestamp</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">(</span><span class="token keyword">timestamp</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">(</span><span class="token keyword">timestamp</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">(</span><span class="token keyword">timestamp</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">(</span><span class="token keyword">timestamp</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">14</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">(</span><span class="token keyword">timestamp</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> root<span class="token punctuation">.</span>sg1<span class="token punctuation">.</span>d1<span class="token punctuation">(</span><span class="token keyword">timestamp</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">18</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li><li><p>使用 cli 查询数据以验证触发器的行为</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>alerting<span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div></li><li><p>正常情况下,得到如下结果</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code>IoTDB<span class="token operator">&gt;</span> <span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>alerting<span class="token punctuation">;</span>
<span class="token operator">+</span><span class="token comment">-----------------------------+--------------------+-------------------+</span>
<span class="token operator">|</span> <span class="token keyword">Time</span><span class="token operator">|</span>root<span class="token punctuation">.</span>alerting<span class="token punctuation">.</span>remote<span class="token operator">|</span>root<span class="token punctuation">.</span>alerting<span class="token punctuation">.</span><span class="token keyword">local</span><span class="token operator">|</span>
<span class="token operator">+</span><span class="token comment">-----------------------------+--------------------+-------------------+</span>
<span class="token operator">|</span><span class="token number">1970</span><span class="token operator">-</span><span class="token number">01</span><span class="token operator">-</span><span class="token number">01</span>T08:<span class="token number">00</span>:<span class="token number">00.006</span><span class="token operator">+</span><span class="token number">08</span>:<span class="token number">00</span><span class="token operator">|</span> <span class="token number">14.0</span><span class="token operator">|</span> <span class="token number">14.0</span><span class="token operator">|</span>
<span class="token operator">+</span><span class="token comment">-----------------------------+--------------------+-------------------+</span>
Total line number <span class="token operator">=</span> <span class="token number">1</span>
It costs <span class="token number">0.006</span>s
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li></ul><p>以上就是基本的使用方法,希望您能喜欢 😄</p><h3 id="重要注意事项-1" tabindex="-1"><a class="header-anchor" href="#重要注意事项-1"><span>重要注意事项</span></a></h3><ul><li><p>触发器是通过反射技术动态装载的,因此您在装载过程中无需启停服务器。</p></li><li><p>不同的 JAR 包中最好不要有全类名相同但功能实现不一样的类。例如:触发器<code>trigger1</code>、<code>trigger2</code>分别对应资源<code>trigger1.jar</code>、<code>trigger2.jar</code>。如果两个 JAR 包里都包含一个<code>org.apache.iotdb.db.engine.trigger.example.AlertListener</code>类,当<code>CREATE TRIGGER</code>使用到这个类时,系统会随机加载其中一个 JAR 包中的类,最终导致触发器执行行为不一致以及其他的问题。</p></li><li><p>拥有同一个全类名的触发器类的版本管理问题。IoTDB 不允许系统中存在拥有同一全类名但是版本(逻辑)不一样的触发器。</p><p>相关问题:IoTDB 预先注册了 10 个<code>org.apache.iotdb.db.engine.trigger.example.AlertListener</code>触发器实例,DBA 更新了<code>org.apache.iotdb.db.engine.trigger.example.AlertListener</code>的实现和对应的 JAR 包,是否可以只卸载其中 5 个,将这 5 个替换为新的实现?</p><p>回答:无法做到。只有将预先注册的 10 个触发器全部卸载,才能装载到新的触发器实例。在原有触发器没有全部被卸载的情况下,新注册的拥有相同全类名的触发器行为只会与现有触发器的行为一致。</p></li></ul>`,8);function T(E,f){const t=e("ExternalLinkIcon"),o=e("RouteLink");return l(),i("div",null,[r,s("p",null,[n("在编写触发器逻辑时,需要使用到下面展示的依赖。如果您使用 "),s("a",d,[n("Maven"),a(t)]),n(",则可以直接从 "),s("a",v,[n("Maven 库"),a(t)]),n(" 中搜索到它们。")]),m,s("p",null,[n("更多用户权限相关的内容,请参考 "),a(o,{to:"/zh/UserGuide/V0.13.x/Administration-Management/Administration.html"},{default:u(()=>[n("权限管理语句")]),_:1}),n("。")]),g,s("p",null,[n("如果您使用 "),s("a",b,[n("Maven"),a(t)]),n(",可以参考我们编写的示例项目 "),w,n("。")]),s("p",null,[n("您可以在 "),s("a",y,[n("这里"),a(t)]),n(" 找到它。")]),h])}const q=c(k,[["render",T],["__file","Triggers.html.vue"]]),R=JSON.parse('{"path":"/zh/UserGuide/V0.13.x/Process-Data/Triggers.html","title":"","lang":"zh-CN","frontmatter":{"description":"触发器 触发器提供了一种侦听序列数据变动的机制。配合用户自定义逻辑,可完成告警、数据清洗、数据转发等功能。 触发器基于 Java 反射机制实现。用户通过简单实现 Java 接口,即可实现数据侦听。IoTDB 允许用户动态装载、卸载触发器,在装载、卸载期间,无需启停服务器。 根据此文档,您将会很快学会触发器的编写与管理。 编写触发器 触发器依赖 触发器的...","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://iotdb.apache.org/UserGuide/V0.13.x/Process-Data/Triggers.html"}],["meta",{"property":"og:url","content":"https://iotdb.apache.org/zh/UserGuide/V0.13.x/Process-Data/Triggers.html"}],["meta",{"property":"og:site_name","content":"IoTDB Website"}],["meta",{"property":"og:description","content":"触发器 触发器提供了一种侦听序列数据变动的机制。配合用户自定义逻辑,可完成告警、数据清洗、数据转发等功能。 触发器基于 Java 反射机制实现。用户通过简单实现 Java 接口,即可实现数据侦听。IoTDB 允许用户动态装载、卸载触发器,在装载、卸载期间,无需启停服务器。 根据此文档,您将会很快学会触发器的编写与管理。 编写触发器 触发器依赖 触发器的..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-07-10T03:11:17.000Z"}],["meta",{"property":"article:modified_time","content":"2023-07-10T03:11:17.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-07-10T03:11:17.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"触发器","slug":"触发器","link":"#触发器","children":[{"level":3,"title":"编写触发器","slug":"编写触发器","link":"#编写触发器","children":[]},{"level":3,"title":"管理触发器","slug":"管理触发器","link":"#管理触发器","children":[]},{"level":3,"title":"实用工具类","slug":"实用工具类","link":"#实用工具类","children":[]},{"level":3,"title":"完整的 Maven 示例项目","slug":"完整的-maven-示例项目","link":"#完整的-maven-示例项目","children":[]},{"level":3,"title":"重要注意事项","slug":"重要注意事项-1","link":"#重要注意事项-1","children":[]}]}],"git":{"createdTime":1688958677000,"updatedTime":1688958677000,"contributors":[{"name":"CritasWang","email":"critas@outlook.com","commits":1}]},"readingTime":{"minutes":18.56,"words":5569},"filePathRelative":"zh/UserGuide/V0.13.x/Process-Data/Triggers.md","localizedDate":"2023年7月10日","autoDesc":true}');export{q as comp,R as data};