📄 distributor.java
字号:
/***************************************************************************** * $Id: Distributor.java,v 1.8 2003/05/07 14:43:46 jheiss Exp $ ***************************************************************************** * Software load balancer * http://distributor.sourceforge.net/ ***************************************************************************** * Copyright 2003 Jason Heiss * * This file is part of Distributor. * * Distributor is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Distributor is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Distributor; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ***************************************************************************** */package oss.distributor;import java.io.*;import java.net.*;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.util.HashMap;import java.util.TreeMap;import java.util.List;import java.util.ArrayList;import java.util.LinkedList;import java.util.Iterator;import java.util.logging.Logger;import java.util.logging.LogManager;import java.util.logging.Level;import java.util.logging.ConsoleHandler;import java.util.logging.FileHandler;import java.text.ParseException;import java.nio.channels.SocketChannel;import java.nio.channels.ServerSocketChannel;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;public class Distributor{ private static void usage() { System.err.println( "Usage: java -jar /path/to/distributor-x.x.jar " + "/path/to/distributor.conf"); System.exit(1); } public static void main(String[] args) { // Perhaps one of the trickier aspects of programming is // Java is how to write a well behaved daemon without being // OS-specific. // // For example, here's the UNIX FAQ entry on writing a daemon: // http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 // Nearly all of that is impossible in Java // // We do what we can here and leave the rest up to an init // script (distributor comes with a sample one). try { System.in.close(); } catch (IOException e) {} Distributor d = new Distributor(args); d.balance(); } InetAddress bindAddress; int port; boolean terminateOnDisable; int connectionTimeout; int connectionFailureLimit; List targetGroups; List distributionAlgorithms; Logger logger; Object serviceTest; Controller controller; TargetSelector targetSelector; private Distributor(String args[]) { // // Prepare the Java logging system for use // // The Java logging system normally reads its default settings // from <java home>/jre/lib/logging.properties. However, we // don't want those defaults used. So we go through a bit of // hackery to feed our own defaults to the logging system. String loggingDefaultsString = new String(); // The default is XMLFormatter, which is too verbose for // most folks. The SimpleFormatter is a bit easier to read. loggingDefaultsString += "java.util.logging.FileHandler.formatter = "; loggingDefaultsString += "java.util.logging.SimpleFormatter\n"; // By default Java does not append to existing // log files, which is probably not what users expect. loggingDefaultsString += "java.util.logging.FileHandler.append = true\n"; ByteArrayInputStream loggingDefaultsStream = new ByteArrayInputStream(loggingDefaultsString.getBytes()); try { LogManager.getLogManager().readConfiguration(loggingDefaultsStream); } catch (IOException e) { System.err.println("Error setting logging defaults: " + e.getMessage()); System.exit(1); } logger = Logger.getLogger(getClass().getName()); // Let each handler pick its own level logger.setLevel(Level.ALL); // // Read the configuration file // int controlPort = 0; if (args.length < 1) { usage(); } try { DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document configDoc = db.parse(args[0]); Element rootElement = configDoc.getDocumentElement(); // Read the logging configuration first so we can use the // logger for reporting errors with the rest of the // configuration. NodeList configChildren = rootElement.getChildNodes(); for (int i=0 ; i<configChildren.getLength() ; i++) { Node configNode = configChildren.item(i); if (configNode.getNodeName().equals("log")) { Element logElement = (Element) configNode; if (logElement.getAttribute("type").equals("console")) { ConsoleHandler ch = new ConsoleHandler(); Level consoleLevel = null; try { consoleLevel = parseLogLevel(logElement.getAttribute("level")); } catch (ParseException e) { System.err.println("Unknown log level"); System.exit(1); } ch.setLevel(consoleLevel); logger.addHandler(ch); } else if (logElement.getAttribute("type").equals("file")) { FileHandler fh = new FileHandler( logElement.getAttribute("filename")); Level fileLevel = null; try { fileLevel = parseLogLevel(logElement.getAttribute("level")); } catch (ParseException e) { System.err.println("Unknown log level"); System.exit(1); } fh.setLevel(fileLevel); logger.addHandler(fh); } } } // The logger is now configured and can be used bindAddress = null; if (rootElement.getAttribute("bindaddr").equals("") || rootElement.getAttribute("bindaddr").equals("0.0.0.0")) { logger.config("Using wildcard bind address"); } else { bindAddress = InetAddress.getByName( rootElement.getAttribute("bindaddr")); } logger.config("Bind address: " + bindAddress); if (rootElement.getAttribute("port").equals("")) { logger.severe("The 'port' attribute is required"); System.exit(1); } else { port = Integer.parseInt(rootElement.getAttribute("port")); logger.config("Port: " + port); } terminateOnDisable = false; if (rootElement.getAttribute("terminate_on_disable").equals("yes")) { terminateOnDisable = true; } logger.config("Terminate on disable: " + terminateOnDisable); connectionTimeout = 2000; if (rootElement.getAttribute("connection_timeout").equals("")) { logger.warning( "Connection timeout not specified, using default"); } else { connectionTimeout = Integer.parseInt( rootElement.getAttribute("connection_timeout")); } logger.config("Connection timeout: " + connectionTimeout); connectionFailureLimit = 5; if (rootElement.getAttribute("connection_failure_limit").equals("")) { logger.warning( "Connection failure limit not specified, using default"); } else { connectionFailureLimit = Integer.parseInt( rootElement.getAttribute("connection_failure_limit")); } logger.config( "Connection failure limit: " + connectionFailureLimit); if (rootElement.getAttribute("control_port").equals("")) { logger.warning( "No control port defined, no control server will " + "be started"); } else { controlPort = Integer.parseInt( rootElement.getAttribute("control_port")); } logger.config("Control port: " + controlPort); // // Read the distribution algorithm configuration and create // the algorithm objects // distributionAlgorithms = new ArrayList(); // Read in the algorithm name -> class name mappings HashMap algoClasses = new HashMap(); for (int i=0 ; i<configChildren.getLength() ; i++) { Node configNode = configChildren.item(i); if (configNode.getNodeName().equals("algo_mapping")) { Element mapElement = (Element) configNode; String algoName = mapElement.getAttribute("name"); String algoClass = mapElement.getAttribute("class"); logger.finest( "Loaded algo mapping: " + algoName + " -> " + algoClass); algoClasses.put(algoName, algoClass); } } // Find the "algorithms" node in the XML document for (int i=0 ; i<configChildren.getLength() ; i++) { Node configNode = configChildren.item(i); if (configNode.getNodeName().equals("algorithms")) { Element algosElement = (Element) configNode; NodeList algosChildren = algosElement.getChildNodes(); for (int j=0 ; j<algosChildren.getLength() ; j++) { Node algoNode = algosChildren.item(j); if (algoNode.getNodeName().equals("algorithm")) { Element algoElement = (Element) algoNode; String algoName = algoElement.getAttribute("name"); logger.finer( "Constructing " + algoClasses.get(algoName)); Object distAlgo = constructObjectFromName( (String) algoClasses.get(algoName), algoElement); distributionAlgorithms.add(distAlgo); } } } } // Log the distribution algorithm configuration if (distributionAlgorithms.size() > 0) { logger.config("Distribution algorithms:"); Iterator iter = distributionAlgorithms.iterator(); while(iter.hasNext()) { logger.config(iter.next().toString()); } } else { logger.severe( "At least one distribution algorithm must be specified"); System.exit(1); } // // Read the target group configuration // targetGroups = new ArrayList(); // Find the "target_group" nodes in the XML document for (int i=0 ; i<configChildren.getLength() ; i++) { Node configNode = configChildren.item(i);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -