serverconnector.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,195 行 · 第 1/2 页

JAVA
1,195
字号
/* * 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.management.server.ServerConnectorMXBean;import com.caucho.util.L10N;import com.caucho.util.Alarm;import com.caucho.vfs.*;import com.caucho.server.resin.*;import javax.management.ObjectName;import java.io.IOException;import java.util.*;import java.util.logging.Level;import java.util.logging.Logger;/** * Defines a member of the cluster. * * A {@link ClusterClient} obtained with {@link #getClient} is used to actually * communicate with this ClusterServer when it is active in another instance of * Resin . */public class ServerConnector{  private static final Logger log    = Logger.getLogger(ServerConnector.class.getName());  private static final L10N L = new L10N(ServerConnector.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 ClusterServer _server;  private ClusterPort _port;  private ObjectName _objectName;  private Cluster _cluster;  private Path _tcpPath;  private ServerConnectorAdmin _admin;  private String _debugId;  private int _maxConnections = Integer.MAX_VALUE / 2;    private ClusterStream []_idle = new ClusterStream[64];  private volatile int _idleHead;  private volatile int _idleTail;  private int _idleSize = 16;  private int _streamCount;  private long _warmupTime;  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;  private ServerPool _serverPool;  public ServerConnector(ClusterServer server)  {    _server = server;    _cluster = _server.getCluster();    _port = server.getClusterPort();  }  /**   * Gets the owning cluster.   */  public Cluster getCluster()  {    return _cluster;  }  /**   * Returns the object name.   */  public ObjectName getObjectName()  {    return _objectName;  }  /**   * Returns the admin.   */  public ServerConnectorMXBean getAdmin()  {    return _admin;  }  /**   * Gets the cluster port.   */  public ClusterPort getClusterPort()  {    return _port;  }  /**   * Returns the user-readable id of the target server.   */  public String getId()  {    return _server.getId();  }  public ClusterServer getServer()  {    return _server;  }  /**   * Returns the index of this connection in the connection group.   */  public int getIndex()  {    return _server.getIndex();  }  /**   * Returns the hostname of the target server.   */  public String getAddress()  {    return _port.getAddress();  }  /**   * Gets the port of the target server.   */  public int getPort()  {    return _port.getPort();  }  /**   * Returns true for a dynamic server   */  public boolean isDynamicServer()  {    return _server.isDynamic();  }  /**   * Returns the time in milliseconds for the slow start throttling.   */  public long getLoadBalanceWarmupTime()  {    return _server.getLoadBalanceWarmupTime();  }  /**   * Returns the socket timeout when connecting to the   * target server.   */  public long getLoadBalanceConnectTimeout()  {    return _server.getLoadBalanceConnectTimeout();  }  /**   * Returns the socket timeout when reading from the   * target server.   */  public long getLoadBalanceSocketTimeout()  {    return _server.getLoadBalanceSocketTimeout();  }  /**   * Returns how long the connection can be cached in the free pool.   */  public long getLoadBalanceIdleTime()  {    return _server.getLoadBalanceIdleTime();  }  /**   * Returns how long the connection will be treated as dead.   */  public long getLoadBalanceRecoverTime()  {    return _server.getLoadBalanceRecoverTime();  }  /**   * Returns the load balance weight.   */  public int getLoadBalanceWeight()  {    return _server.getLoadBalanceWeight();  }  /**   * Initialize   */  public void init()    throws Exception  {    _warmupTime = _server.getLoadBalanceWarmupTime();    _warmupChunkTime = _warmupTime / WARMUP_MAX;    if (_warmupChunkTime <= 0)      _warmupChunkTime = 1;          _failRecoverTime = _server.getLoadBalanceRecoverTime();    _failChunkTime = _failRecoverTime / 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(getLoadBalanceConnectTimeout()));    if (_port.isSSL())      _tcpPath = Vfs.lookup("tcps://" + address + ":" + getPort(), attr);    else      _tcpPath = Vfs.lookup("tcp://" + address + ":" + getPort(), attr);    _admin = new ServerConnectorAdmin(this);    Thread thread = Thread.currentThread();    ClassLoader oldLoader = thread.getContextClassLoader();    try {      Resin resin = Resin.getLocal();      if (resin != null)	thread.setContextClassLoader(resin.getClassLoader());            String name = getId();      if (name == null)        name = "";    } catch (Exception e) {      log.log(Level.FINER, e.toString(), e);    } finally {      thread.setContextClassLoader(oldLoader);    }  }  public void register()  {    _admin.register();  }  /**   * 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 the debug id.   */  public String getDebugId()  {    if (_debugId == null) {      String selfId = null;      Cluster localCluster = Cluster.getLocal();      if (localCluster != null)	selfId = localCluster.getId();      if (selfId == null || selfId.equals(""))	selfId = "default";      String targetId = _server.getId();      if (targetId == null || targetId.equals(""))	targetId = String.valueOf(_server.getIndex());      _debugId = selfId + "->" + targetId;    }        return _debugId;  }  /**   * 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)

⌨️ 快捷键说明

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