需求:做一个windows服务,实现从ftp服务器实时下载或者更新文件到本地磁盘。

功能挺简单的。直接写个ftp工具类用定时器跑就能搞定,那我为什么不用呢?

别问,问就是我无聊啊,然后研究一下Flume打发时间。哈哈~

一、Flume部分

Source组件和Sink组件用的都是第三方。

source组件:https://github.com/keedio/flume-ftp-source

Sink组件用的谁的目前已经找不到了,网上搜到了一个升级版的。

File sink组件:https://github.com/huyanping/flume-sinks-safe-roll-file-sink

因为一些个性化的需求,所以我对他们源代码做了些变动。

2019/02/15: 新增了采集至HDFS的sink.因为flume自带的hdfs sink不支持高可用环境。所以依然对源代码做了些改动

具体修改:

HDFSEventSink.java

 public void configurateHA(Context context) {
String nns = Preconditions.checkNotNull(
context.getString("nameNodeServer"), "nameNodeServer is required");
hdfsEnv.set("fs.defaultFS", "hdfs://" + nns);
hdfsEnv.set("dfs.nameservices", nns);
hdfsEnv.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem"); Map<String, String> servers = context.getSubProperties("server.");
List<String> serverNames = Lists.newArrayListWithExpectedSize(servers.size()); servers.forEach((key, value) -> {
String name = Preconditions.checkNotNull(
key, "server.name is required");
String[] hostAndPort = value.split(":");
Preconditions.checkArgument(2 == hostAndPort.length, "hdfs.server is error."); hdfsEnv.set(String.format("dfs.namenode.rpc-address.%s.%s", nns, name), value);
serverNames.add(name);
}); hdfsEnv.set(String.format("dfs.ha.namenodes.%s", nns), Joiner.on(",").join(serverNames));
hdfsEnv.set(String.format("dfs.client.failover.proxy.provider.%s", nns),
"org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");
hdfsEnv.setBoolean("fs.automatic.close", false);
}

Flume伪集群配置

 # Describe the sink
a1.sinks.k1.type = com.syher.flume.sink.hdfs.HDFSEventSink
# 目标路径
a1.sinks.k1.hdfs.path = hdfs://bigData:8020/flume-wrapper/pdf-201901301740
a1.sinks.k1.hdfs.fileType = DataStream
a1.sinks.k1.hdfs.useLocalTimeStamp = true
#a1.sinks.k1.hdfs.batchSize = 3000
#a1.sinks.k1.hdfs.rollSize = 1024000000
#a1.sinks.k1.hdfs.rollCount = 0

Flume高可用配置文件

 # Describe the sink
a1.sinks.k1.type = com.syher.flume.sink.hdfs.HDFSEventSink
# hdfs服务器是否高可用
a1.sink.k1.hdfs.HA = true
# 目标路径
a1.sinks.k1.hdfs.path = hdfs://bigData/flume-wrapper/pdf-201901301805
a1.sinks.k1.hdfs.nameNodeServer = bigData
a1.sink.k1.hdfs.server.nn1 = master:9000
a1.sink.k1.hdfs.server.nn2 = slave1:9000
a1.sinks.k1.hdfs.fileType = DataStream
a1.sinks.k1.hdfs.useLocalTimeStamp = true
#a1.sinks.k1.hdfs.batchSize = 3000
#a1.sinks.k1.hdfs.rollSize = 0
#a1.sinks.k1.hdfs.rollInterval = 60
#a1.sinks.k1.hdfs.rollCount = 0

具体代码参考:https://github.com/rxiu/study-on-road/tree/master/trickle-flume

Ftp-Source组件的关键技术是Apache FtpClient,而TailDir-sink则用的RandomAccessFile。

Junit测试类我已经写好了,如果不想安装服务又有兴趣了解的朋友,可以自己改下配置跑一下看看。

二、JSW服务部分

用的java service wrapper把java程序做成了windows服务。

JSW工具包地址:https://pan.baidu.com/s/1Mg483tA0USYqFZ_bNV30tg 提取码:ejda

解压后在conf目录可以看到两个配置文件。一个是flume的,一个是jsw的。

bin目录里面是一些装卸启停的批命令。

lib目录里面有项目运行依赖的jar包。

