这里只是做了简单的demo,并未深研

1.编写PolluteSink

  1.1 maven创建项目(pom.xml)

<dependencies>
<dependency>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-core</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-configuration</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-sdk</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-core</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-support</artifactId>
<version>3.0.0-M2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

  1.2 自定义sink

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

package com.example.demo1.pollute;

import com.example.demo1.entity.Pollute;
import com.example.demo1.utils.FormatDataUtil;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.apache.flume.*;
import org.apache.flume.conf.Configurable;
import org.apache.flume.sink.AbstractSink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.nio.charset.Charset;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; /**
* 污染源在线自动监控(监测)系统数据传输标准(国标)
*
* @author chenxiaokang
* @date 2019/10/14 13:53
*/
public class PolluteSink extends AbstractSink implements Configurable { private Logger LOG = LoggerFactory.getLogger(PolluteSink.class); private String tableName;
private String user;
private String password;
private String hostname;
private String port;
private Connection conn;
private String databaseName;
private PreparedStatement preparedStatement; @Override
public void configure(Context context) {
databaseName = context.getString("databaseName");
Preconditions.checkNotNull(databaseName, "databaseName must be set!!");
tableName = context.getString("tableName");
Preconditions.checkNotNull(tableName, "tableName must be set!!");
user = context.getString("user");
Preconditions.checkNotNull(user, "user must be set!!");
password = context.getString("password");
Preconditions.checkNotNull(password, "password must be set!!");
hostname = context.getString("hostname");
Preconditions.checkNotNull(hostname, "host must be set!!");
port = context.getString("port");
Preconditions.checkNotNull(port, "port must be set!!");
} @Override
public Status process() throws EventDeliveryException {
Status result = Status.READY;
Channel channel = getChannel();
List<String> actions = Lists.newArrayList();
Transaction transaction = null;
try {
transaction = channel.getTransaction();
Event event;
String content;
transaction.begin();
event = channel.take();
LOG.info("event:{}",event);
if (event != null) {
System.out.println("content++++:"+event.getBody());
content = new String(event.getBody(), Charset.forName("UTF-8"));
System.out.println("content"+content);
actions.add(content);
} else {
result = Status.BACKOFF;
}
Map<String, String> map = null;
System.out.println("actions.size() :"+actions.size() );
if (actions.size() > 0) {
for (String temp : actions) {
LOG.info("--- content : " + temp);
System.out.println(temp);
map = FormatDataUtil.getMapByData(temp);
List<Pollute> pollutes = new ArrayList<>();
for (Map.Entry<String, String> entry : map.entrySet()) {
Pollute pollute = new Pollute();
pollute.setKey(entry.getKey());
pollute.setValue(entry.getValue());
pollutes.add(pollute);
}
if (pollutes.size() > 0) {
preparedStatement.clearBatch();
for (Pollute pollute : pollutes) {
preparedStatement.setString(1, pollute.getKey());
preparedStatement.setString(2, pollute.getValue());
preparedStatement.setTimestamp(3,new Timestamp(System.currentTimeMillis()));
preparedStatement.addBatch();
}
preparedStatement.executeBatch();
conn.commit();
}
}
}
transaction.commit();
} catch (Exception e) {
e.printStackTrace();
LOG.error("", e);
} finally {
if (transaction != null) {
transaction.close();
} }
return result;
} @Override
public void start() {
super.start();
try {
//调用Class.forName()方法加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} String url = "jdbc:mysql://"+hostname+":3306/"+databaseName+"?allowMultiQueries=true&useUnicode=true&" +
"characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull";
//调用DriverManager对象的getConnection()方法,获得一个Connection对象 try {
LOG.info("user:{},password:{}",user,password);
conn = DriverManager.getConnection(url, user, password);
conn.setAutoCommit(false);
//创建一个Statement对象
preparedStatement = conn.prepareStatement("insert into bs_pollute(`key`,`value`,date_add) values (?,?,?)"); } catch (SQLException e) {
e.printStackTrace();
} } @Override
public void stop() {
super.stop();
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
} if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
} } }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package com.example.demo1.utils;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map; /**
* @author chenxiaokang
* @date 2019/10/14 11:25
*/
public class FormatDataUtil { private static String arg = "";
private static String arg1 = ";";
private static String arg2 = ",";
private static String arg3 = "=";
private static String arg4 = "&&";
private static String arg6 = "##";
private static String arg7 = "DataTime"; public static void main(String[] args) throws IOException {
String data = "QN=20040516010101001;ST=32;CN=1072;PW=123456;MN=88888880000001;Flag=3;CP=&&PW=654321&&";
FileUtils.writeFile("polluteTxt",getMapByData(data));
} /**
* 将接收到的数据转为map
* @param data
* @return
*/
public static Map<String, String> getMapByData(String data) {
System.out.println("data:"+data);
if (isEmpty(data)) {
return null;
}
Map<String, String> map = new HashMap<String, String>();
data = data.replaceAll(arg6, "");
if(isContainsChars(data,arg1)){
String[] temp = getArrayByChar(data, arg1);
for (String s : temp) {
// 如果有多个参数用逗号分割
if (isContainsChars(s, arg2)) {
String[] temp1 = getArrayByChar(s, arg2);
for (String s1 : temp1) {
intoMap(map, s1);
}
} else {
intoMap(map,s);
}
}
}
return map;
} /**
* 因为字段中存在特殊的(CP=&&DataTime=20040516020111)格式,不光是以(key=value)格式
* 所以需要对其进行处理
* @param map
* @param var
*/
public static void intoMap(Map<String, String> map, String var) {
// 数据中是否存在CP=&&DataTime=20040516020111;格式 如果有按&&分割
if (isContainsChars(var, arg4)) {
String[] temp2 = getArrayByChar(var, arg4);
String[] temp3;
if(temp2.length == 1){
temp3 = getArrayByChar(temp2[0], arg3);
}else{
temp3 = getArrayByChar(temp2[1], arg3);
}
if (temp3.length == 2) {
if(arg7.equals(temp3[0])){
map.put(temp3[0],formatDateStr(temp3[1]));
}else{
map.put(temp3[0], temp3[1]);
}
}
} else {
// 数据直接是key=value格式
String[] temp4 = getArrayByChar(var, arg3);
if (temp4.length == 2) {
if(arg7.equals(temp4[0])){
map.put(temp4[0],formatDateStr(temp4[1]));
}else{
map.put(temp4[0], temp4[1]);
}
}
}
} /**
* 根据指定字符分割字符串
*
* @param datastr
* @param s
* @return
*/
public static String[] getArrayByChar(String datastr, String s) {
if (isEmpty(datastr) || !isContainsChars(datastr, s)) {
return null;
}
return datastr.trim().replaceAll("\\s*", arg).split(s);
} /**
* 判断字符串是否包含指定字符串
*
* @param str
* @return
*/
public static boolean isContainsChars(String str, String arg) {
if (isEmpty(str) || isEmpty(arg)) {
return false;
}
return str.contains(arg);
}
/**
* 判断字符串是否为空
*
* @param str
* @return
*/
public static boolean isEmpty(String str) {
return str == null || arg.equals(str);
} /**
* 格式化时间字符串
* @param datestr
* @return
*/
public static String formatDateStr(String datestr){
if(isEmpty(datestr)){
return arg;
}
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
try {
Date date = format.parse(datestr);
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
} catch (ParseException e) {
e.printStackTrace();
}
return datestr;
} }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

