![JAR search and dependency download from the Maven repository](/logo.png)
org.zbus.server.ZbusServer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zbus-client Show documentation
Show all versions of zbus-client Show documentation
lightweight message queue, service bus
The newest version!
package org.zbus.server;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.zbus.common.BrokerInfo;
import org.zbus.common.BrokerMqInfo;
import org.zbus.common.MessageMode;
import org.zbus.common.Proto;
import org.zbus.logging.Logger;
import org.zbus.logging.LoggerFactory;
import org.zbus.remoting.Helper;
import org.zbus.remoting.Message;
import org.zbus.remoting.MessageHandler;
import org.zbus.remoting.RemotingClient;
import org.zbus.remoting.RemotingServer;
import org.zbus.remoting.callback.ErrorCallback;
import org.zbus.remoting.znet.Session;
import org.zbus.server.mq.AbstractMQ;
import org.zbus.server.mq.PubSub;
import org.zbus.server.mq.ReplyHelper;
import org.zbus.server.mq.MQ;
public class ZbusServer extends RemotingServer {
private static final Logger log = LoggerFactory.getLogger(ZbusServer.class);
private String adminToken = "";
private long trackDelay = 1000;
private long trackInterval = 3000;
private long mqCleanDelay = 1000;
private long mqCleanInterval = 3000;
private AdminHandler adminHandler;
private final Timer trackReportTimer = new Timer("TrackReportTimer", true);
private final Timer mqSessionCleanTimer = new Timer("MqSessionCleanTimer", true);
private final List trackClients = new ArrayList();
private ExecutorService reportExecutor = new ThreadPoolExecutor(4,
16, 120, TimeUnit.SECONDS, new LinkedBlockingQueue());
private ExecutorService mqExecutor = new ThreadPoolExecutor(4,
16, 120, TimeUnit.SECONDS, new LinkedBlockingQueue());
private final ConcurrentMap mqTable = new ConcurrentHashMap();
public ZbusServer(int serverPort) throws IOException {
this("0.0.0.0", serverPort);
}
public ZbusServer(String serverHost, int serverPort) throws IOException {
super(serverHost, serverPort, new ZbusServerDispachterManager());
this.ownDispachterManager = true;
ZbusServerEventAdaptor eventHandler = (ZbusServerEventAdaptor) this.serverHandler;
eventHandler.setMqTable(mqTable);
this.serverName = "ZbusServer";
this.adminHandler = new AdminHandler();
this.adminHandler.setAdminToken(this.adminToken);
this.mqSessionCleanTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Iterator> iter = mqTable.entrySet().iterator();
while(iter.hasNext()){
Entry e = iter.next();
AbstractMQ mq = e.getValue();
mq.cleanSession();
}
}
}, mqCleanDelay, mqCleanInterval);
}
private AbstractMQ findMQ(Message msg, Session sess) throws IOException{
String mqName = msg.getMq();
AbstractMQ mq = mqTable.get(mqName);
boolean ack = msg.isAck();
if(mq == null){
if(ack){
ReplyHelper.reply404(msg, sess);
}
return null;
}
if(!"".equals(mq.getAccessToken())){
if(!mq.getAccessToken().equals(msg.getToken())){
if(ack){
ReplyHelper.reply403(msg, sess);
}
return null;
}
}
return mq;
}
public void init(){
this.registerGlobalHandler(new MessageHandler() {
@Override
public void handleMessage(Message msg, Session sess) throws IOException {
String mqReply = msg.getMqReply();
if(mqReply == null || mqReply.equals("")){
msg.setMqReply(sess.id()); //reply default to self
}
msg.setHead(Message.HEADER_CLIENT, sess.getRemoteAddress());
msg.setHead(Message.HEADER_BROKER, serverAddr);
if(!Message.HEARTBEAT.equals(msg.getCommand())){
log.info("%s", msg);
}
}
});
this.registerHandler(Proto.Heartbeat, new MessageHandler() {
@Override
public void handleMessage(Message msg, Session sess) throws IOException {
//ignore;
}
});
this.registerHandler(Proto.Produce, new MessageHandler() {
@Override
public void handleMessage(Message msg, Session sess) throws IOException {
AbstractMQ mq = findMQ(msg, sess);
if(mq == null) return;
mq.produce(msg, sess);
}
});
this.registerHandler(Proto.Consume, new MessageHandler() {
@Override
public void handleMessage(Message msg, Session sess) throws IOException {
AbstractMQ mq = findMQ(msg, sess);
if(mq == null) return;
mq.consume(msg, sess);
}
});
this.registerHandler(Proto.Request, new MessageHandler() {
@Override
public void handleMessage(Message msg, Session sess) throws IOException {
AbstractMQ reqMq = findMQ(msg, sess);
if(reqMq == null) return;
String replyMqName = msg.getMqReply();
AbstractMQ replyMq = mqTable.get(replyMqName);
if(replyMq == null){
int mode = MessageMode.intValue(MessageMode.MQ, MessageMode.Temp);
replyMq = new MQ(replyMqName, mqExecutor, mode);
replyMq.setCreator(sess.getRemoteAddress());
mqTable.putIfAbsent(replyMqName, replyMq);
}
msg.setAck(false);
Message msgConsume = Message.copyWithoutBody(msg);
reqMq.produce(msg, sess);
replyMq.consume(msgConsume, sess);
}
});
//初始化管理处理回调
this.registerHandler(Proto.Admin, adminHandler);
adminHandler.registerHandler(Proto.CreateMQ, new MessageHandler() {
@Override
public void handleMessage(Message msg, Session sess) throws IOException {
String msgId= msg.getMsgId();
String mqName = msg.getHeadOrParam("mq_name");
String accessToken = msg.getHeadOrParam("access_token", "");
String type = msg.getHeadOrParam("mq_mode", "");
int mode = 0;
try{
mode = Integer.valueOf(type);
} catch (Exception e){
msg.setBody("mq_mode invalid");
ReplyHelper.reply400(msg, sess);
return;
}
if(mqName == null){
msg.setBody("Missing mq_name filed");
ReplyHelper.reply400(msg, sess);
return;
}
AbstractMQ mq = mqTable.get(mqName);
if(mq == null){
if(MessageMode.isEnabled(mode, MessageMode.PubSub)){
mq = new PubSub(mqName, mqExecutor, mode);
} else {//默认到消息队列
mq = new MQ(mqName, mqExecutor, mode);
}
mq.setAccessToken(accessToken);
mq.setCreator(sess.getRemoteAddress());
mqTable.putIfAbsent(mqName, mq);
log.info("MQ Created: %s", mq);
ReplyHelper.reply200(msgId, sess);
reportToTrackServer();
return;
}
if(MessageMode.isEnabled(mode, MessageMode.MQ) && !(mq instanceof MQ)){
msg.setBody("MsgQueue, type not matched");
ReplyHelper.reply400(msg, sess);
return;
}
if(MessageMode.isEnabled(mode, MessageMode.PubSub) && !(mq instanceof PubSub)){
msg.setBody("Pubsub, type not matched");
ReplyHelper.reply400(msg, sess);
return;
}
ReplyHelper.reply200(msgId, sess);
}
});
//WEB监控
intiMonitor();
}
private void intiMonitor() {
this.registerHandler("", new MessageHandler() {
@Override
public void handleMessage(Message msg, Session sess) throws IOException {
msg = new Message();
msg.setStatus("200");
msg.setHead("content-type","text/html");
String body = Helper.loadFileContent("zbus.htm");
msg.setBody(body);
sess.write(msg);
}
});
this.registerHandler("jquery", new MessageHandler() {
@Override
public void handleMessage(Message msg, Session sess) throws IOException {
msg = new Message();
msg.setStatus("200");
msg.setHead("content-type","application/javascript");
String body = Helper.loadFileContent("jquery.js");
msg.setBody(body);
sess.write(msg);
}
});
this.registerHandler("data", new MessageHandler() {
@Override
public void handleMessage(Message msg, Session sess) throws IOException {
msg = packServerInfo();
msg.setStatus("200");
msg.setHead("content-type", "application/json");
sess.write(msg);
}
});
}
public Map getMqInfoTable(){
Map table = new HashMap();
for(Map.Entry e : this.mqTable.entrySet()){
table.put(e.getKey(), e.getValue().getMqInfo());
}
return table;
}
private Message packServerInfo(){
Message msg = new Message();
BrokerInfo info = new BrokerInfo();
info.setBroker(serverAddr);
info.setMqTable(getMqInfoTable());
msg.setBody(info.toString());
return msg;
}
public void setupTrackServer(String trackServerAddr){
if(trackServerAddr == null) return;
trackClients.clear();
String[] serverAddrs = trackServerAddr.split("[;]");
for(String addr : serverAddrs){
addr = addr.trim();
if( addr.isEmpty() ) continue;
RemotingClient client = new RemotingClient(addr);
client.onError(new ErrorCallback() {
@Override
public void onError(IOException e, Session sess) throws IOException {
//ignore
}
});
trackClients.add(client);
}
this.trackReportTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
reportToTrackServer();
}
}, trackDelay, trackInterval);
}
private void reportToTrackServer(){
reportExecutor.submit(new Runnable() {
@Override
public void run() {
Message msg = packServerInfo();
msg.setCommand(Proto.TrackReport);
for(RemotingClient client : trackClients){
try {
client.invokeAsync(msg, null);
} catch (IOException e) {
//ignore
}
}
}
});
}
public void setAdminToken(String adminToken) {
this.adminToken = adminToken;
}
public void setTrackDelay(long trackDelay) {
this.trackDelay = trackDelay;
}
public void setTrackInterval(long trackInterval) {
this.trackInterval = trackInterval;
}
public void close(){
this.trackReportTimer.cancel();
this.mqSessionCleanTimer.cancel();
for(RemotingClient client : this.trackClients){
client.close();
}
super.close();
}
public static void main(String[] args) throws Exception{
int serverPort = Helper.option(args, "-p", 15555);
String adminToken = Helper.option(args, "-adm", "");
String trackServerAddr = Helper.option(args, "-track",
"127.0.0.1:16666;127.0.0.1:16667");
ZbusServer zbus = new ZbusServer(serverPort);
zbus.setAdminToken(adminToken);
zbus.setupTrackServer(trackServerAddr);
zbus.start();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy