change SpiderMonitor to singleton #98

master
yihua.huang 2014-04-26 18:14:25 +08:00
parent ab4d36806e
commit 86a45a6643
3 changed files with 35 additions and 25 deletions

View File

@ -18,7 +18,7 @@ public class MonitorExample {
Spider githubSpider = Spider.create(new GithubRepoPageProcessor()) Spider githubSpider = Spider.create(new GithubRepoPageProcessor())
.addUrl("https://github.com/code4craft"); .addUrl("https://github.com/code4craft");
SpiderMonitor spiderMonitor = new SpiderMonitor(); SpiderMonitor spiderMonitor = SpiderMonitor.instance();
spiderMonitor.register(oschinaSpider); spiderMonitor.register(oschinaSpider);
spiderMonitor.register(githubSpider); spiderMonitor.register(githubSpider);
//If you want to connect it from remote, use spiderMonitor.server().jmxStart(); //If you want to connect it from remote, use spiderMonitor.server().jmxStart();

View File

@ -8,9 +8,7 @@ import us.codecraft.webmagic.SpiderListener;
import us.codecraft.webmagic.utils.Experimental; import us.codecraft.webmagic.utils.Experimental;
import us.codecraft.webmagic.utils.IPUtils; import us.codecraft.webmagic.utils.IPUtils;
import javax.management.JMException; import javax.management.*;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL; import javax.management.remote.JMXServiceURL;
@ -36,7 +34,7 @@ public class SpiderMonitor {
Server, Client, Local; Server, Client, Local;
} }
private static AtomicInteger serialNumber = new AtomicInteger(); private static SpiderMonitor INSTANCE = new SpiderMonitor();
private AtomicBoolean started = new AtomicBoolean(false); private AtomicBoolean started = new AtomicBoolean(false);
@ -48,6 +46,10 @@ public class SpiderMonitor {
private int serverPort; private int serverPort;
private MBeanServer mbeanServer;
private String jmxServerName;
private String serverHost; private String serverHost;
private Type type = Type.Local; private Type type = Type.Local;
@ -62,13 +64,16 @@ public class SpiderMonitor {
return spiderStatuses.get(0); return spiderStatuses.get(0);
} }
private SpiderMonitor() {
}
/** /**
* Register spider for monitor. * Register spider for monitor.
* *
* @param spiders * @param spiders
* @return * @return
*/ */
public SpiderMonitor register(Spider... spiders) { public synchronized SpiderMonitor register(Spider... spiders) throws JMException {
for (Spider spider : spiders) { for (Spider spider : spiders) {
MonitorSpiderListener monitorSpiderListener = new MonitorSpiderListener(); MonitorSpiderListener monitorSpiderListener = new MonitorSpiderListener();
if (spider.getSpiderListeners() == null) { if (spider.getSpiderListeners() == null) {
@ -78,7 +83,11 @@ public class SpiderMonitor {
} else { } else {
spider.getSpiderListeners().add(monitorSpiderListener); spider.getSpiderListeners().add(monitorSpiderListener);
} }
spiderStatuses.add(getSpiderStatusMBean(spider, monitorSpiderListener)); SpiderStatusMXBean spiderStatusMBean = getSpiderStatusMBean(spider, monitorSpiderListener);
if (started.get()) {
registerMBean(spiderStatusMBean);
}
spiderStatuses.add(spiderStatusMBean);
} }
return this; return this;
} }
@ -87,8 +96,8 @@ public class SpiderMonitor {
return new SpiderStatus(spider, monitorSpiderListener); return new SpiderStatus(spider, monitorSpiderListener);
} }
public static SpiderMonitor create() { public static SpiderMonitor instance() {
return new SpiderMonitor(); return INSTANCE;
} }
public class MonitorSpiderListener implements SpiderListener { public class MonitorSpiderListener implements SpiderListener {
@ -132,7 +141,7 @@ public class SpiderMonitor {
* @throws IOException * @throws IOException
* @throws JMException * @throws JMException
*/ */
public SpiderMonitor server(int port) throws IOException, JMException { public synchronized SpiderMonitor server(int port) throws IOException, JMException {
try { try {
Registry registry = LocateRegistry.createRegistry(port); Registry registry = LocateRegistry.createRegistry(port);
} catch (ExportException e) { } catch (ExportException e) {
@ -161,7 +170,7 @@ public class SpiderMonitor {
* *
* @return * @return
*/ */
public SpiderMonitor local() { public synchronized SpiderMonitor local() {
this.type = Type.Local; this.type = Type.Local;
return this; return this;
} }
@ -176,7 +185,7 @@ public class SpiderMonitor {
* @throws IOException * @throws IOException
* @throws JMException * @throws JMException
*/ */
public SpiderMonitor client(String serverHost, int serverPort) throws IOException, JMException { public synchronized SpiderMonitor client(String serverHost, int serverPort) throws IOException, JMException {
type = Type.Client; type = Type.Client;
this.serverHost = serverHost; this.serverHost = serverHost;
this.serverPort = serverPort; this.serverPort = serverPort;
@ -194,38 +203,39 @@ public class SpiderMonitor {
return client(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT); return client(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT);
} }
public SpiderMonitor jmxStart() throws IOException, JMException { public synchronized SpiderMonitor jmxStart() throws IOException, JMException {
return jmxStart("localhost", DEFAULT_SERVER_PORT);
}
public SpiderMonitor jmxStart(String jndiServer, int rmiPort) throws IOException, JMException {
if (!started.compareAndSet(false, true)) { if (!started.compareAndSet(false, true)) {
logger.error("Monitor has already started!"); logger.error("Monitor has already started!");
return this; return this;
} }
String jmxServerName = "WebMagic-" + IPUtils.getFirstNoLoopbackIPAddresses() + "-" + serialNumber.incrementAndGet(); jmxServerName = "WebMagic-" + IPUtils.getFirstNoLoopbackIPAddresses();
// start JNDI // start JNDI
MBeanServer localServer = ManagementFactory.getPlatformMBeanServer(); mbeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName objName; ObjectName objName;
if (type != Type.Local) { if (type != Type.Local) {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + jndiServer + ":" + rmiPort + "/" + jmxServerName); JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + serverHost + ":" + serverPort + "/" + jmxServerName);
System.out.println("JMXServiceURL: " + url.toString()); System.out.println("JMXServiceURL: " + url.toString());
System.out.println("Please replace localhost of your ip if you want to connect it in remote server."); System.out.println("Please replace localhost of your ip if you want to connect it in remote server.");
JMXConnectorServer jmxConnServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, localServer); JMXConnectorServer jmxConnServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer);
jmxConnServer.start(); jmxConnServer.start();
objName = new ObjectName(jmxServerName + ":name=WebMagicMonitor"); objName = new ObjectName(jmxServerName + ":name=WebMagicMonitor");
localServer.registerMBean(jmxConnServer, objName); mbeanServer.registerMBean(jmxConnServer, objName);
} }
for (SpiderStatusMXBean spiderStatus : spiderStatuses) { for (SpiderStatusMXBean spiderStatus : spiderStatuses) {
objName = new ObjectName(jmxServerName + ":name=" + spiderStatus.getName()); registerMBean(spiderStatus);
localServer.registerMBean(spiderStatus, objName);
} }
return this; return this;
} }
protected void registerMBean(SpiderStatusMXBean spiderStatus) throws MalformedObjectNameException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
ObjectName objName;
objName = new ObjectName(jmxServerName + ":name=" + spiderStatus.getName());
mbeanServer.registerMBean(spiderStatus, objName);
}
} }

View File

@ -39,7 +39,7 @@ public class Kr36NewsModel {
} }
}, Kr36NewsModel.class).thread(20); }, Kr36NewsModel.class).thread(20);
thread.start(); thread.start();
SpiderMonitor spiderMonitor = SpiderMonitor.create(); SpiderMonitor spiderMonitor = SpiderMonitor.instance();
spiderMonitor.server().register(thread).jmxStart(); spiderMonitor.server().register(thread).jmxStart();
} }