包结构如下

  1.3 创建entity

package com.example.demo1.entity;

import java.util.Date;

/**
* 数据
* @author chenxiaokang
* @date 2019/10/15 10:26
*/
public class Pollute {
private String key;
private String value;
private Date dateAdd; public Date getDateAdd() {
return dateAdd;
} public void setDateAdd(Date dateAdd) {
this.dateAdd = dateAdd;
} public String getValue() {
return value;
} public void setValue(String value) {
this.value = value;
} public String getKey() {
return key;
} public void setKey(String key) {
this.key = key;
}
}

  1.4 将项目打包成jar,并拷贝到flume中lib(需要将mysql的jar也要考进去)

2.flume中conf配置(模拟数据需要将agent.sources.ri.type 改为 avro)并启动flume 命令/opt/flume/bin/flume-ng agent --conf-file /opt/flume/conf/flume-conf.properties -n agent -c /opt/flume/conf/  -Dflume.root.logger=DEBUG,console

3.编写模拟发送数据类并启动

package com.example.demo1.utils;

import org.apache.flume.Event;
import org.apache.flume.EventDeliveryException;
import org.apache.flume.api.RpcClient;
import org.apache.flume.api.RpcClientFactory;
import org.apache.flume.event.EventBuilder;
import java.nio.charset.Charset; /**
* @author chenxiaokang
* @date 2019/10/14 18:32
*/
public class CouScoketUtil { public static void main(String[] args) throws Exception {
MyRpcClientFacade client = new MyRpcClientFacade();
// Initialize client with the remote Flume agent's host and port
client.init("服务器IP地址", 7001); // Send 10 events to the remote Flume agent. That agent should be
// configured to listen with an AvroSource.
// String sampleData = "ERROR";
String sampleData = "ST=91;CN=9011;PW=123456;MN=88888880000001;Flag=0;CP=&&QN=20040516010101001;QnRtn=1&&";
System.out.println("发送数据");
client.sendDataToFlume(sampleData);
client.cleanUp();
}
} class MyRpcClientFacade {
private RpcClient client;
private String hostname;
private int port; public void init(String hostname, int port) {
// Setup the RPC connection
this.hostname = hostname;
this.port = port;
this.client = RpcClientFactory.getDefaultInstance(hostname, port);
System.out.println("建立连接");
// Use the following method to create a thrift client (instead of the
// above line):
// this.client = RpcClientFactory.getThriftInstance(hostname, port);
} public void sendDataToFlume(String data) {
// Create a Flume Event object that encapsulates the sample data
Event event = EventBuilder.withBody(data, Charset.forName("UTF-8"));
try {
client.append(event);
} catch (EventDeliveryException e) {
// clean up and recreate the client
client.close();
client = null;
client = RpcClientFactory.getDefaultInstance(hostname, port);
// Use the following method to create a thrift client (instead of
// the above line):
// this.client = RpcClientFactory.getThriftInstance(hostname, port);
}
} public void cleanUp() {
// Close the RPC connection
System.out.println("断开连接");
client.close();
}
}

