案例七:Flume自定义拦截器

在此案例中,实现:将小写字母转换成大写字母

一、配置Pom.xml文件

  <dependencies>

<!-- flume核心依赖 -->

        <dependency>

            <groupId>org.apache.flume</groupId>

            <artifactId>flume-ng-core</artifactId>

            <version>1.8.0</version>

        </dependency>

    </dependencies>

    <build>

        <plugins>

<!-- 打包插件 -->

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-jar-plugin</artifactId>

                <version>2.4</version>

                <configuration>

                    <archive>

                        <manifest>

                            <addClasspath>true</addClasspath>

                            <classpathPrefix>lib/</classpathPrefix>

                            <mainClass></mainClass>

                        </manifest>

                    </archive>

                </configuration>

            </plugin>

            <!-- 编译插件 -->

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-compiler-plugin</artifactId>

                <configuration>

                    <source>1.8</source>

                    <target>1.8</target>

                    <encoding>utf-8</encoding>

                </configuration>

            </plugin>

        </plugins>

    </build>

二、自定义实现拦截器-代码实现

1.首先,在java包里创建一个Package--flume,再在这个包里创建一个类-MyInterceptor(自定义拦截器)

2.代码实现

1 package flume;
 2 
 3 import org.apache.flume.Context;
 4 import org.apache.flume.Event;
 5 import org.apache.flume.interceptor.Interceptor;
 6 
 7 import java.util.ArrayList;
 8 import java.util.List;
 9 
10 public class MyInterceptor implements Interceptor {
11 
12     @Override
13     public void initialize() {
14 
15     }
16 
17     /**
18      * 拦截器实现方法
19      * @param event 一个事件 ,封装一行的数据 ,有header和body(具体的数据)
20      * @return
21      */
22     @Override
23     public Event intercept(Event event) {
24         //获取数据body
25         byte[] oldbody = event.getBody();
26         //将数据转换为大写
27         byte[] bytes = new String(oldbody).toUpperCase().getBytes();
28         //封装-setBody()没有返回值,所以不能在return里面写
29         event.setBody(bytes);
30         // 返回
31         return event;
32     }
33 
34     @Override
35     public List<Event> intercept(List<Event> list) {
36         ArrayList<Event> eventArrayList = new ArrayList<>();
37         //循环将每个事件的数据转换成大写
38         for(Event event:list){
39             eventArrayList.add(intercept(event));
40         }
41         return eventArrayList;
42     }
43 
44     /**
45      * 关闭资源
46      */
47     @Override
48     public void close() {
49 
50     }
51 
52     //定义一个内部类
53     public static class Builder implements Interceptor.Builder{
54 
55         @Override
56         public Interceptor build() {
57             return new MyInterceptor();
58         }
59 
60         @Override
61         public void configure(Context context) {
62 
63         }
64     }

3.目前还不能运行,因为要调用flume的底层配置。

所以接下来要对该代码进行打包:

1)使用Maven做成Jar包:

(1)点击右侧竖条的Maven--》选择里面的Lifecycle中的clean

(2)然后再点击下面的package进行打包

(3)包打完之后看log找到包的所在位置:

[INFO]Buildingjar:D:\idealC\JavaProject\zookeeper\target\zookeeper-1.0-SNAPSHOT.jar

或者看IDEA左侧target/maven-archiver里,那也有刚打好的包。

2)上传jar包

(1)跳到此目录下:/opt/module/flume-1.8.0/lib

(2)上传此jar到此jar目录中,拖拽上传即可

3)配置新的自定义的拦截器

(1)转到/opt/module/flume-1.8.0/myconf/目录下

(2)创建配置文件

[root@bigdata111 myconf]# vi flume-myInterceptor.conf

(3)添加配置(配置文件如下)、保存离开

#1 agent

a1.sources = r1

a1.sinks = k1

a1.channels = c1

 

#2 source

a1.sources.r1.type = exec

a1.sources.r1.command = tail -F /opt/plus

 

#定义拦截器

a1.sources.r1.interceptors = i1

#拦截器类型-IDEA里定义的内部类Builder--右键--》Copy Reference复制--》粘贴(全类名)

#注意:下面自定义类名前面符号应该是$,而不是"."

#就是粘贴之后要检查并将其改过来

a1.sources.r1.interceptors.i1.type = flume.MyInterceptor$Builder

 

a1.sinks.k1.type = logger

 

a1.channels.c1.type = memory

a1.channels.c1.capacity = 1000

a1.channels.c1.transactionCapacity = 100

 

a1.sources.r1.channels = c1

a1.sinks.k1.channel = c1

4.执行:

[root@bigdata111 myconf]# flume-ng agent -c ../conf/ -n a1 -f flume-myInterceptor.conf -Dflume.root.logger==INFO,console

5.看到正确结果:

(1)查看检测的plus文件内容:

 

flume发送给java服务 flume使用java编写_jar

(2)执行后的logger:

 

flume发送给java服务 flume使用java编写_jar_02

(3)分析:

从这可以看出,通过自定义拦截器已经可以实现:将小写字母转换成大写。

纯数字的Event也会被接收:

比如这里再向plus文件里添加数据:999

[root@bigdata111 opt]# echo 999 >> plus

 

flume发送给java服务 flume使用java编写_flume发送给java服务_03

从logger里能够看到,接收成功。

6.易出现的问题-类找不到,logger报错

查看日志发现问题-类找不到:

 

flume发送给java服务 flume使用java编写_ide_04

这是因为配置文件的全类名前面的符号$被粘贴成了"."因此找不到类,报错。比如下面的例子:

#定义拦截器

a1.sources.r1.interceptors = i1

#拦截器类型-IDEA里定义的内部类Builder--右键--》Copy Reference复制--》粘贴(全类名)

#注意:下面自定义类名前面符号应该是$,此处是错误的

#就是粘贴之后要检查并将其改过来

a1.sources.r1.interceptors.i1.type = flume.MyInterceptor.Builder

接下来解决:

(1)打开.jar包的所在位置-并用压缩软件打开此jar压缩包

(2)按照全类名找到最终的文件,并将其名字复制一下,再重新粘贴到配置文件中。

 

flume发送给java服务 flume使用java编写_拦截器_05

(3)删除原来上传的jar包、再次生成jar包并重新上传,然后启动执行。