Redis系列 -5 【Storm-redis-pubsub】 -Storm接口系列

简单实现,参看代码说话:

package yieldbot.storm.spout;

import static backtype.storm.utils.Utils.tuple;

import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;

import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;

import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields;
import backtype.storm.utils.Utils;

public class RedisPubSubSpout extends BaseRichSpout {
	
	static final long serialVersionUID = 737015318988609460L;
	static Logger LOG = Logger.getLogger(RedisPubSubSpout.class);
	
	SpoutOutputCollector _collector;
	final String host;
	final int port;
	final String pattern;
	LinkedBlockingQueue<String> queue;
	JedisPool pool;
	
	public RedisPubSubSpout(String host, int port, String pattern) {
		this.host = host;
		this.port = port;
		this.pattern = pattern;
	}
	
	
	//在这里有一个监控的线程类
	class ListenerThread extends Thread {
		LinkedBlockingQueue<String> queue;
		JedisPool pool;
		String pattern;
		
		public ListenerThread(LinkedBlockingQueue<String> queue, JedisPool pool, String pattern) {
			this.queue = queue;
			this.pool = pool;
			this.pattern = pattern;
		}
		
		public void run() {
			
			
		        // JedisPubSub 对象去Redis中间去订阅一个数据的通道
			JedisPubSub listener = new JedisPubSub() {

				@Override
				public void onMessage(String channel, String message) {
					queue.offer(message);
				}

				@Override
				public void onPMessage(String pattern, String channel, String message) {
					queue.offer(message);
				}

				@Override
				public void onPSubscribe(String channel, int subscribedChannels) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onPUnsubscribe(String channel, int subscribedChannels) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onSubscribe(String channel, int subscribedChannels) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onUnsubscribe(String channel, int subscribedChannels) {
					// TODO Auto-generated method stub
					
				}
			};
			
			
			// 从池中取得对象
			Jedis jedis = pool.getResource();
			try {
			
			        /**
			        ** listener 一个监听的线程
			        ** pattern  模式
			        /
				jedis.psubscribe(listener, pattern);
			} finally {
			
			        try
			        {
				pool.returnResource(jedis);
			        }catch(Eexception e)
			         {
			           
			           //有关 pool.returnResource(jedis)的诡异现象请参考
			           //http://www.tuicool.com/articles/aUra2m
			             System.out.println("请务必使用try-catch");         
			  
			         }
			
			}
		}
	};
	
	public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
		_collector = collector;、
		
		
		// 初始化队列,pool,和监控的线程
		queue = new LinkedBlockingQueue<String>(1000);
		pool = new JedisPool(new JedisPoolConfig(),host,port);
		
		ListenerThread listener = new ListenerThread(queue,pool,pattern);
		listener.start();
		
	}

	public void close() {
		pool.destroy();
	}

	public void nextTuple() {
	
	        // 从队列之中取值的一个过程,在这里判断为空以后,就开始不断的使用Storm发射数据
		String ret = queue.poll();
        if(ret==null) {
            Utils.sleep(50);
        } else {
            _collector.emit(tuple(ret));            
        }
	}

	public void ack(Object msgId) {
		// TODO Auto-generated method stub

	}

	public void fail(Object msgId) {
		// TODO Auto-generated method stub

	}

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

	public boolean isDistributed() {
		return false;
	}
}


    

   Plus:    

            如果您对于Java数据结构不熟悉,请参考本ID的博文:

                Java【集合类型】 - LinedBolockingQueue 详解。

             如果您对于Redis-Clinet : jedis API 使用不够熟悉,还请参看本ID的博文:

                Redis【Jedis】 - 基本Api 使用详解

             如不透彻,还请自行google , 

            

            Thanks 。               



你可能感兴趣的:(Redis系列 -5 【Storm-redis-pubsub】 -Storm接口系列)