4.数据保存成功

flume客户端模拟数据发送并记录在mysql数据库的更多相关文章

  1. FLUME安装&环境(二):拉取MySQL数据库数据到Kafka

    Flume安装成功,环境变量配置成功后,开始进行agent配置文件设置. 1.agent配置文件(mysql+flume+Kafka) #利用Flume将MySQL表数据准实时抽取到Kafka a1. ...

  2. MySQL数据表修复, 如何修复MySQL数据库(MyISAM / InnoDB)

    常用的Mysql数据库修复方法有下面3种: 1. mysql原生SQL命令: repair 即执行REPAIR TABLE SQL语句 语法:REPAIR TABLE tablename[,table ...

  3. Java基础知识➣发送Emai和访问MySQL数据库(七)

    概述 Java程序发送 E-mail 十分简单,但是首先你应该在你的机器上安装 JavaMail API 和Java Activation Framework (JAF) .Java访问数据则需要 使 ...

  4. 使用log4net无法将日志记录插入mysql数据库解决办法

    写在前面 今天没事研究了下,将日志文件写入mysql数据库,因为新公司用的数据库也是mysql,项目中需要将日志信息写入数据库,没办法,就研究了下.在使用过程中遇到一个很蛋疼的问题.最后解决了,郁闷了 ...

  5. 信息技术手册可视化进度报告 基于BeautifulSoup框架的python3爬取数据并连接保存到MySQL数据库

    老师给我们提供了一个word文档,里面是一份信息行业热词解释手册,要求我们把里面的文字存进数据库里面,然后在前台展示出来. 首先面临的问题是怎么把数据导进MySQL数据库,大家都有自己的方法,我采用了 ...

  6. telnet客户端模拟浏览器发送请求

    telnet 客户端 telnet客户端能够发出请求去连接服务器(模拟浏览器) 使用telnet之前,需要开启telnet客户端 1.进入控制面板 2.进入程序和功能,选择打开或关闭windows功能 ...

  7. Fiddler使用 断点 模拟返回 AutoResponder Mock 模拟数据 相关学习记录

    断点 测试中有时需要改变发出去的请求信息,需要用到打断点的方法.断点包含两种方式: before response:在request请求的时候,未到达服务器之前,一般用来修改请求参数 after re ...

  8. 亿条数据在PHP中实现Mysql数据库分表100张

    当数据量猛增的时候,大家都会选择库表散列等等方式去优化数据读写速度.笔者做了一个简单的尝试,1亿条数据,分100张表.具体实现过程如下: 首先创建100张表: $i=0; while($i<=9 ...

  9. 1亿条数据在PHP中实现Mysql数据库分表100张

    当数据量猛增的时候,大家都会选择库表散列等等方式去优化数据读写速度.笔者做了一个简单的尝试,1亿条数据,分100张表.具体实现过程如下: 首先创建100张表: $i=0; while($i<=9 ...

随机推荐

  1. Block as a Value for SQL over NoSQL

    作者 Yang Cao,Wenfei Fan,Tengfei Yuan University of Edinburgh,Beihang University SICS, Shenzhen Univer ...

  2. 玩转 .NET Core 3.0:逐浪CMS新版发布,建站更简单、网站更安全

    2019年11月11日,在大家都忙于网上体会“双11 ”的热闹气氛的时候,逐浪CMS开发者团队正在做着新版本发布的最后工作.此次更新是基本于 .NET Core 3.0开发,也是全国首个基于 .NET ...

  3. 【Oracle】RAC的多实例数据迁移至单机的多实例。

    思路:一般的思路可以通过RMAN进行数据的恢复.由于数据库可以停机,因此,这次试用数据泵(expdp,impdp)进行数据 的导入导出. 1.源数据库导出 通过编写导出shell脚本导出数据,如下: ...

  4. 去除 inline-block 元素间距

    案例重现 布局时经常能发现inline元素和inline-block元素水平呈现的元素间,会存在着一些意想不到的间距,举例: .inline-block { display: inline-block ...

  5. css中:link和@import的区别

    两者都是外部引用css的方式.但是有一定的区别: 1. 从属关系:link是一个xhtml标签,除了加载css外,还可以定义 RSS.rel 连接属性等: @import属于css范畴,只能加载css ...

  6. React hooks详解

    此篇文章仅是对hooks入门的总结,老鸟略过吧~ React从16.8.X以后增加了一个新特性,react hooks 让我们看看这个新特性又带来了哪些惊喜呢~以下内容我们采取不同方式创建组件来进行对 ...

  7. php 生成游戏兑换码(礼包)方法

    最近项目中要做礼包码生成,看了看网上的代码,可以使用php扩展unid 当然我这里并不是用的unid,而是使用的php自带的uniqid,人狠话不多.看代码 /** * 生成礼包接口 100W数据同时 ...

  8. 【Weiss】【第03章】增补附注

    基本上每章到增补附注这里就算是结束了. 根据设想,每章的这一篇基本上会注明这一章哪些题没有做,原因是什么,如果以后打算做了也会在这里补充. 还有就是最后会把有此前诸多习题的代码和原数据结构放整理后,以 ...

  9. DOM-XSS攻击原理与防御

    XSS的中文名称叫跨站脚本,是WEB漏洞中比较常见的一种,特点就是可以将恶意HTML/JavaScript代码注入到受害用户浏览的网页上,从而达到劫持用户会话的目的.XSS根据恶意脚本的传递方式可以分 ...

  10. IDENTITY_INSERT 设置为 OFF 时,不能为表中的标识列插入显式值 的解决方法一例

    如题 IDENTITY_INSERT 设置为 OFF 时,不能为表中的标识列插入显式值 很多网上的文章是设置表的 IDENTITY_INSERT 为 ON EF中还要对模型就行设置 [Column(N ...