lib.d目录没啥用,是我备份了从flume拷出来的一些无用的jar包。可删。

具体的配置和用法可以看压缩包里的使用说明文档。

注意,jsw的logfile的日志级别最好指定ERROR级别的,不然听说、可能会造成内存不足。

三、采集结果

可以看到,文件采集效率还是很稳的。一分钟不到就搞定了。

hdfs采集结果:

四、问题记录

hdfs采集时,用junit测试没有问题,用jsw测试一直没动静,也不报错。然后开了远程调试。调试方法:

在wrapper.conf中加入如下代码:

 # remote debug
#wrapper.java.additional.1=-Xdebug
#wrapper.java.additional.2=-Xnoagent
#wrapper.java.additional.3=-Djava.compiler=NONE #wrapper.java.additional.4=-Xrunjdwp:transport=dt_socket,server=y,address=5005,suspend=y

远程联调以后,终于有抛异常了

java.lang.NoClassDefFoundError: Could not initialize class org.apache.commons.lang.SystemUtils

找了下lib文件夹,里面确实有这个包,也没冲突。不得已在SystemUtils类里面打了个断电一步一步调试。最后发现是java.version的问题。

jdk10版本在下面代码的第5行报错了。因为JAVA_VERSION_TRIMMED值是10长度只有两位导致了越界。

     private static float getJavaVersionAsFloat() {
if (JAVA_VERSION_TRIMMED == null) {
return 0f;
}
String str = JAVA_VERSION_TRIMMED.substring(0, 3);
if (JAVA_VERSION_TRIMMED.length() >= 5) {
str = str + JAVA_VERSION_TRIMMED.substring(4, 5);
}
try {
return Float.parseFloat(str);
} catch (Exception ex) {
return 0;
}
}

由于之前为了学习jdk10新特性,搞了个jdk8,jdk10双环境,然后换回jdk8的时候是直接改的JAVA_HOME。

所以在dos窗口敲了下java -version 输出的是1.8_xxxxx。

但是不知道为啥java的System.getProperties("java.version")获取的依旧是10。

然后重新检查了JDK的J三个环境变量。

最后发现把PATH中的一个C:\ProgramData\Oracle\Java\javapath;路径去掉就没问题了。

 C:\ProgramData\Oracle\Java\javapath;G:\syhenian\oracle_11_21;E:\Program Files\Python36\Scripts\;E:\Program Files\Python36\;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;%M2_HOME%\bin;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;%CURL_HOME%\bin;E:\Program Files\scala\bin;%SCALA_HOME%\bin;%SCALA_HOME%\jre\bin;E:\Program Files\Python36;C:\Program Files (x86)\Git\cmd;%GRADLE_HOME%\bin;%ANDROID_HOME%\tools;
%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\build-tools\27.0.3;E:\Program Files\7-Zip;F:\Program Files\nodejs\;%HADOOP_HOME%\bin;

总结:common-lang包不知道升级管不管用,反正flume自带的这个包暂时是不支持jdk10的。有需要的可以自己改源码。

