简介
- Apache Nifi 是一个易于使用,功能强大且可靠的系统,用于处理和分发数据。可以自动化管理系统间的数据流。它使用高度可配置的指示图来管理数据路由、转换和系统中介逻辑,支持从多种数据源动态拉取数据。
- 基于web图形界面,通过脱宅、连接、配置完成基于流程的编程,实现数据采集等功能的数据处理与分发系统。
核心概念
- FlowFile
FlowFile表示在系统中移动的每个对象,对于每个FlowFile,Nifi都会记录它的一个属性键值对和零个或多个字节内容(FlowFile有attribute和content两者选择) - FlowFile Processor
处理器可以访问给定FlowFilw的属性及内容。处理器可以给定工作单元中的零个或多个流文件进行操作,并提交该工作或回滚该工作。 - Connection
Connection用来连接处理器。充当队列并允许各种进程以不同的速率进行交互。这些队列可以动态的进行优先级排序,并且可以在负载上设置上限,从而启用背压。 - Flow Controller
流控制器维护流程如何连接,并管理和分配所有流程使用的线程。流控制器充当代理,促进处理器之间流文件的交换。 - Process Group
进程组里是一组特定的流程和连接,可以通过输入端口接收数据并通过输出端口发送数据,这样我们在进程组里简单的组合组件,就可以得到一个全新功能的组件(Process Group)。
部署
鉴权
HTTP
- NiFi不通过HTTP执行用户身份验证。使用HTTP,所有用户都将被授予所有角色,拥有所有权限。
- dockerfile启动时会跑【sh/start.sh】脚本,如果配置了环境变量【NIFI_WEB_HTTP_PORT】,会重置部分参数。
单用户(Single User)
-
默认环境是单用户。
-
默认生成用户密码。
-
自定义用户密码。
- 密码必须是12位以及以上。
- dockerfile启动时会跑【sh/start.sh】脚本,如果配置了环境变量【SINGLE_USER_CREDENTIALS_USERNAME/SINGLE_USER_CREDENTIALS_PASSWORD】会执行生成用户密码操作。
environment:
- SINGLE_USER_CREDENTIALS_USERNAME=admin
- SINGLE_USER_CREDENTIALS_PASSWORD=admin
- docker-compose.yaml示例
version: '3'
services:
nifi:
image: apache/nifi:latest
ports:
- '8443:8443'
environment:
- NIFI_WEB_PROXY_HOST=192.168.5.1:8443
- SINGLE_USER_CREDENTIALS_USERNAME=admin
- SINGLE_USER_CREDENTIALS_PASSWORD=admin
volumes:
- ./data:/opt/nifi/nifi-current/data
轻量级目录访问协议(LDAP)
参数(待验证)
environment:
- NIFI_SECURITY_USER_LOGIN_IDENTITY_PROVIDER="ldap-provider"
- LDAP_AUTHENTICATION_STRATEGY=SIMPLE
- LDAP_MANAGER_DN=cn=admin,dc=example,dc=com
- LDAP_MANAGER_PASSWORD=your_ldap_admin_password
- LDAP_TLS_KEYSTORE=
- LDAP_TLS_KEYSTORE_PASSWORD=
- LDAP_TLS_KEYSTORE_TYPE=
- LDAP_TLS_TRUSTSTORE=
- LDAP_TLS_TRUSTSTORE_PASSWORD=
- LDAP_TLS_TRUSTSTORE_TYPE=
- LDAP_TLS_PROTOCOL=
- LDAP_URL=ldap://your_ldap_server:389
- LDAP_USER_SEARCH_BASE=ou=users,dc=example,dc=com
- LDAP_USER_SEARCH_FILTER=(&(objectClass=inetOrgPerson)(uid={0}))
- LDAP_IDENTITY_STRATEGY=USE_DN
- LDAP_REFERRAL_STRATEGY=
- NIFI_LDAP_CONNECT_TIMEOUT=10 secs
- NIFI_LDAP_READ_TIMEOUT=10 secs
- NIFI_LDAP_IDENTITY_STRATEGY=USE_USERNAME
示例
示例-版本管理
提交版本
同步版本
切换版本
提交版本
示例-连接pg+请求接口
自定义pg连接服务
jdbc:postgresql://xx:8000/xx?user=xx&password=xx
初始化数据流GenerateFlowFile
- 大部分处理器需要有数据流入才能触发执行,GenerateFlowFile 处理器不需要数据流入就能产生数据,一般用于触发任务调度。
${literal(''):replaceEmpty(${now():toNumber():minus(86400000):format('yyyy-MM-dd')})}
调度时间scheduling
9点0分
ExecuteSql
写入:INSERT INTO test_asm(client_id,client_secret,token) VALUES('${client_id}','${client_secret}','${token}')
设置失败终止terminate
连接
queued表示有几个进程
run once
retry
查看数据view data provenance
show modified attributes only
avro转json=ConverAvroToJson
备注:sql查询数据结果是avro格式
拆分json数组=SplotJson
提取json字段为属性=EvaluateJsonPath
替换文本=ReplaceText
- dict
{ "client_id": "${client_id}", "client_secret": "${client_secret}", "grant_type": "client_credentials", "scope": "searchadsorg" }
- 表单
client_id=${client_id}&client_secret=${client_secret}&grant_type=client_credentials&scope=searchadsorg
http请求=InvokeHTT
- 重试=RetryFlowFile
代理服务:StandardProxyConfigurationService
示例-钉钉告警
全局变量Variables
空白处 右键
增加失败路由:RouteOnAttribute
${status:equals('failed')}
失败则提取信息
提取账号:AttributesToJSON
合并:MergeContent
去重:QueryRecord
使用 SQL 语句从json文件内容中查询数据,并生成新的文件内容
提取去重后的属性:ExtractText
统计成功和失败的数量:MergeContent
以status为标志
配置不同的消息:UpdateAttribute
不同的规则对应不同的内容
提取message:ReplaceText
合并消息:MergeContent
根据内容将数据路由到不同的关系:RoteOnContent
判断是否at所有人:UpdateAttribute
如果存在Exception ${RouteOnContent.Route:equals('Exception'):ifElse('true', 'false')}
请求体:ReplaceText
{ "text": { "content": "${now():format('yyyy-MM-dd HH:mm:ss')} 【${platform}】 authorization end! $1" }, "msgtype": "text", "at": { "isAtAll": ${is_at_all} } }
生成时间戳和签名:ExecuteScript
import javax.crypto.Mac import javax.crypto.spec.SecretKeySpec def flowFile = session.get(); if (flowFile == null) { return; } Long timestamp = System.currentTimeMillis() //String s = "SECa2abc875130e190641cb2c7ddc6e0d69416dca05faa3653a4437f22fdc58a211" String s = secret.evaluateAttributeExpressions(flowFile).value String stringToSign = timestamp + "\n" + s Mac mac = Mac.getInstance("HmacSHA256") mac.init(new SecretKeySpec(s.getBytes("UTF-8"), "HmacSHA256")) byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")) String sign = URLEncoder.encode(signData.encodeBase64().toString(),"UTF-8") session.putAttribute(flowFile, "timestamp", timestamp.toString()) session.putAttribute(flowFile, "sign", sign) session.transfer(flowFile, REL_SUCCESS)
发送webhook:InvokeHTTP
${DingTalkWebhook}×tamp=${timestamp}&sign=${sign}
常见错误
- 未设置数据接收处理器,各种状态要对应中断或者下游processer
Component is invalid: 'JsonPaths' is invalid because Exactly one JsonPath must be set if using destination of flowfile-content
- 修改参数时,必须先stop
- url是被编码过的,参数改为表单提交,拼接url
application/x-www-form-urlencoded
- json解析失败:
- ConverAvroToJson时,如果是空或者单条记录时,是否包装成list
- 同步版本时
解决:先disable 组件服务