diff --git a/webmagic-extension/src/main/java/us/codecraft/webmagic/example/MonitorExample.java b/webmagic-extension/src/main/java/us/codecraft/webmagic/example/MonitorExample.java index 0763fddf..60f62b0a 100644 --- a/webmagic-extension/src/main/java/us/codecraft/webmagic/example/MonitorExample.java +++ b/webmagic-extension/src/main/java/us/codecraft/webmagic/example/MonitorExample.java @@ -18,7 +18,7 @@ public class MonitorExample { Spider githubSpider = Spider.create(new GithubRepoPageProcessor()) .addUrl("https://github.com/code4craft"); - SpiderMonitor spiderMonitor = new SpiderMonitor(); + SpiderMonitor spiderMonitor = SpiderMonitor.instance(); spiderMonitor.register(oschinaSpider); spiderMonitor.register(githubSpider); //If you want to connect it from remote, use spiderMonitor.server().jmxStart(); diff --git a/webmagic-extension/src/main/java/us/codecraft/webmagic/monitor/SpiderMonitor.java b/webmagic-extension/src/main/java/us/codecraft/webmagic/monitor/SpiderMonitor.java index b9a9d207..10ca508c 100644 --- a/webmagic-extension/src/main/java/us/codecraft/webmagic/monitor/SpiderMonitor.java +++ b/webmagic-extension/src/main/java/us/codecraft/webmagic/monitor/SpiderMonitor.java @@ -8,9 +8,7 @@ import us.codecraft.webmagic.SpiderListener; import us.codecraft.webmagic.utils.Experimental; import us.codecraft.webmagic.utils.IPUtils; -import javax.management.JMException; -import javax.management.MBeanServer; -import javax.management.ObjectName; +import javax.management.*; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; @@ -36,7 +34,7 @@ public class SpiderMonitor { Server, Client, Local; } - private static AtomicInteger serialNumber = new AtomicInteger(); + private static SpiderMonitor INSTANCE = new SpiderMonitor(); private AtomicBoolean started = new AtomicBoolean(false); @@ -48,6 +46,10 @@ public class SpiderMonitor { private int serverPort; + private MBeanServer mbeanServer; + + private String jmxServerName; + private String serverHost; private Type type = Type.Local; @@ -62,13 +64,16 @@ public class SpiderMonitor { return spiderStatuses.get(0); } + private SpiderMonitor() { + } + /** * Register spider for monitor. * * @param spiders * @return */ - public SpiderMonitor register(Spider... spiders) { + public synchronized SpiderMonitor register(Spider... spiders) throws JMException { for (Spider spider : spiders) { MonitorSpiderListener monitorSpiderListener = new MonitorSpiderListener(); if (spider.getSpiderListeners() == null) { @@ -78,7 +83,11 @@ public class SpiderMonitor { } else { spider.getSpiderListeners().add(monitorSpiderListener); } - spiderStatuses.add(getSpiderStatusMBean(spider, monitorSpiderListener)); + SpiderStatusMXBean spiderStatusMBean = getSpiderStatusMBean(spider, monitorSpiderListener); + if (started.get()) { + registerMBean(spiderStatusMBean); + } + spiderStatuses.add(spiderStatusMBean); } return this; } @@ -87,8 +96,8 @@ public class SpiderMonitor { return new SpiderStatus(spider, monitorSpiderListener); } - public static SpiderMonitor create() { - return new SpiderMonitor(); + public static SpiderMonitor instance() { + return INSTANCE; } public class MonitorSpiderListener implements SpiderListener { @@ -132,7 +141,7 @@ public class SpiderMonitor { * @throws IOException * @throws JMException */ - public SpiderMonitor server(int port) throws IOException, JMException { + public synchronized SpiderMonitor server(int port) throws IOException, JMException { try { Registry registry = LocateRegistry.createRegistry(port); } catch (ExportException e) { @@ -161,7 +170,7 @@ public class SpiderMonitor { * * @return */ - public SpiderMonitor local() { + public synchronized SpiderMonitor local() { this.type = Type.Local; return this; } @@ -176,7 +185,7 @@ public class SpiderMonitor { * @throws IOException * @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; this.serverHost = serverHost; this.serverPort = serverPort; @@ -194,38 +203,39 @@ public class SpiderMonitor { return client(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT); } - public SpiderMonitor jmxStart() throws IOException, JMException { - return jmxStart("localhost", DEFAULT_SERVER_PORT); - } - - public SpiderMonitor jmxStart(String jndiServer, int rmiPort) throws IOException, JMException { + public synchronized SpiderMonitor jmxStart() throws IOException, JMException { if (!started.compareAndSet(false, true)) { logger.error("Monitor has already started!"); return this; } - String jmxServerName = "WebMagic-" + IPUtils.getFirstNoLoopbackIPAddresses() + "-" + serialNumber.incrementAndGet(); + jmxServerName = "WebMagic-" + IPUtils.getFirstNoLoopbackIPAddresses(); // start JNDI - MBeanServer localServer = ManagementFactory.getPlatformMBeanServer(); + mbeanServer = ManagementFactory.getPlatformMBeanServer(); ObjectName objName; 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("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(); objName = new ObjectName(jmxServerName + ":name=WebMagicMonitor"); - localServer.registerMBean(jmxConnServer, objName); + mbeanServer.registerMBean(jmxConnServer, objName); } for (SpiderStatusMXBean spiderStatus : spiderStatuses) { - objName = new ObjectName(jmxServerName + ":name=" + spiderStatus.getName()); - localServer.registerMBean(spiderStatus, objName); + registerMBean(spiderStatus); } 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); + } + } diff --git a/webmagic-samples/src/main/java/us/codecraft/webmagic/model/samples/Kr36NewsModel.java b/webmagic-samples/src/main/java/us/codecraft/webmagic/model/samples/Kr36NewsModel.java index 3dcc5f9c..6208f685 100644 --- a/webmagic-samples/src/main/java/us/codecraft/webmagic/model/samples/Kr36NewsModel.java +++ b/webmagic-samples/src/main/java/us/codecraft/webmagic/model/samples/Kr36NewsModel.java @@ -39,7 +39,7 @@ public class Kr36NewsModel { } }, Kr36NewsModel.class).thread(20); thread.start(); - SpiderMonitor spiderMonitor = SpiderMonitor.create(); + SpiderMonitor spiderMonitor = SpiderMonitor.instance(); spiderMonitor.server().register(thread).jmxStart(); }