⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpcookiedistributionalgorithm.java.temp

📁 简单的分布式算法
💻 TEMP
字号:
/* ***************************************************************************** * $Id$ ***************************************************************************** * A distribution algorithm which ensures clients speak to a * consistent server.  Similar in effect to a hash selection algorithm * but implemented by feeding the client an HTTP cookie which records * the target that the client is connected to.  Obviously only works for * HTTP servers, but provides a better distribution than a standard hash * algorithm because many clients behind a web proxy or NAT router don't * all get stuck on the same server. ***************************************************************************** * 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.util.HashMap;import java.nio.ByteBuffer;import java.nio.channels.SocketChannel;class HTTPCookieDistributionAlgorithm	extends DistributionAlgorithm implements Runnable{	Map clientHeaderBuffers;	int hashTimeout;	Map ipMap;	Map lastConnectTime;	static final int DEFAULT_HEADER_BUFFER_SIZE = 4096;	int maxHeaderSize;	Thread thread;	/*	 * Because the distribution algorithms are instantiated via	 * Class.forName(), they must have public constructors.	 */	public HTTPCookieDistributionAlgorithm(		Distributor distributor, Element configElement)	{		super(distributor);		/*		 * hashTimeout defines how long we keep a record of the last		 * target a given client was sent too.  Set it too long and		 * you'll use a lot of memory on a busy server.  But it needs to		 * be long enough that client sessions get sent to the right		 * server.  The right value is highly dependant on your		 * environment.  Reasonable values probably range anywhere from		 * one hour to a couple of days.		 */		hashTimeout = 1800000;		try		{			hashTimeout =				Integer.parseInt(configElement.getAttribute("hash_timeout"));		}		catch (NumberFormatException e)		{			logger.warning("Invalid hash timeout, using default:  " +				e.getMessage());		}		logger.config("Hash timeout:  " + hashTimeout);		// ***		// Need to read this from configElement		maxHeaderSize = 32768;		clientHeaderBuffers = new HashMap();		ipMap = new HashMap();		lastConnectTime = new HashMap();		thread = new Thread(this, getClass().getName());	}	/* 	* This allows Distributor to delay some of our initialization until 	* it is ready.  There are some things we need that Distributor may 	* not have ready at the point at which it constructs us, so we wait 	* and retrieve them at the start of run(). 	*/	public void startThread()	{		thread.start();	}	// On a new connection we need to look for a cookie in the HTTP	// headers.  If there is one we prefer that target, just like the	// hash algorithm (i.e. prefer that target and fail back to round	// robin if the preferred target is down).  If there isn't a cookie,	// or if the preferred target is unavailable and we connect the	// client to a new target, we set a cookie in the return traffic.	// http://wp.netscape.com/newsref/std/cookie_spec.html	//	// Possible cookie fields and defaults:	// expires		User's session	// domain		Server hostname	// path			Document path	// secure		No	//	// We need a cookie as follows	// Set-Cookie: DistributorTarget=<target> path=/	// The HTTP RFC (2616) says headers are US-ASCII, so we need to	// specify that as the charset for Java to use when decoding strings	// from the input stream.	public void tryToConnect(SocketChannel client)	{		clientHeaderBuffers.put(			client,			ByteBuffer.allocate(DEFAULT_HEADER_BUFFER_SIZE));		// ***		// Register with selector	}	public void run()	{		List failed;		Iterator iter;		SocketChannel client;		// Finish any initialization that was delayed until Distributor		// was ready.		finishInitialization();		while(true)		{			// ***			select			{				foreach sockchan				{					while (readMore)					{						ByteBuffer buf = clientHeaderBuffers.get(sockchan);						// Bump the buffer's limit by one, thus allowing						// read() to read one byte						buf.limit(buf.position() + 1);						r = sockchan.read(buf);						if (r == 1)						{							// Ignore leading CRLF's per							// section 4.1 of RFC 2616							// ***							if (buf.position() == 1)							{							}							//							// Look for end of headers							//							// Grab the last 4 bytes of the buffer							byte[] lastBit = new byte[4];							// Back the buffer position up by 3 so we							// get 4 bytes							buf.position(buf.position() - 3);							buf.get(lastBit);							// Restore the buffer position							buf.position(buf.position() + 3);							// The end of the headers will be signified							// by CRLFCRLF, i.e. a start/header line							// followed by a blank line.							if (lastBit[0] == '\r' &&								lastBit[1] == '\n' &&								lastBit[2] == '\r' &&								lastBit[3] == '\n')							{							}						}						else if (r == 0)						{							// No more data can be read for now, but							// we still haven't seen the end of the							// headers.  Ratchet the buffer's limit							// back by one so it's ready for the next							// time around.							buf.limit(buf.position());						}						else if (r == -1)						{							// EOF encountered but end of headers not							// found.  This connection is bogus, discard							// it.						}					}				}			}			// Give any failed connections back to TargetSelector			failed = checkForFailedConnections();			iter = failed.iterator();			while(iter.hasNext())			{				client = (SocketChannel) iter.next();				targetSelector.addUnconnectedClient(client);			}			// Purge old entries from ipMap			synchronized(lastConnectTime)			{				iter = lastConnectTime.entrySet().iterator();				while(iter.hasNext())				{					Entry timeEntry = (Entry) iter.next();					addr = (InetAddress) timeEntry.getKey();					lastConnect = ((Long) timeEntry.getValue()).longValue();					if (lastConnect + hashTimeout < System.currentTimeMillis())					{						synchronized(ipMap)						{							ipMap.remove(addr);						}						lastConnectTime.remove(addr);					}				}			}			// ***			logger.fine("connections.size():  " + connections.size());			logger.fine("connectStartTime.size():  " + connectStartTime.size());			logger.fine("ipMap.size():  " + ipMap.size());			logger.fine("lastConnectTime.size():  " + lastConnectTime.size());		}	}	public void connectionNotify(Connection conn)	{		// Store a mapping for this client's IP address so that we can		// inject the appropriate cookie later		synchronized(ipMap)		{			logger.finer(				"Storing mapping from " +				conn.getClient().socket().getInetAddress() +				" to " + conn.getTarget());			ipMap.put(				conn.getClient().socket().getInetAddress(),				conn.getTarget());		}		// And record the time to allow us to dump old entries from the		// maps after a while (see the run method).		synchronized(lastConnectTime)		{			lastConnectTime.put(				conn.getClient().socket().getInetAddress(),				new Long(System.currentTimeMillis()));		}	}	// If we have any data queued up from the cookie search, prepend it	public ByteBuffer reviewClientToServerData(		SocketChannel client, SocketChannel server, ByteBuffer buffer)	{		// ***	}	// Inject a Set-Cookie header if appropriate	public ByteBuffer reviewServerToClientData(		SocketChannel server, SocketChannel client, ByteBuffer buffer)	{		// ***	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -