serverpool.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,285 行 · 第 1/2 页
JAVA
1,285 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source 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. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.server.cluster;import com.caucho.config.ConfigException;import com.caucho.management.server.ServerConnectorMXBean;import com.caucho.util.L10N;import com.caucho.util.Alarm;import com.caucho.util.QDate;import com.caucho.vfs.*;import com.caucho.server.resin.*;import javax.management.ObjectName;import java.io.IOException;import java.io.Serializable;import java.util.*;import java.util.logging.Level;import java.util.logging.Logger;/** * A pool of connections to a Resin server. */public class ServerPool{ private static final Logger log = Logger.getLogger(ServerPool.class.getName()); private static final L10N L = new L10N(ServerPool.class); private static final int ST_NEW = 0; private static final int ST_STANDBY = 1; private static final int ST_SESSION_ONLY = 2; // the following 5 are the active states private static final int ST_STARTING = 3; private static final int ST_WARMUP = 4; private static final int ST_BUSY = 5; private static final int ST_FAIL = 6; private static final int ST_ACTIVE = 7; private static final int ST_CLOSED = 8; // number of chunks in the throttling private static final int WARMUP_MAX = 16; private static final int WARMUP_MIN = -16; private static final int []WARMUP_CONNECTION_MAX = new int[] { 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 8, 8, 16, 32, 64, 128 }; private final String _serverId; private final String _targetId; private final String _address; private final int _port; private final boolean _isSecure; private String _debugId; private Path _tcpPath; private int _maxConnections = Integer.MAX_VALUE / 2; private long _loadBalanceConnectTimeout = 5000; private long _loadBalanceSocketTimeout = 30000; private long _loadBalanceIdleTime = 10000; private long _loadBalanceRecoverTime = 15000; private long _loadBalanceWarmupTime = 60000; private int _loadBalanceWeight = 100; private ClusterStream []_idle = new ClusterStream[64]; private volatile int _idleHead; private volatile int _idleTail; private int _idleSize = 16; private int _streamCount; private long _warmupChunkTime; private long _failRecoverTime; private long _failChunkTime; private volatile int _state = ST_NEW; // current connection count private volatile int _activeCount; private volatile int _startingCount; private volatile int _loadBalanceAllocateCount; // numeric value representing the throttle state private volatile int _warmupState; // load management data private volatile long _lastFailConnectTime; private volatile long _dynamicFailRecoverTime = 1000L; private volatile long _lastFailTime; private volatile long _lastBusyTime; private volatile long _failTime; private volatile long _firstSuccessTime; private volatile long _lastSuccessTime; private volatile long _prevSuccessTime; private volatile double _latencyFactor; // statistics private volatile long _keepaliveCountTotal; private volatile long _connectCountTotal; private volatile long _failCountTotal; private volatile long _busyCountTotal; private volatile double _cpuLoadAvg; private volatile long _cpuSetTime; public ServerPool(String serverId, String targetId, String address, int port, boolean isSecure) { _serverId = serverId; _targetId = targetId; _debugId = _serverId + "->" + _targetId; _address = address; _port = port; _isSecure = isSecure; } public ServerPool(String serverId, ClusterServer server) { this(serverId, server.getId(), server.getClusterPort().getAddress(), server.getClusterPort().getPort(), server.getClusterPort().isSSL()); _loadBalanceConnectTimeout = server.getLoadBalanceConnectTimeout(); _loadBalanceSocketTimeout = server.getLoadBalanceSocketTimeout(); _loadBalanceIdleTime = server.getLoadBalanceIdleTime(); _loadBalanceRecoverTime = server.getLoadBalanceRecoverTime(); _loadBalanceWarmupTime = server.getLoadBalanceWarmupTime(); _loadBalanceWeight = server.getLoadBalanceWeight(); } /** * Returns the user-readable id of the target server. */ public String getId() { return _targetId; } /** * Returns the debug id. */ public String getDebugId() { return _debugId; } /** * Returns the hostname of the target server. */ public String getAddress() { return _address; } /** * Gets the port of the target server. */ public int getPort() { return _port; } /** * The socket timeout when connecting to the target server. */ public long getLoadBalanceConnectTimeout() { return _loadBalanceConnectTimeout; } /** * The socket timeout when connecting to the target server. */ public void setLoadBalanceConnectTimeout(long timeout) { _loadBalanceConnectTimeout = timeout; } /** * The socket timeout when reading from the target server. */ public long getLoadBalanceSocketTimeout() { return _loadBalanceSocketTimeout; } /** * The socket timeout when reading from the target server. */ public void setLoadBalanceSocketTimeout(long timeout) { _loadBalanceSocketTimeout = timeout; } /** * How long the connection can be cached in the free pool. */ public long getLoadBalanceIdleTime() { return _loadBalanceIdleTime; } /** * How long the connection can be cached in the free pool. */ public void setLoadBalanceIdleTime(long timeout) { _loadBalanceIdleTime = timeout; } /** * Returns how long the connection will be treated as dead. */ public void setLoadBalanceRecoverTime(long timeout) { _loadBalanceRecoverTime = timeout; } /** * Returns the time in milliseconds for the slow start throttling. */ public void setLoadBalanceWarmupTime(long timeout) { _loadBalanceWarmupTime = timeout; } /** * The load balance weight. */ public int getLoadBalanceWeight() { return _loadBalanceWeight; } /** * The load balance weight. */ public void setLoadBalanceWeight(int weight) { _loadBalanceWeight = weight; } /** * Initialize */ public void init() throws Exception { _warmupChunkTime = _loadBalanceWarmupTime / WARMUP_MAX; if (_warmupChunkTime <= 0) _warmupChunkTime = 1; _failChunkTime = _loadBalanceRecoverTime / WARMUP_MAX; if (_failChunkTime <= 0) _failChunkTime = 1; _state = ST_STARTING; String address = getAddress(); if (address == null) address = "localhost"; HashMap<String,Object> attr = new HashMap<String,Object>(); attr.put("connect-timeout", new Long(_loadBalanceConnectTimeout)); if (_isSecure) _tcpPath = Vfs.lookup("tcps://" + address + ":" + _port, attr); else _tcpPath = Vfs.lookup("tcp://" + address + ":" + _port, attr); } /** * Returns the number of active connections. */ public int getActiveCount() { return _activeCount; } /** * Returns the number of idle connections. */ public int getIdleCount() { return (_idleHead - _idleTail + _idle.length) % _idle.length; } /** * Returns the number of load balance allocations */ public int getLoadBalanceAllocateCount() { return _loadBalanceAllocateCount; } /** * Allocate a connection for load balancing. */ public void allocateLoadBalance() { synchronized (this) { _loadBalanceAllocateCount++; } } /** * Free a connection for load balancing. */ public void freeLoadBalance() { synchronized (this) { _loadBalanceAllocateCount--; } } /** * Returns the total number of successful socket connections */ public long getConnectCountTotal() { return _connectCountTotal; } /** * Returns the number of times a keepalive connection has been used. */ public long getKeepaliveCountTotal() { return _keepaliveCountTotal; } /** * Returns the total number of failed connect attempts. */ public long getFailCountTotal() { return _failCountTotal; } /** * Returns the time of the last failure. */ public Date getLastFailTime() { return new Date(_lastFailTime); } /** * Returns the time of the last failure. */ public Date getLastFailConnectTime() { return new Date(_lastFailConnectTime); } /** * Returns the time of the last failure. */ public long getLastSuccessTime() { return _lastSuccessTime; } /** * Returns the latency factory */ public double getLatencyFactor() { return _latencyFactor; } /** * Returns the count of busy connections. */ public long getBusyCountTotal() { return _busyCountTotal; } /** * Returns the time of the last busy. */ public Date getLastBusyTime() { return new Date(_lastBusyTime); } /** * Sets the CPU load avg (from backend). */ public void setCpuLoadAvg(double load) { _cpuSetTime = Alarm.getCurrentTime(); _cpuLoadAvg = load; } /** * Gets the CPU load avg */ public double getCpuLoadAvg() { double avg = _cpuLoadAvg; long time = _cpuSetTime; long now = Alarm.getCurrentTime(); if (now - time < 10000L) return avg; else return avg * 10000L / (now - time); } /** * Returns true if the server is active. */ public final boolean isActive() { switch (_state) { case ST_ACTIVE: return true; case ST_STANDBY: case ST_CLOSED: return false; case ST_FAIL: return (_failTime + _failRecoverTime <= Alarm.getCurrentTime()); default: return false; } } /** * Returns true if the server is dead. */ public boolean isDead() { return ! isActive(); } /** * Enable the client */ public void enable() { start(); } /** * Disable the client */ public void disable() { stop(); } /** * Returns the lifecycle state. */ public String getState() { updateWarmup(); switch (_state) { case ST_NEW: return "init"; case ST_STANDBY: return "standby"; case ST_SESSION_ONLY: return "session-only"; case ST_STARTING: return "starting"; case ST_WARMUP: return "warmup"; case ST_BUSY: return "busy"; case ST_FAIL: return "fail"; case ST_ACTIVE: return "active"; case ST_CLOSED: return "closed"; default: return "unknown(" + _state + ")"; } } /** * Returns true if the server can open a connection. */ public boolean canOpenSoftOrRecycle() { return getIdleCount() > 0 || canOpenSoft(); } /** * Returns true if the server can open a connection. */ public boolean canOpenSoft() { int state = _state; if (state == ST_ACTIVE) return true; else if (ST_STARTING <= state && state < ST_ACTIVE) { long now = Alarm.getCurrentTime(); if (now < _lastFailConnectTime + _dynamicFailRecoverTime) { return false; } int warmupState = _warmupState; if (warmupState < 0) { return (_failTime - warmupState * _failChunkTime < now); } else if (WARMUP_MAX <= warmupState) return true; int connectionMax = WARMUP_CONNECTION_MAX[warmupState]; int idleCount = getIdleCount(); int activeCount = _activeCount + _startingCount; int totalCount = activeCount + idleCount; return totalCount < connectionMax; } else { return false; } } /** * Return true if active. */ public boolean isEnabled() { int state = _state; return ST_STARTING <= state && state <= ST_ACTIVE; } private void toActive() { synchronized (this) { if (_state < ST_CLOSED) _state = ST_ACTIVE; } } public void toBusy() { _lastBusyTime = Alarm.getCurrentTime(); _firstSuccessTime = 0; synchronized (this) { _busyCountTotal++; if (_state < ST_CLOSED) _state = ST_BUSY; } } public void toFail() { _failTime = Alarm.getCurrentTime(); _lastFailTime = _failTime; _firstSuccessTime = 0; synchronized (this) { _failCountTotal++; if (_state < ST_CLOSED) _state = ST_FAIL; } clearRecycle(); } /** * Called when the socket read/write fails. */ public void failSocket() { synchronized (this) { _failCountTotal++; long now = Alarm.getCurrentTime(); _firstSuccessTime = 0; // only degrade one per 100ms if (now - _failTime >= 100) { _warmupState--; _failTime = now; _lastFailTime = _failTime; } if (_warmupState < WARMUP_MIN) _warmupState = WARMUP_MIN; if (_state < ST_CLOSED) _state = ST_FAIL; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?