Storm的消息队列接入以及多种方式落地实例代码实现

一 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.0http://maven.apache.org/xsd/maven-4.0.0.xsd";>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.cakin</groupId>
     <artifactId>stormexapmle</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <packaging>jar</packaging>
     <name>stormexapmle</name>
     <url>http://maven.apache.org</url>
     <properties>
          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
     <dependencies>
           <dependency>
                <groupId>org.apache.storm</groupId>
                <artifactId>storm-core</artifactId>
                <version>0.9.2-incubating</version>
                <exclusions>
                     <exclusion>
                          <artifactId>log4j-over-slf4j</artifactId>
                           <groupId>org.slf4j</groupId>
                     </exclusion>
                     <!--与 slf4j-log4j12 冲突,所以需要进行exclude移除 -->
                </exclusions>
           </dependency>
           <!--metaq依赖 -->
           <dependency>
                <groupId>com.taobao.metamorphosis</groupId>
                <artifactId>metamorphosis-commons</artifactId>
                <version>1.4.6.2</version>
           </dependency>
           <dependency>
                <groupId>com.taobao.metamorphosis</groupId>
                <artifactId>metamorphosis-client</artifactId>
                <version>1.4.6.2</version>
           </dependency>
           <!--mysql依赖 -->
           <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.22</version>
           </dependency>
           <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
           </dependency>
     </dependencies>
</project>

二 数据生产类
1 DataProDucer
package sourcedata;
import com.taobao.metamorphosis.Message;
import com.taobao.metamorphosis.client.MessageSessionFactory;
import com.taobao.metamorphosis.client.MetaClientConfig;
import com.taobao.metamorphosis.client.MetaMessageSessionFactory;
import com.taobao.metamorphosis.client.producer.MessageProducer;
import com.taobao.metamorphosis.client.producer.SendResult;
import com.taobao.metamorphosis.utils.ZkUtils;
import java.util.Random;
//该的目的是构造一个随机的domain数据集
public class DataProDucer {
    private static String topic = "test";
    private static String zkRoot = "/meta";
    private static String zkConnect = "192.168.0.110:2181";
    private static  MetaClientConfig metaClientConfig;
    private transient static MessageSessionFactory sessionFactory;
    private transient static MessageProducer messageProducer;
    private transient static SendResult sendResult;
    public static void main(String[] args) throws Exception {
        Random random = new Random();
        //构造一个随机记录
        String[] net0 = {"baidu", "hitwh", "google", "jikexueyuan", "hadoop",
                "storm", "blogchong", "cooje", "mite8", "mygod"};
        String[] net1 = {"com", "net", "cn", "edu", "tv", "org", "us", "jp","club" ,"pub",
                "rec", "info"};
        String[] times = {"2000", "2001", "2002", "2005", "2007", "2010",
                "2011", "2012", "2013", "1998", "2014", "2015"};
        String[] value = {"1326", "1446", "1401", "1202", "1871", "2000",
                "122", "23000", "400", "240", "8888", "100000", "34123"};
        String[] validity = {"3", "5", "20", "100", "32", "12", "50", "1",
                "23", "45", "200"};
        String[] seller = {"Huang", "Lina", "James", "Gale", "Kathryn",
                "Acong", "Green", "Facke", "Nina", "Litao", "Pony", "Blogchong", "Mite"};
        ZkUtils.ZKConfig zkconf = new ZkUtils.ZKConfig();
        zkconf.zkConnect = zkConnect;
        zkconf.zkRoot = zkRoot;
        MetaClientConfig metaconf = new MetaClientConfig();
        metaconf.setZkConfig(zkconf);
        metaClientConfig = metaconf;
        sessionFactory = new MetaMessageSessionFactory(metaClientConfig);
        messageProducer = sessionFactory.createProducer();
        messageProducer.publish(topic);
        while (true) {
            // 构造域名
            String net = "www."; + net0[random.nextInt(net0.length)] + "."
                    + net1[random.nextInt(net1.length)];
            String records = net + "\t" + value[random.nextInt(value.length)] + "\t"
                    + times[random.nextInt(times.length)] + "\t"
                    + validity[random.nextInt(validity.length)] + "\t"
                    + seller[random.nextInt(seller.length)];
            sendResult = messageProducer
                    .sendMessage(new Message(topic, (records).getBytes()));
            if (sendResult.isSuccess()) {
                System.out.println("消息:[" + records + "] 发送成功!");
            } else {
                System.err.println("消息:[" + records + "] 发送失败!");
            }
            Thread.sleep(100);
        }
    }
}
2 GetSource
package sourcedata;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Random;
/**
 * @Des 构造一个随机的域名交易信息源,写入文件中
 */
