User: tpeuss Date: 03/02/02 05:47:31 Modified: varia/src/main/org/jboss/web/loadbalancer/scheduler RoundRobinScheduler.java Scheduler.java TargetNode.java Added: varia/src/main/org/jboss/web/loadbalancer/scheduler StandardTargetNode.java TargetNodeStateChangedNotification.java Removed: varia/src/main/org/jboss/web/loadbalancer/scheduler WeightedTargetNode.java Log: o Added some MBeans (TargetNodes are now MBeans that can be managed) o Prepared the Scheduler/Invoker for failover management o Changed the config file to reflect the new MBean structure Revision Changes Path 1.2 +2 -12 contrib/varia/src/main/org/jboss/web/loadbalancer/scheduler/RoundRobinScheduler.java Index: RoundRobinScheduler.java =================================================================== RCS file: /cvsroot/jboss/contrib/varia/src/main/org/jboss/web/loadbalancer/scheduler/RoundRobinScheduler.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- RoundRobinScheduler.java 28 Jan 2003 20:18:31 -0000 1.1 +++ RoundRobinScheduler.java 2 Feb 2003 13:47:31 -0000 1.2 @@ -14,28 +14,18 @@ * A scheduler that schedules the requests in a * round-robin fashion. * @author Thomas Peuss <jb...@pe...> - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ public class RoundRobinScheduler extends Scheduler { protected int nextNode=0; - protected void schedule(Request request) throws NoSchedulableNodeAvailableException, IOException + protected void choose(Request request) throws NoSchedulableNodeAvailableException, IOException { TargetNode target=null; if(targetNodeList.size()==0) { throw new NoSchedulableNodeAvailableException(); - } - - if(request.isStickySession()) { - parseRequestHeader(request); - String stickyNode=findStickyNode(request); - if(stickyNode!=null) { - request.setTargetNode(findTargetNodeByName(stickyNode)); - log.debug("Client is sticky on node "+stickyNode); - return; - } } synchronized (targetNodeList) { 1.2 +51 -8 contrib/varia/src/main/org/jboss/web/loadbalancer/scheduler/Scheduler.java Index: Scheduler.java =================================================================== RCS file: /cvsroot/jboss/contrib/varia/src/main/org/jboss/web/loadbalancer/scheduler/Scheduler.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Scheduler.java 28 Jan 2003 20:18:32 -0000 1.1 +++ Scheduler.java 2 Feb 2003 13:47:31 -0000 1.2 @@ -12,9 +12,13 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.StringTokenizer; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; import javax.management.Notification; import javax.management.NotificationListener; +import javax.management.ObjectName; import org.jboss.logging.Logger; +import org.jboss.util.jmx.MBeanProxy; import org.jboss.web.loadbalancer.core.Request; import org.jboss.web.loadbalancer.core.RequestHeader; import org.jboss.web.loadbalancer.core.RequestHeaderElement; @@ -25,13 +29,14 @@ import org.jboss.web.loadbalancer.util.Util; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import org.w3c.dom.Text; import java.io.OutputStreamWriter; import org.jboss.web.loadbalancer.util.Constants; /** * Base class for schedulers. * @author Thomas Peuss <jb...@pe...> - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ public abstract class Scheduler implements NotificationListener @@ -42,8 +47,9 @@ protected ArrayList targetNodeList; protected Logger log; protected static final String CR_LF = "\r\n"; + protected MBeanServer server; - protected abstract void schedule(Request request) throws NoSchedulableNodeAvailableException, IOException; + protected abstract void choose(Request request) throws NoSchedulableNodeAvailableException, IOException; public void handleNotification(Notification notification, java.lang.Object handback) { @@ -59,7 +65,7 @@ while (!invokationDone) { schedule(request); - log.debug("Scheduling request on node " + request.getTargetNode().name); + log.debug("Scheduling request on node " + request.getTargetNode().getName()); invokationDone = invoker.invoke(request); } @@ -86,6 +92,14 @@ return; } + if (notification instanceof TargetNodeStateChangedNotification) { + TargetNodeStateChangedNotification changeNotification = (TargetNodeStateChangedNotification) notification; + + log.debug(changeNotification.getSource()); + + return; + } + log.debug("Unhandled Notification: " + notification.toString()); } @@ -107,6 +121,8 @@ protected void parseConfig() throws Exception { + server=(MBeanServer)MBeanServerFactory.findMBeanServer(null).get(0); + stickySession = Boolean.valueOf(config.getAttribute("stickySession")).booleanValue(); Element element = (Element) config.getElementsByTagName("invoker").item(0); invoker = (Invoker) Thread.currentThread().getContextClassLoader().loadClass(element.getAttribute("className")).newInstance(); @@ -116,15 +132,42 @@ NodeList nodes = config.getElementsByTagName("node"); for (int i = 0; i < nodes.getLength(); ++i) { element = (Element) nodes.item(i); - TargetNode targetNode = new TargetNode(); - targetNode.setName(element.getAttribute("name")); - targetNode.setAddress(InetAddress.getByName(element.getAttribute("host"))); - targetNode.setPort(Integer.parseInt(element.getAttribute("port"))); + String name=((Text)element.getFirstChild()).getData(); + ObjectName objectName=new ObjectName(name); + TargetNode targetNode=(TargetNode)MBeanProxy.create(TargetNode.class,objectName); + + server.addNotificationListener(objectName, this, null, null); targetNodeList.add(targetNode); } } + protected void schedule(Request request) throws NoSchedulableNodeAvailableException, IOException + { + TargetNode target=null; + + if(targetNodeList.size()==0) { + throw new NoSchedulableNodeAvailableException(); + } + + if(request.isStickySession()) { + parseRequestHeader(request); + String stickyNode=findStickyNode(request); + if(stickyNode!=null) { + request.setTargetNode(findTargetNodeByName(stickyNode)); + log.debug("Client is sticky on node "+stickyNode); + return; + } else { + // Sticky node is down --> choose another node + choose(request); + } + } + + // Not sticky --> so we must choose a node + choose(request); + } + + protected void parseRequestHeader(Request request) throws IOException { InputStream stream = request.getClientInputStream(); @@ -221,4 +264,4 @@ writer.write(Constants.ERROR_MESSAGE_503); writer.flush(); } -} \ No newline at end of file +} 1.2 +59 -51 contrib/varia/src/main/org/jboss/web/loadbalancer/scheduler/TargetNode.java Index: TargetNode.java =================================================================== RCS file: /cvsroot/jboss/contrib/varia/src/main/org/jboss/web/loadbalancer/scheduler/TargetNode.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- TargetNode.java 28 Jan 2003 20:18:34 -0000 1.1 +++ TargetNode.java 2 Feb 2003 13:47:31 -0000 1.2 @@ -6,60 +6,68 @@ */ package org.jboss.web.loadbalancer.scheduler; -import java.net.InetAddress; +import javax.management.NotificationBroadcaster; /** * A class that holds the information and state of the target nodes. * @author Thomas Peuss <jb...@pe...> - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ + * @jmx:mbean name="jboss:service=LoadBalancer, type=TargetNode" */ -public class TargetNode +public interface TargetNode extends TargetNodeMBean, NotificationBroadcaster { - public static final int NODE_ACCEPTING_NEW_SESSIONS = 0; - public static final int NODE_ACCEPTING_OLD_SESSIONS = 1; - public static final int NODE_DEACTIVATED = 2; - protected int state = NODE_ACCEPTING_NEW_SESSIONS; - protected String name; - protected InetAddress address; - protected int port; - - public InetAddress getAddress() - { - return address; - } - - public String getName() - { - return name; - } - - public int getPort() - { - return port; - } - - public int getState() - { - return state; - } - - public void setAddress(InetAddress address) - { - this.address = address; - } - - public void setName(String name) - { - this.name = name; - } - - public void setPort(int port) - { - this.port = port; - } - - public void setState(int state) - { - this.state = state; - } -} \ No newline at end of file + /** + * @jmx:managed-attribute + * */ + public String getAddress(); + + /** + * @jmx:managed-attribute + * */ + public String getName(); + + /** + * @jmx:managed-attribute + * */ + public int getPort(); + + /** + * @jmx:managed-attribute + * */ + public int getState(); + + /** + * @jmx:managed-attribute + * */ + public void setAddress(String address); + + /** + * @jmx:managed-attribute + * */ + public void setName(String name); + + /** + * @jmx:managed-attribute + * */ + public void setPort(int port); + + /** + * @jmx:managed-attribute + * */ + public void setState(int state); + + /** + * @jmx:managed-attribute + * */ + public String getStateString(); + + /** + * @jmx:managed-operation + * */ + public void markAsUp(); + + /** + * @jmx:managed-operation + * */ + public void markAsDown(); +} 1.1 contrib/varia/src/main/org/jboss/web/loadbalancer/scheduler/StandardTargetNode.java Index: StandardTargetNode.java =================================================================== /* * JBoss, the OpenSource WebOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.jboss.web.loadbalancer.scheduler; import java.net.InetAddress; import java.net.UnknownHostException; import javax.management.NotificationBroadcasterSupport; /** * A class that holds the information and state of the target nodes. * @author Thomas Peuss <jb...@pe...> * @version $Revision: 1.1 $ * @jmx:mbean name="jboss:service=LoadBalancer, type=StandardTargetNode" */ public class StandardTargetNode extends NotificationBroadcasterSupport implements TargetNode, StandardTargetNodeMBean { public static final int NODE_UP=0; public static final int NODE_DOWN=1; protected static final String[] STATE_STRINGS={"UP","DOWN"}; protected int state = NODE_UP; protected String name; protected String address; protected int port; /** * @jmx:managed-attribute * */ public String getAddress() { return address; } /** * @jmx:managed-attribute * */ public String getName() { return name; } /** * @jmx:managed-attribute * */ public int getPort() { return port; } /** * @jmx:managed-attribute * */ public int getState() { return state; } /** * @jmx:managed-attribute * */ public void setAddress(String address) { this.address = address; } /** * @jmx:managed-attribute * */ public void setName(String name) { this.name = name; } /** * @jmx:managed-attribute * */ public void setPort(int port) { this.port = port; } /** * @jmx:managed-attribute * */ public void setState(int state) { this.state = state; } /** * @jmx:managed-attribute * */ public String getStateString() { return this.STATE_STRINGS[this.state]; } /** * @jmx:managed-operation * */ public void markAsUp() { if (this.state==NODE_DOWN) { this.state=NODE_UP; sendNodeStateChangedNotification(); } } /** * @jmx:managed-operation * */ public void markAsDown() { if (this.state==NODE_UP) { this.state=NODE_DOWN; sendNodeStateChangedNotification(); } } protected void sendNodeStateChangedNotification() { this.sendNotification(new TargetNodeStateChangedNotification(this)); } } 1.1 contrib/varia/src/main/org/jboss/web/loadbalancer/scheduler/TargetNodeStateChangedNotification.java Index: TargetNodeStateChangedNotification.java =================================================================== /* * JBoss, the OpenSource WebOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.jboss.web.loadbalancer.scheduler; import javax.management.Notification; /** * This notification is emitted when the state of a TargetNode changes. * @author Thomas Peuss <jb...@pe...> * @version $Revision: 1.1 $ */ public class TargetNodeStateChangedNotification extends Notification { private static final String NOTIFICATION_TYPE = TargetNodeStateChangedNotification.class.getName(); private static int sequenceNumber; public TargetNodeStateChangedNotification(Object source) { super(NOTIFICATION_TYPE, source, sequenceNumber++); } } |