一、前言
zeromq pub-sub模型,发布者将一系列数据发送到订阅者。例如Rss 和微博关注
二、code
#-------------# | Publisher | +-------------+ | PUB | '-------------' bind | | updates | .---------------+---------------. | | | updates updates updates | | | | | | v v v connect connect connect .------------. .------------. .------------. | SUB | | SUB | | SUB | +------------+ +------------+ +------------+ | Subscriber | | Subscriber | | Subscriber | #------------# #------------# #------------#
例子如下:发布者发布一系列有地点,温度和相对湿度的气候数据,订阅者获取感兴趣的数据例如1001站点
publish
package com.bitch.mq.pub_sub;
import org.zeromq.ZMQ;
import java.util.Random;
//
// Weather update server in Java
// Binds PUB socket to tcp://*:5556
// Publishes random weather updates
//
public class wuserver {
public static void main (String[] args) throws Exception {
// Prepare our context and publisher
ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket publisher = context.socket(ZMQ.PUB);
publisher.bind("tcp://*:5556");
//publisher.bind("ipc://weather");
// Initialize random number generator
Random srandom = new Random(System.currentTimeMillis());
while (!Thread.currentThread().isInterrupted ()) {
// Get values that will fool the boss
int zipcode, temperature, relhumidity;
zipcode = 10000 + srandom.nextInt(10000) ;
temperature = srandom.nextInt(215) - 80 + 1;
relhumidity = srandom.nextInt(50) + 10 + 1;
// Send message to all subscribers
String update = String.format("%05d %d %d", zipcode, temperature, relhumidity);
// System.out.println("send data****************"+update);
publisher.send(update, 0);
}
publisher.close ();
context.term ();
}
}
subscribe
package com.bitch.mq.pub_sub;
import org.zeromq.ZMQ;
import java.util.StringTokenizer;
//
// Weather update client in Java
// Connects SUB socket to tcp://localhost:5556
// Collects weather updates and finds avg temp in zipcode
//
public class wuclient {
public static void main (String[] args) {
ZMQ.Context context = ZMQ.context(1);
// Socket to talk to server
System.out.println("Collecting updates from weather server");
ZMQ.Socket subscriber = context.socket(ZMQ.SUB);
subscriber.connect("tcp://localhost:5556");
// Subscribe to zipcode, default is NYC, 10001
String filter = (args.length > 0) ? args[0] : "10001 ";
subscriber.subscribe(filter.getBytes());
// Process 100 updates
int update_nbr;
long total_temp = 0;
for (update_nbr = 0; update_nbr < 100; update_nbr++) {
// Use trim to remove the tailing '0' character
String string = subscriber.recvStr(0).trim();
System.out.println(string);
StringTokenizer sscanf = new StringTokenizer(string, " ");
int zipcode = Integer.valueOf(sscanf.nextToken());
int temperature = Integer.valueOf(sscanf.nextToken());
int relhumidity = Integer.valueOf(sscanf.nextToken());
total_temp += temperature;
}
System.out.println("Average temperature for zipcode '"
+ filter + "' was " + (int) (total_temp / update_nbr));
subscriber.close();
context.term();
}
}
三、模式存在问题
1、一个订阅方实际上可以链接到不止一个发布方,每次使用一条连接命令。数据会交叉到达,
因此没有哪个单一的发布方能够淹没其它发布方。
2、 如果一个发布方没有与它连接的订阅方,它会简单的扔掉所有消息。
3、 如果你使用TCP,并且订阅方很慢,消息将会在发布方排队。我们将会看到随后如何使用“高水准”的方法来避免这种情况的出现。