//该的目的是构造一个随机的domain数据集
public class GetSource {
    public static void main(String[] args) {
        Random random = new Random();
        int note_num = 10000;
        //构造一个随机记录
        String[] net0 = {"baidu", "hitwh", "google", "jikexueyuan", "hadoop",
                "storm", "blogchong", "cooje", "mite8", "mygod"};
        String[] net1 = {"com", "net", "cn", "edu", "tv", "org", "us", "jp","club" ,"pub",
                "rec", "info"};
        String[] times = {"2000", "2001", "2002", "2005", "2007", "2010",
                "2011", "2012", "2013", "1998", "2014", "2015"};
        String[] value = {"1326", "1446", "1401", "1202", "1871", "2000",
                "122", "23000", "400", "240", "8888", "100000", "34123"};
        String[] validity = {"3", "5", "20", "100", "32", "12", "50", "1",
                "23", "45", "200"};
        String[] seller = {"Huang", "Lina", "James", "Gale", "Kathryn",
                "Acong", "Green", "Facke", "Nina", "Litao", "Pony", "Blogchong", "Mite"};
        // 写入中文字符时解决中文乱码问题
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(new File("domain.log"));
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        OutputStreamWriter osw = null;
        try {
            osw = new OutputStreamWriter(fos, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        BufferedWriter bw = new BufferedWriter(osw);
        for (int i = 0; i < note_num; i++) {
            // 构造域名
            String net = "www."; + net0[random.nextInt(net0.length)] + "."
                    + net1[random.nextInt(net1.length)];
            String records = net + "\t" + value[random.nextInt(value.length)] + "\t"
                    + times[random.nextInt(times.length)] + "\t"
                    + validity[random.nextInt(validity.length)] + "\t"
                    + seller[random.nextInt(seller.length)];
            try {
                bw.write(records);
                bw.newLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 注意关闭的先后顺序,先打开的后关闭,后打开的先关闭
        try {
            bw.close();
            osw.close();
            fos.close();
            System.out.println("write ok !");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

三 Spout类
1 MetaSpout类
package spout;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import com.taobao.gecko.core.util.LinkedTransferQueue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import backtype.storm.spout.Scheme;
import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichSpout;
import backtype.storm.topology.OutputFieldsDeclarer;
import util.ConfCheck;
import util.MacroDef;
import util.SpoutMetaq.MetaMessageWrapper;
import util.SpoutMetaq.StringScheme;
import xml.SpoutXml;
import com.taobao.metamorphosis.client.MetaClientConfig;
import com.taobao.metamorphosis.exception.MetaClientException;
import com.taobao.metamorphosis.utils.ZkUtils.ZKConfig;
import com.taobao.metamorphosis.Message;
import com.taobao.metamorphosis.client.MessageSessionFactory;
import com.taobao.metamorphosis.client.MetaMessageSessionFactory;
import com.taobao.metamorphosis.client.consumer.ConsumerConfig;
import com.taobao.metamorphosis.client.consumer.MessageConsumer;
import com.taobao.metamorphosis.client.consumer.MessageListener;
/**
 * @Des Spout数据源,从metaq中消费数据
 */
public class MetaSpout implements IRichSpout {
    public static final String FETCH_MAX_SIZE = "meta.fetch.max_size";
    public static final String TOPIC = "meta.topic";
    public static final int DEFAULT_MAX_SIZE = 128 * 1024;
    private transient MessageConsumer messageConsumer;
    private transient MessageSessionFactory sessionFactory;
    private MetaClientConfig metaClientConfig;
    private ConsumerConfig consumerConfig;
    static final Log log = LogFactory.getLog(MetaSpout.class);
    public static final long WAIT_FOR_NEXT_MESSAGE = 1L;
    private transient ConcurrentHashMap<Long, MetaMessageWrapper> id2wrapperMap;
    private transient SpoutOutputCollector collector;
    private transient LinkedTransferQueue<MetaMessageWrapper> messageQueue;
    private long spout_debug = 5;
    private long register = 0;
    private long reg_tmp = 0;
    private boolean spout_flag = true;
    String topic = "storm-test";
    private final Scheme scheme = new StringScheme();
    private boolean flag_par = true;
    private String spoutXml = "MetaSpout.xml";
    //是否加载配置标志位
    private static boolean flag_load = false;
    @SuppressWarnings("rawtypes")
    private Map conf = null;
    public MetaSpout(String SpoutXml) {
        super();
        if (SpoutXml == null) {
            this.flag_par = false;
        } else {
            this.spoutXml = SpoutXml;
        }
    }
    @SuppressWarnings("rawtypes")
    public void open(final Map conf, final TopologyContext context,
                     final SpoutOutputCollector collector) {
        System.out.println("MetaSpout--   Start!");
        this.collector = collector;
        this.conf = conf;
        this.spout_debug = MacroDef.SPOUT_DEBUG;
        this.spout_flag = MacroDef.SPOUT_FLAG;
        this.reg_tmp = this.spout_debug;
        if (!this.flag_par) {
            System.out
                    .println("MetaSpout-- Erre: can't get the path of Spout.xml!");
        } else {
            // 调用检测线程
            new ConfCheck(this.spoutXml, MacroDef.HEART_BEAT,
                    MacroDef.Thread_type_metaqspout).start();
        }
    }
    private void setUpMeta(final String topic, final Integer maxSize)
            throws MetaClientException {
        this.sessionFactory = new MetaMessageSessionFactory(
                this.metaClientConfig);
        this.messageConsumer = this.sessionFactory
                .createConsumer(this.consumerConfig);
        this.messageConsumer.subscribe(topic, maxSize, new MessageListener() {
            public void recieveMessages(final Message message) {
                final MetaMessageWrapper wrapper = new MetaMessageWrapper(
                        message);
                MetaSpout.this.id2wrapperMap.put(message.getId(), wrapper);
                MetaSpout.this.messageQueue.offer(wrapper);
                try {
                    wrapper.latch.await();
                } catch (final InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                // 获取数据失败
                if (!wrapper.success) {
                    throw new RuntimeException("MetaSpout  --     Obtain data fail!");
                }
            }
            public Executor getExecutor() {
                return null;
            }
        }).completeSubscribe();
    }
    public void close() {
        try {
            this.messageConsumer.shutdown();
        } catch (final MetaClientException e) {
            log.error("Shutdown consumer failed", e);
        }
        try {
            this.sessionFactory.shutdown();
        } catch (final MetaClientException e) {
            log.error("Shutdown session factory failed", e);
        }
    }
    //更改标志位
    public static void isload() {
        flag_load = false;
    }
    // 加载参数操作
    public void Loading() {
        // MetaSpout参数
        new SpoutXml(this.spoutXml).read();
        // 读取接收Topic
        String MetaRevTopic = SpoutXml.MetaRevTopic;
        // 读取MetaQ所在zk地址
        String MetaZkConnect = SpoutXml.MetaZkConnect;
        // 读取MetaQ所在的zk配置
        String MetaZkRoot = SpoutXml.MetaZkRoot;
        // 读取metaqconsumer配置“strom-test01”
        String MetaConsumerGroup = SpoutXml.MetaConsumerConf;
        // 获取连接zk配置(metaq)
        ZKConfig zkconf = new ZKConfig();
        // zkconf.zkConnect // ="192.168.5.240:2181";//
        zkconf.zkConnect = MetaZkConnect;
        // zkconf.zkRoot = "/meta";
        zkconf.zkRoot = MetaZkRoot;
        MetaClientConfig metaconf = new MetaClientConfig();
        metaconf.setZkConfig(zkconf);
        this.metaClientConfig = metaconf;
        this.consumerConfig = new ConsumerConfig(MetaConsumerGroup);
        this.topic = MetaRevTopic;
        if (this.topic == null) {
            throw new IllegalArgumentException(TOPIC + " is null");
        }
        Integer maxSize = (Integer) conf.get(FETCH_MAX_SIZE);
        if (maxSize == null) {
            log.warn("Using default FETCH_MAX_SIZE");
            maxSize = DEFAULT_MAX_SIZE;
        }
        this.id2wrapperMap = new ConcurrentHashMap<Long, MetaMessageWrapper>();
        this.messageQueue = new LinkedTransferQueue<MetaMessageWrapper>();
        try {
            this.setUpMeta(this.topic, maxSize);
        } catch (final MetaClientException e) {
            log.error("Setup meta consumer failed", e);
        }
        flag_load = true;
    }
    // 数据发布操作
    public void nextTuple() {
        if (!this.flag_par) {
            // 配置文件中参数为空(无法从配置文件中获取正确参数)
            System.out
                    .println("MetaSpout-- Erre: can't get the path of Spout.xml!");
        } else {
            // 检测配置文件是否更改
            if (!flag_load) {
                // 检测配置文件是否更改
                Loading();
                if (register != 0) {
                    System.out.println("MetaSpout-- Conf Change: "
                            + this.spoutXml);
                } else {
                    System.out.println("MetaSpout-- Conf Loaded: "
                            + this.spoutXml);
                }
            }
            if (this.messageConsumer != null) {
                try {
                    final MetaMessageWrapper wrapper = this.messageQueue.poll(
                            WAIT_FOR_NEXT_MESSAGE, TimeUnit.MILLISECONDS);
                    if (wrapper == null) {
                        return;
                    }
                    final Message message = wrapper.message;
                    // 统计数据量,并且输出打印
                    this.register++;
                    if (this.register >= this.reg_tmp) {
                        if (this.spout_flag) {
                            System.out
                                    .println("MetaSpout    --     Send Tuple Count: "
                                            + this.register);
                        }
                        this.reg_tmp = this.register + this.spout_debug;
                    }
                    // 数据发布操作
                    this.collector.emit(
                            this.scheme.deserialize(message.getData()),
                            message.getId());
                    Thread.sleep(100);
                } catch (final InterruptedException e) {
                }
            }
        }
    }
    public void ack(final Object msgId) {
        if (msgId instanceof Long) {
            final long id = (Long) msgId;
            final MetaMessageWrapper wrapper = this.id2wrapperMap.remove(id);
            if (wrapper == null) {
                System.out.println("MetaSpout--ack");
                log.warn(String.format("don't know how to ack(%s: %s)", msgId
                        .getClass().getName(), msgId));
                return;
            }
            wrapper.success = true;
            wrapper.latch.countDown();
        } else {
            System.out.println("MetaSpout--ack");
            log.warn(String.format("don't know how to ack(%s: %s)", msgId
                    .getClass().getName(), msgId));
        }
    }
    public void fail(final Object msgId) {
        if (msgId instanceof Long) {
            final long id = (Long) msgId;
            final MetaMessageWrapper wrapper = this.id2wrapperMap.remove(id);
            if (wrapper == null) {
                System.out.println("MetaSpout--fail");
                log.warn(String.format("don't know how to reject(%s: %s)",
                        msgId.getClass().getName(), msgId));
                return;
            }
            wrapper.success = false;
            wrapper.latch.countDown();
        } else {
            System.out.println("MetaSpout--fail");
            log.warn(String.format("don't know how to reject(%s: %s)", msgId
                    .getClass().getName(), msgId));
        }
    }
    public void declareOutputFields(final OutputFieldsDeclarer declarer) {
        declarer.declare(this.scheme.getOutputFields());
    }
    public boolean isDistributed() {
        return true;
    }
    public void activate() {
    }
    public void deactivate() {
    }
    public Map<String, Object> getComponentConfiguration() {
        return null;
    }
}
2 ReadLogSpout类
package spout;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Map;
import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichSpout;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values;
import util.MacroDef;
/**
 * @Des Spout数据源,从log文件中直接读取数据
 */
public class ReadLogSpout implements IRichSpout {
     private SpoutOutputCollector collector;
     FileInputStream fis;
     InputStreamReader isr;
     BufferedReader br;
     @SuppressWarnings("rawtypes")
     public void open(Map conf, TopologyContext context,
                SpoutOutputCollector collector) {
           this.collector = collector;
           
           String file = "domain.log";
           try {
                this.fis = new FileInputStream(file);
                this.isr = new InputStreamReader(fis, MacroDef.ENCODING);
                this.br = new BufferedReader(isr);
           } catch (Exception e) {
                e.printStackTrace();
           }
     }
     public void close() {
     }
     public void activate() {
     }
     public void deactivate() {
     }
     public void nextTuple() {
           String str = "";
           try {
                while ((str = this.br.readLine()) != null) {
                     this.collector.emit(new Values(str));
                     Thread.sleep(100);
                }
           } catch (Exception e) {
                e.printStackTrace();
           }
     }
     public void ack(Object msgId) {
     }
     public void fail(Object msgId) {
     }
     public void declareOutputFields(OutputFieldsDeclarer declarer) {
           declarer.declare(new Fields("str"));
     }
     public Map<String, Object> getComponentConfiguration() {
           return null;
     }
}

四 数据过滤bolt
package bolt;
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichBolt;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
import util.ConfCheck;
import util.MacroDef;
import xml.FilterXml;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @Des 过滤Bolt,进行数据的正则过滤,范围过滤以及普通字符串过滤
 */
@SuppressWarnings("serial")
public class FilterBolt implements IRichBolt {
     private OutputCollector collector;
    //是否加载配置标志位
     private static boolean flag_load = false;
     private long register = 0;
    //默认参数~~
     String monitorXml = "Filter.xml";
    // 参数判空标志
     private boolean flag_par = true;
    // 匹配条件间的逻辑关系
     String MatchLogic = "AND";
    // !--匹配类型列表
     String MatchType = "regular::range::routine0";
    // !--匹配字段列表-
     String MatchField = "1::2::5";
    // !--字段值列表-
     String FieldValue = ".*baidu.*::1000,2000::ina";
     public FilterBolt(String MonitorXML) {
           if (MonitorXML == null) {
                flag_par = false;
           } else {
                this.monitorXml = MonitorXML;
           }
     }
     @SuppressWarnings("rawtypes")
     public void prepare(Map stormConf, TopologyContext context,
                OutputCollector collector) {
           System.out.println("FilterBolt  --   Start!");
           this.collector = collector;
                     
           if (!this.flag_par) {
                System.out
                           .println("MetaSpout-- Erre: can't get the path of Spout.xml!");
           } else {
            // 调用检测线程
                new ConfCheck(this.monitorXml, MacroDef.HEART_BEAT,
                          MacroDef.Thread_type_filterbolt).start();
           }
     }
     public void execute(Tuple input) {
           String str = input.getString(0);
           if (!this.flag_par) {
                System.out
                           .println("FilterBolt-- Erre: can't get the path of Filter.xml!");
           } else {
            // 检测配置文件是否更改
                if (!flag_load ) {
                // 配置文件发生更改则进行加载参数操作
                     Loading();
                     if (register != 0) {
                           System.out.println("FilterBolt-- Conf Change: "
                                     + this.monitorXml);
                     } else {
                           System.out.println("FilterBolt-- Conf Loaded: "
                                     + this.monitorXml);
                     }
                }
                boolean moni = Monitor(str, this.MatchLogic, this.MatchType,
                           this.MatchField, this.FieldValue);
                if (moni) {
                     this.collector.emit(new Values(str));
                }
            this.collector.ack(input);
           }
     }
    //更改标志位
     public static void isload() {
           flag_load = false;
     }
    // 加载参数操作
     public void Loading() {
        // 从conf中获取参数
           System.out.println("FilterXml:     " + this.monitorXml);
           new FilterXml(this.monitorXml).read();
           this.MatchLogic = FilterXml.MatchLogic;
           this.MatchType = FilterXml.MatchType;
           this.MatchField = FilterXml.MatchField;
           this.FieldValue = FilterXml.FieldValue;
           flag_load = true;
     }
     private boolean Monitor(String str, String logic, String type,
                String field, String value) {
           String[] types = type.split(MacroDef.FLAG_COLON);
           String[] fields = field.split(MacroDef.FLAG_COLON);
           String[] values = value.split(MacroDef.FLAG_COLON);
           int flag_init = types.length;
           int flag = 0;
           if (logic.equals(MacroDef.RULE_AND)) {
                for (int i = 0; i < flag_init; i++) {
                     if (types[i].equals(MacroDef.RLUE_REGULAR)) {
                           boolean regu = regular(str, fields[i], values[i]);
                           if (regu) {
                                flag++;
                           }
                     } else if (types[i].equals(MacroDef.RULE_RANGE)) {
                           boolean ran = range(str, fields[i], values[i]);
                           if (ran) {
                                flag++;
                           }
                     } else if (types[i].equals(MacroDef.RULE_ROUTINE0)) {
                           boolean rou0 = routine0(str, fields[i], values[i]);
                           if (rou0) {
                                flag++;
                           }
                     } else if (types[i].equals(MacroDef.RULE_ROUTINE1)) {
                           boolean rou1 = routine1(str, fields[i], values[i]);
                           if (rou1) {
                                flag++;
                           }
                     }
                }
                if (flag == flag_init) {
                     return true;
                } else {
                     return false;
                }
                
           } else if (logic.equals(MacroDef.RULE_OR)) {
                
                for (int i = 0; i < flag_init; i++) {
                     if (types[i].equals(MacroDef.RLUE_REGULAR)) {
                           boolean regu = regular(str, fields[i], values[i]);
                           if (regu) {
                                flag++;
                           }
                     } else if (types[i].equals(MacroDef.RULE_RANGE)) {
                           boolean ran = range(str, fields[i], values[i]);
                           if (ran) {
                                flag++;
                           }
                     } else if (types[i].equals(MacroDef.RULE_ROUTINE0)) {
                           boolean rou0 = routine0(str, fields[i], values[i]);
                           if (rou0) {
                                flag++;
                           }
                     } else if (types[i].equals(MacroDef.RULE_ROUTINE1)) {
                           boolean rou1 = routine1(str, fields[i], values[i]);
                           if (rou1) {
                                flag++;
                           }
                     }
                }
                if (flag != 0) {
                     return true;
                } else {
                     return false;
                }
           }
           return false;
     }
    // 正则匹配判断
     private boolean regular(String str, String field, String value) {
           String[] strs = str.split(MacroDef.FLAG_TABS);
           Pattern p = Pattern.compile(value);
           Matcher m = p.matcher(strs[Integer.parseInt(field) - 1]);
           boolean result = m.matches();
           if (result) {
                return true;
           } else {
                return false;
           }
     }
    // 范围匹配
     private boolean range(String str, String field, String value) {
           String[] strs = str.split(MacroDef.FLAG_TABS);
           String[] values = value.split(MacroDef.FLAG_COMMA);
           int strss = Integer.parseInt(strs[Integer.parseInt(field) - 1]);
           if (values.length == 1) {
                if (strss > Integer.parseInt(values[0])) {
                     return true;
                } else {
                     return false;
                }
           } else if (values.length == 2 && values[0].length() == 0) {
                if (strss < Integer.parseInt(values[1])) {
                     return true;
                } else {
                     return false;
                }
           } else if (values.length == 2 && values[0].length() != 0) {
                if (strss > Integer.parseInt(values[0])
                           && strss < Integer.parseInt(values[1])) {
                     return true;
                } else {
                     return false;
                }
           } else {
                return false;
           }
     }
    // 常规模糊匹配
     private boolean routine0(String str, String field, String value) {
           String[] strs = str.split(MacroDef.FLAG_TABS);
           String strss = strs[Integer.parseInt(field) - 1];
           if (strss.contains(value)) {
                return true;
           } else {
                return false;
           }
     }
    // 常规完全匹配
     private boolean routine1(String str, String field, String value) {
           String[] strs = str.split(MacroDef.FLAG_TABS);
           String strss = strs[Integer.parseInt(field) - 1];
           if (strss.equals(value)) {
                return true;
           } else {
                return false;
           }
     }
     public void cleanup() {
     }
     public void declareOutputFields(OutputFieldsDeclarer declarer) {
           declarer.declare(new Fields("str"));
     }
     public Map<String, Object> getComponentConfiguration() {
           return null;
     }
}

五 数据落地
1 MetaBolt
package bolt;
import java.util.Map;
import com.taobao.metamorphosis.client.MetaClientConfig;
import com.taobao.metamorphosis.exception.MetaClientException;
import com.taobao.metamorphosis.utils.ZkUtils.ZKConfig;
import com.taobao.metamorphosis.Message;
import com.taobao.metamorphosis.client.MessageSessionFactory;
import com.taobao.metamorphosis.client.MetaMessageSessionFactory;
import com.taobao.metamorphosis.client.producer.MessageProducer;
import com.taobao.metamorphosis.client.producer.SendResult;
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.IRichBolt;
import backtype.storm.tuple.Tuple;
import util.ConfCheck;
import util.MacroDef;
import xml.MetaXml;
/**
 * @Des Metaq回写Bolt,数据生产
 */
@SuppressWarnings("serial")
public class MetaBolt implements IRichBolt {
    private MetaClientConfig metaClientConfig;
    // 是否加载配置标志位
    private static boolean flag_load = false;
    private transient MessageSessionFactory sessionFactory;
    private transient MessageProducer messageProducer;
    public static String Topic;
    private transient SendResult sendResult;
    String metaXml = "MetaBolt.xml";
    private boolean flag_par = true;
    private long meta_debug = 5;
    private long register = 0;
    private long reg_tmp = 0;
    public MetaBolt(String MetaXml) {
        super();
        if (MetaXml == null) {
            flag_par = false;
        } else {
            this.metaXml = MetaXml;
        }
    }
    @SuppressWarnings({"rawtypes"})
    public void prepare(final Map conf, TopologyContext context,
                        final OutputCollector collector) {
        System.out.println("MetaBolt --   Start!");
        this.reg_tmp = MacroDef.meta_debug;
        if (!this.flag_par) {
            System.out
                    .println("MetaSpout-- Erre: can't get the path of Spout.xml!");
        } else {
            // 调用检测线程
            new ConfCheck(this.metaXml, MacroDef.HEART_BEAT,
                    MacroDef.Thread_type_metaqbolt).start();
        }
    }
    @SuppressWarnings({"static-access", "unused"})
    public void execute(Tuple input) {
        String str = input.getString(0);
        if (!this.flag_par) {
            System.out
                    .println("MeataBolt-- Erre: can't get the path of MetaBolt.xml!");
        } else {
            try {
                // 检测配置文件是否更改
                if (!flag_load ) {
                    // 配置文件发生更改则进行加载参数操作
                    Loading();
                    if (register != 0) {
                        System.out.println("MetaBolt-- Conf Change: "
                                + this.metaXml);
                    } else {
                        System.out.println("MetaBolt-- Conf Loaded: "
                                + this.metaXml);
                    }
                }
                if (str != null) {
                    // 写入metaq的数据必须加上换行
                    str = str + MacroDef.FLAG_ROW;
                    this.sendResult = this.messageProducer
                            .sendMessage(new Message(this.Topic, str.getBytes()));
                    // 往metaq写数据
                    if (!sendResult.isSuccess()) {
                        System.err
                                .println("MetaBolt-- Send message failed,error message:"
                                        + sendResult.getErrorMessage());
                        System.err.println("MetaBolt-- Error Tuple: " + str);
                    } else {
                        System.out
                                .println("MetaBolt   --   Send Message success: "+ str);
                        this.register++;
                        if (this.register >= this.reg_tmp) {
                            if (!MacroDef.meta_flag ) {
                                System.out
                                        .println("MetaBolt --     Send Tuple Count: "
                                                + this.register);
                            }
                            this.reg_tmp = this.register + this.meta_debug;
                        }// 数量统计
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    // 更改标志位
    public static void isload() {
        flag_load = false;
    }
    // 加载参数操作
    public void Loading() {
        new MetaXml(this.metaXml).read();
        // MetaSpout参数
        // 读取接收Topic
        this.Topic = MetaXml.MetaTopic;
        // 获取连接zk配置(metaq)
        ZKConfig zkconf = new ZKConfig();
        // zkconf.zkConnect
        zkconf.zkConnect = MetaXml.MetaZkConnect;
        // zkconf.zkRoot = "/meta";
        zkconf.zkRoot = MetaXml.MetaZkRoot;
        MetaClientConfig metaconf = new MetaClientConfig();
        metaconf.setZkConfig(zkconf);
        this.metaClientConfig = metaconf;
        if (this.Topic == null) {
            throw new IllegalArgumentException(this.Topic + ":" + " is null");
        }
        try {
            this.sessionFactory = new MetaMessageSessionFactory(
                    this.metaClientConfig);
            this.messageProducer = this.sessionFactory.createProducer();
            this.messageProducer.publish(this.Topic);
        } catch (final MetaClientException e) {
            e.printStackTrace();
        }
        flag_load = true;
    }
    public void cleanup() {
    }
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
    }
    public Map<String, Object> getComponentConfiguration() {
        return null;
    }
}
2 MysqlBolt类
package bolt;
import java.util.Map;
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichBolt;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Tuple;
import util.ConfCheck;
import util.MacroDef;
import util.MysqlOpt;
import xml.MysqlXml;
/**
 * @Des 数据落地Mysql接口
 */
@SuppressWarnings("serial")
public class MysqlBolt implements IRichBolt {
     @SuppressWarnings("unused")
     private OutputCollector collector;
    //是否加载配置标志位
     private static boolean flag_load = false;
     
     private long register = 0;
     String mysqlXml = "Mysql.xml";
     MysqlOpt mysql = new MysqlOpt();
     private boolean flag_par = true;
     private boolean flag_xml = true;
     String from = "monitor"; // 表名
    // 构造函数
     public MysqlBolt(String MysqlXML) {
           if (MysqlXML == null) {
                flag_par = false;
           } else {
                this.mysqlXml = MysqlXML;
           }
     }
     public static void main(String[] args) {
     }
     @SuppressWarnings("rawtypes")
     public void prepare(Map stormConf, TopologyContext context,
                OutputCollector collector) {
           System.out.println("MysqlBolt   --   Start!");
           this.collector = collector;
           
           if (!this.flag_par) {
                System.out
                           .println("MetaSpout-- Erre: can't get the path of Spout.xml!");
           } else {
            // 调用检测线程
                new ConfCheck(this.mysqlXml, MacroDef.HEART_BEAT,
                          MacroDef.Thread_type_mysqlbolt).start();
           }
     }
    // 更改标志位
     public static void isload() {
           flag_load = false;
     }
    // 参数初始化
     public void Loading() {
           new MysqlXml(this.mysqlXml).read();
        // mysql地址及端口
           String host_port = MysqlXml.Host_port;
        // 数据库名
           String database = MysqlXml.Database;
        // 用户名
           String username = MysqlXml.Username;
        // 密码
           String password = MysqlXml.Password;
        // 表名
           this.from = MysqlXml.From;
           if (!this.mysql.connSQL(host_port, database, username, password)) {
                System.out
                           .println("MysqlBolt--Config errer, Please check Mysql-conf: "
                                     + this.mysqlXml);
                flag_xml = false;
           } else {
                System.out.println("MysqlBolt-- test connect mysql success: " + this.mysqlXml);
           }
        flag_load = true;
     }
     public void execute(Tuple input) {
           String str = input.getString(0);
           if (!this.flag_par) {
                System.out
                           .println("MysqlBolt-- Erre: can't get the path of Mysql.xml!");
           } else {
            // 检测配置文件是否更改
                if (!flag_load ) {
                // 配置文件发生更改则进行加载参数操作
                     Loading();
                     if (register != 0) {
                           System.out.println("MysqlBolt-- Conf Change: "
                                     + this.mysqlXml);
                     } else {
                           System.out.println("MysqlBolt-- Conf Loaded: "
                                     + this.mysqlXml);
                     }
                }
                if (this.flag_xml) {
                     String sql = send_str(str);
                     if (!this.mysql.insertSQL(sql)) {
                           System.out
                                     .println("MysqlBolt-- Erre: can't insert tuple into database!");
                           System.out.println("MysqlBolt-- Error Tuple: " + str);
                           System.out.println("SQL: " + sql);
                     }
                }
           }
     }
     public String send_str(String str) {
           String send_tmp = null;
           String field[] = str.split(MacroDef.FLAG_TABS);
           for (int i = 0; i < field.length; i++) {
                if (i == 0) {
                     send_tmp = "'" + field[0] + "', '";
                } else if (i == (field.length - 1)) {
                     send_tmp = send_tmp + field[i] + "'";
                } else {
                     send_tmp = send_tmp + field[i] + "', '";
                }
           }
           String send = "insert into " + this.from
                     + "(domain, value, time, validity, seller) values (" + send_tmp
                     + ");";
           return send;
     }
     public void cleanup() {
     }
     public void declareOutputFields(OutputFieldsDeclarer declarer) {
     }
     public Map<String, Object> getComponentConfiguration() {
           return null;
     }
}
3 PrintBolt
package bolt;

import backtype.storm.topology.BasicOutputCollector;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseBasicBolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;

/**
* @author blogchong
* @version 2015年06月07日 上午14:31:25
* @Blog www.blogchong.com
* @米特吧大数据论坛 www.mite8.com
* @email blogchong@163.com
* @QQ_G 191321336
* @Weixin: blogchong
* @Des 数据打印Bolt
*/

@SuppressWarnings("serial")
public class PrintBolt extends BaseBasicBolt {

    public static void main(String[] args) {

    }

    public void execute(Tuple input, BasicOutputCollector collector) {
        try {
            String mesg = input.getString(0);
            if (mesg != null)
                // 打印数据
                System.out.println("Tuple: " + mesg);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        declarer.declare(new Fields("mesg"));

    }

}

六 拓扑构建
import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.StormSubmitter;
import backtype.storm.generated.AlreadyAliveException;
import backtype.storm.generated.InvalidTopologyException;
import backtype.storm.topology.TopologyBuilder;
import bolt.FilterBolt;
import bolt.MetaBolt;
import bolt.MysqlBolt;
import bolt.PrintBolt;
import spout.MetaSpout;
/**
 * @Des  数据源Spout,从metaq中消费数据/从文本中读取数据
 */
public class Topology {
    // 实例化TopologyBuilder类。
     private static TopologyBuilder builder = new TopologyBuilder();
     public static void main(String[] args) throws InterruptedException,
                AlreadyAliveException, InvalidTopologyException {
           Config config = new Config();
        //数据源-->读取log文件/从消息队列metaq中消费
//         builder.setSpout("spout", new ReadLogSpout(), 1);
        builder.setSpout("spout", new MetaSpout("MetaSpout.xml"), 1);
        // 创建filter过滤节点
           builder.setBolt("filter", new FilterBolt("FilterBolt.xml"), 1)
                     .shuffleGrouping("spout");
        // 创建mysql数据存储节点
           builder.setBolt("mysql", new MysqlBolt("MysqlBolt.xml"), 1)
                     .shuffleGrouping("filter");
        //创建metaq回写节点
        builder.setBolt("meta", new MetaBolt("MetaBolt.xml"), 1)
                .shuffleGrouping("filter");
        //创建print消息打印节点
           builder.setBolt("print", new PrintBolt(), 1).shuffleGrouping("filter");
           config.setDebug(false);
           if (args != null && args.length > 0) {
                config.setNumWorkers(1);
                StormSubmitter.submitTopology(args[0], config,
                           builder.createTopology());
           } else {
            // 这里是本地模式下运行的启动代码。
                config.setMaxTaskParallelism(1);
                LocalCluster cluster = new LocalCluster();
                cluster.submitTopology("dataopttopology", config, builder.createTopology());
           }
     }
}

七 其他类

八 参考
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值