基于Flume做FTP文件实时同步的windows服务。的更多相关文章

  1. rsync+inotify 实现服务器之间目录文件实时同步(转)

    软件简介: 1.rsync 与传统的 cp. tar 备份方式相比,rsync 具有安全性高.备份迅速.支持增量备份等优点,通过 rsync 可 以解决对实时性要求不高的数据备份需求,例如定期的备份文 ...

  2. Centos 6.5 rsync+inotify 两台服务器文件实时同步

    rsync和inotify是什么我这里就不在介绍了,有专门的文章介绍这两个工具. 1.两台服务器IP地址分别为: 源服务器:192.168.1.2 目标服务器:192.168.1.3 @todo:从源 ...

  3. sersync基于rsync+inotify实现数据实时同步

    一.环境描述 需求:服务器A与服务器B为主备服务模式,需要保持文件一致性,现采用sersync基于rsync+inotify实现数据实时同步 主服务器A:192.168.1.23 从服务器B:192. ...

  4. (转)Linux下通过rsync与inotify(异步文件系统事件监控机制)实现文件实时同步

    Linux下通过rsync与inotify(异步文件系统事件监控机制)实现文件实时同步原文:http://www.summerspacestation.com/linux%E4%B8%8B%E9%80 ...

  5. centos文件实时同步inotify+rsync

    我的应用场景是重要文件备份 端口:873,备份端打开即可 下载地址:https://rsync.samba.org/ftp/rsync/src/ 服务端和客户端要保持版本一致 网盘链接:https:/ ...

  6. rsync+inotify-tools文件实时同步

    rsync+inotify-tools文件实时同步案例 全量备份 Linux下Rsync+sersync实现数据实时同步完成. 增量备份 纯粹的使用rsync做单向同步时,rsync的守护进程是运行在 ...

  7. rsync+sersync实现数据文件实时同步

    一.简介 sersync是基于Inotify开发的,类似于Inotify-tools的工具: sersync可以记录下被监听目录中发生变化的(包括增加.删除.修改)具体某一个文件或某一个目录的名字: ...

  8. sersync+rsync实现服务器文件实时同步

    sersync+rsync实现服务器文件实时同步 一.为什么要用rsync+sersync架构? 1.sersync是基于inotify开发的,类似于inotify-tools的工具 2.sersyn ...

  9. inotify用法简介及结合rsync实现主机间的文件实时同步

    一.inotify简介 inotify是Linux内核2.6.13 (June 18, 2005)版本新增的一个子系统(API),它提供了一种监控文件系统(基于inode的)事件的机制,可以监控文件系 ...

随机推荐

  1. CentOS 7 IPv6关闭

    你可以用两个方法做到这个.方法 1编辑文件/etc/sysctl.conf,vi /etc/sysctl.conf添加下面的行:net.ipv6.conf.all.disable_ipv6 =1net ...

  2. TSQL--SQL SERVER 常用系统变量

    ----------全局变量select @@version as '版本';---------------------------返回当前数据库的版本信息 select APP_NAME ( ) a ...

  3. Python 爬虫入门实例(爬取小米应用商店的top应用apk)

    一,爬虫是什么? 爬虫就是获取网络上各种资源,数据的一种工具.具体的可以自行百度. 二,如何写简单爬虫 1,获取网页内容 可以通过 Python(3.x) 自带的 urllib,来实现网页内容的下载. ...

  4. C#中哈希表(HashTable)的用法详解

    描述: 哈希表存放 key.values ,key值可以用于快速调取用,values 对应object类型,也就是说所有类型. 实例: 1.HashTable存放学生的成绩 Hashtable ht1 ...

  5. sql--CONVERT、FOR XML PATH解决实际问题

    需求:每个平台分类下的门店,每个门店的名称.图片路径.评分,每个门店下的四个产品的名称.图片路径.评分 思路: 一开始门店动态化好写,用Ajax就行了.但是每个门店下面的产品,每个去请求一次查询有点不 ...

  6. Js 事件详解

    1.事件流 1.1 事件流 描述的是在页面中接受事件的顺序 1.2 事件冒泡 由最具体的元素接收,然后逐级向上传播最不具体的元素的节点(文档) 1.3 事件捕获 最不具体的节点先接收事件,而最具体的节 ...

  7. python当中的装饰器

    1.装饰器 首先我们来说一下一个软件的设计原则:开闭原则,又被称为开发封闭原则,你的代码对功能的扩展是开放的,你的程序对修改源代码是封闭的.这样的软件设计思路可以更好的维护和开发. 开放:对功能扩展开 ...

  8. ClamAV学习【8】——64位Windows7下编译运行实践

    之前用SourceInsight静态分析了ClamAV引擎源码,现在打算开始动态研究下.不过出师不利,一开始就遇到纠结的问题,能力还有待提高. 从官网下了一个VS2005工程的源码包(http://d ...

  9. CASE语句用法学习

    A. 使用带有 CASE 简单表达式的 SELECT 语句 SELECT ProductNumber, Category = CASE ProductLine WHEN 'R' THEN 'Road' ...

  10. 【文文殿下】浅谈KMP算法next数组与循环节的关系

    KMP算法 KMP算法是一种字符串匹配算法,他可以在O(n+m)的时间内求出一个模式串在另一个模式串下出现的次数. KMP算法是利用next数组进行自匹配,然后来进行匹配的. Next数组 Next数 ...