flume http source示例讲解
一、介绍
flume自带的Http Source可以通过Http Post接收事件。
场景:对于有些应用程序环境,它可能不能部署Flume SDK及其依赖项,或客户端代码倾向于通过HTTP而不是Flume的PRC发送数据的情况,此时HTTP SOURCE可以用来将数据接收到Flume中。
从客户端的角度看,HTTP SOURCE表现的像web服务器一样能接收flume事件
二、参数
配置参数 | 默认值 | 描述 |
type | http (org.apache.fluem.source.httpSource) | |
bind | 绑定的IP地址或主机名 | |
port | 绑定的端口号 | |
enableSSL | false | |
keystore | 使用的keystore文件的路径 | |
keystorePassword | 能够进入keystore的密码 | |
handler | JSONHandler | HTTP SOURCE使用的处理程序类 |
handler.* | 传给处理程序类的任何参数 可以 通过使用此参数(*)配置传入 |
为了安全传输,http source也支持SSL,SSL支持的相关例子可以参见我的关于flume之Avro Source博客
Flume 事件使用一个可插拔的“handler”程序来实现转换,它必须实现的HTTPSourceHandler接口。此处理程序需要一个HttpServletRequest和返回一个flume 事件列表。默认是:JSONHandler。
例如:xxx.handler=com.dxz.flume_demo.source.HTTPSourceXmlHandler
自定义的handler如果想传入参数,可以使用handler.*配置
如:xxx.handler.myparam=zhangsan
如果配置中没有指定处理程序,HTTP SOURCE将使用与Flume绑定的处理程序,即:JSONHandler,它能处理JSON格式的事件。每个事件可以包含包装为数组的几个事件,尽管Source写入的管道可能有限制的事务能力。
处理程序接受UTF-8,UTF-16,UTF-32编码的JSON格式的数据,并且将它转换成一个列表的事件。
格式:
[ { "headers":{"":"","":""
},
"body":"the first event"
},
{ "headers":{"":"","":""
},
"body":"the second event"
}
]
配置文件http_source.conf
a1.sources=r1
a1.sinks=k1
a1.channels=c1 a1.sources.r1.type=http
a1.sources.r1.bind=localhost
a1.sources.r1.port=50000
a1.sources.r1.channels=c1 a1.sinks.k1.type=logger
a1.sinks.k1.channel=c1 a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
启动:cd到bin目录下执行
flume-ng.cmd agent -conf ../conf -conf-file ../conf/http_source.conf -name a1 -property flume.root.logger=INFO,console
3) 测试:
$ curl -X POST -d'[{"headers":{"h1":"v1","h2":"v2"},"body":"hello body"}]' http://192.168.1.102:50000
4) 服务器端结果
2.http source handler自定义例子
假定xml请求格式,期望格式如下:
<events>
<event>
<headers><header1>value1</header1></headers>
<body>test</body>
</event>
<event>
<headers><header1>value1</header1></headers>
<body>test2</body>
</event>
</events>
现在要求flume http source可以处理这种请求的xml格式
操作步骤如下:
1)建立maven工程,pom.xml文件如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.dxz</groupId>
<artifactId>flume-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>flume-demo</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-core</artifactId>
<version>1.6.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
2)开发代码 ,自定义handler类
package com.dxz.flume_demo.source; import com.google.common.base.Preconditions;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.event.EventBuilder;
import org.apache.flume.source.http.HTTPBadRequestException;
import org.apache.flume.source.http.HTTPSourceHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException; import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class HTTPSourceXMLHandler implements HTTPSourceHandler {
private final String ROOT = "events";
private final String EVENT_TAG = "event";
private final String HEADERS_TAG = "headers";
private final String BODY_TAG = "body"; private final String CONF_INSERT_TIMESTAMP = "insertTimestamp";
private final String TIMESTAMP_HEADER = "timestamp";
private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); // Document builders are not thread-safe.
// So make sure we have one for each thread.
private final ThreadLocal<DocumentBuilder> docBuilder = new ThreadLocal<DocumentBuilder>(); private boolean insertTimestamp;
private static final Logger LOG = LoggerFactory.getLogger(HTTPSourceXMLHandler.class); public List<Event> getEvents(HttpServletRequest httpServletRequest) throws HTTPBadRequestException, Exception {
if (docBuilder.get() == null) {
docBuilder.set(documentBuilderFactory.newDocumentBuilder());
}
Document doc;
final List<Event> events;
try {
doc = docBuilder.get().parse(httpServletRequest.getInputStream());
Element root = doc.getDocumentElement(); root.normalize();
// Verify that the root element is "events"
Preconditions.checkState(ROOT.equalsIgnoreCase(root.getTagName())); NodeList nodes = root.getElementsByTagName(EVENT_TAG);
LOG.info("get nodes={}", nodes); int eventCount = nodes.getLength();
events = new ArrayList<Event>(eventCount);
for (int i = 0; i < eventCount; i++) {
Element event = (Element) nodes.item(i);
// Get all headers. If there are multiple header sections,
// combine them.
NodeList headerNodes = event.getElementsByTagName(HEADERS_TAG);
Map<String, String> eventHeaders = new HashMap<String, String>();
for (int j = 0; j < headerNodes.getLength(); j++) {
Node headerNode = headerNodes.item(j);
NodeList headers = headerNode.getChildNodes();
for (int k = 0; k < headers.getLength(); k++) {
Node header = headers.item(k); // Read only element nodes
if (header.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
// Make sure a header is inserted only once,
// else the event is malformed
Preconditions.checkState(!eventHeaders.containsKey(header.getNodeName()),
"Header expected only once " + header.getNodeName());
eventHeaders.put(header.getNodeName(), header.getTextContent());
}
}
Node body = event.getElementsByTagName(BODY_TAG).item(0);
if (insertTimestamp) {
eventHeaders.put(TIMESTAMP_HEADER, String.valueOf(System.currentTimeMillis()));
}
System.out.println("httpServletRequest.getCharacterEncoding()="+httpServletRequest.getCharacterEncoding());
System.out.println("body.getTextContent()=" + body.getTextContent());
events.add(EventBuilder.withBody(
body.getTextContent().getBytes(Charset.defaultCharset()), eventHeaders));
}
} catch (SAXException ex) {
throw new HTTPBadRequestException("Request could not be parsed into valid XML", ex);
} catch (Exception ex) {
throw new HTTPBadRequestException(
"Request is not in expected format. " + "Please refer documentation for expected format.", ex);
}
return events;
} public void configure(Context context) {
insertTimestamp = context.getBoolean(CONF_INSERT_TIMESTAMP, false);
}
}
3)在该工程的flume-demo目录下执行命令mvn package,会将该工程打成jar包,会生产target目录,从中找到flume-demo.jar,将其拷贝到flume的lib目录下
4)flume配置文件:http_source_xml.conf
a1.sources=r1
a1.sinks=k1
a1.channels=c1 a1.sources.r1.type=http
a1.sources.r1.bind=localhost
a1.sources.r1.port=50000
a1.sources.r1.channels=c1
a1.sources.r1.handler=com.dxz.flume_demo.source.HTTPSourceXMLHandler
a1.sources.r1.insertTimestamp=true a1.sinks.k1.type=logger
a1.sinks.k1.channel=c1 a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
5)启动服务
flume-ng.cmd agent -conf ../conf -conf-file ../conf/http_source_xml.conf -name a1 -property flume.root.logger=INFO,console
6)测试:
7)结果:
转自:
https://blog.csdn.net/liuxiao723846/article/details/63342490
flume http source示例讲解的更多相关文章
- 一次flume exec source采集日志到kafka因为单条日志数据非常大同步失败的踩坑带来的思考
本次遇到的问题描述,日志采集同步时,当单条日志(日志文件中一行日志)超过2M大小,数据无法采集同步到kafka,分析后,共踩到如下几个坑.1.flume采集时,通过shell+EXEC(tail -F ...
- 把Flume的Source设置为 Spooling directory source
把Flume的Source设置为 Spooling directory source,在设定的目录下放置需要读取的文件,一些文件在读取过程中会报错. 文件格式和报错如下: 实验一 读取汉子和“:&qu ...
- (ZZ)WPF经典编程模式-MVVM示例讲解
http://www.cnblogs.com/xjxz/archive/2012/11/14/WPF.html 本篇从两个方面来讨论MVVM模式: MVVM理论知识 MVVM示例讲解 一,MVVM理论 ...
- Flume:source和sink
Flume – 初识flume.source和sink 目录基本概念常用源 Source常用sink 基本概念 什么叫flume? 分布式,可靠的大量日志收集.聚合和移动工具. events ...
- 012——VUE中todos示例讲解class中应用表达式
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- FLUME KAFKA SOURCE 和 SINK 使用同一个 TOPIC
FLUME KAFKA SOURCE 和 SINK 使用同一个 TOPIC 最近做了一个事情,过滤下kakfa中的数据后,做这个就用到了flume,直接使用flume source 和 flume s ...
- 【机器学习】【条件随机场CRF-2】CRF的预测算法之维特比算法(viterbi alg) 详解 + 示例讲解 + Python实现
1.CRF的预测算法条件随机场的预测算法是给定条件随机场P(Y|X)和输入序列(观测序列)x,求条件概率最大的输出序列(标记序列)y*,即对观测序列进行标注.条件随机场的预测算法是著名的维特比算法(V ...
- PHP服务器端API原理及示例讲解(接口开发)
http://www.jb51.net/article/136816.htm 下面小编就为大家分享一篇PHP服务器端API原理及示例讲解(接口开发),具有很好的参考价值,希望对大家有所帮助 相信大家都 ...
- 示例讲解PostgreSQL表分区的三种方式
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 表分区是解决一些因单表过大引用的性能问题的方式,比如某张表过大就会造成查询变慢,可能分区是一种解决方案.一般建议 ...
随机推荐
- Version Control 版本控制
一.version control是什么: version control版本控制,是指对软件开发过程中各种程序代码.配置文件及说明文档等文件变更的管理,是软件配置管理的核心思想之一. 二.versi ...
- 《DSP using MATLAB》Problem 6.5
代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% Output In ...
- How should I store JSON in redis?
var redis = require("redis"); var client = redis.createClient(); js = { "like":& ...
- log4net 自定义日志级别记录多个日志
程序中原来只记录一个日志,现在我要写一个用户操作日志,需要与原来的日志分开,在config文件中一阵折腾无果(要么写不全,要么写重了,反正没办法完美分离,要么与现存代码没办法完美兼容),差点放弃准备自 ...
- zabbix使用企业微信发送告警信息
用qq邮箱发送告警信息一点都不方便,看到网上说也可以使用微信发送告警信息,所以就试了一下. 首先先试着在虚拟主机上给微信发送信息. 我们需要注册企业微信,注册时有一个地方需要注意,就是注册时选择组织, ...
- UML异步怎么表达
直接看结果 第一虚框和第二虚框是异步的.m1 和m2 没有任何先后关系. 第一虚框和第二虚框是异步的,两者没有任何先后关系.m3和m4是有先后关系的.m3()比m4()先执行.同样m5()和m6().
- 【转载】Win10桌面图标有小箭头怎么去掉?Win10去掉桌面图标小箭头的方法
以下文章转载至系统之家 网址:http://www.xitongzhijia.net/xtjc/20190104/146560.html Win10桌面图标有小箭头怎么去掉?Win10去掉桌面图标小箭 ...
- 怎样解题 (G. 波利亚 著)
第一部分 (已看) 目的 1. 帮助学生 2. 问题,建议,思维活动 3. 普遍性 4. 常识 5. 教师和学生,模仿和实践 主要部分,主要问题 6. 四个阶段 7. 理解题目 8. 例子 9. 拟订 ...
- java System.arraycopy()
package study.stage2; import java.util.Arrays; /** * Created by Sandy.Liu on 2017/7/19. */public cla ...
- Spring5 新特性
Spring Framework 5.0是在Spring Framework 4.0之后将近四年内一次重大的升级. 最大特点之一是响应式编程(Reactive Programming). 响应式编程核 ...