📄 ajp13connector.java
字号:
} /** * Return the maximum number of processors allowed, or <0 for unlimited. */ public int getMaxProcessors() { return (maxProcessors); } /** * Set the maximum number of processors allowed, or <0 for unlimited. * * @param maxProcessors The new maximum processors */ public void setMaxProcessors(int maxProcessors) { this.maxProcessors = maxProcessors; } /** * Return the port number on which we listen for AJP13 requests. */ public int getPort() { return (this.port); } /** * Set the port number on which we listen for AJP13 requests. * * @param port The new port number */ public void setPort(int port) { this.port = port; } /** * Return the scheme that will be assigned to requests received * through this connector. Default value is "http". */ public String getScheme() { return (this.scheme); } /** * Set the scheme that will be assigned to requests received through * this connector. * * @param scheme The new scheme */ public void setScheme(String scheme) { this.scheme = scheme; } /** * Return the secure connection flag that will be assigned to requests * received through this connector. Default value is "false". */ public boolean getSecure() { return (this.secure); } /** * Set the secure connection flag that will be assigned to requests * received through this connector. * * @param secure The new secure connection flag */ public void setSecure(boolean secure) { this.secure = secure; } /** * Returns the <code>Service</code> with which we are associated. */ public Service getService() { return service; } /** * Set the <code>Service</code> with which we are associated. */ public void setService(Service service) { this.service = service; } /** * Get the value of the tomcatAuthentication flag. */ public boolean getTomcatAuthentication() { return tomcatAuthentication; } /** * Set the value of the tomcatAuthentication flag. */ public void setTomcatAuthentication(boolean tomcatAuthentication) { this.tomcatAuthentication = tomcatAuthentication; } // --------------------------------------------------------- Public Methods /** * Create (or allocate) and return a Request object suitable for * specifying the contents of a Request to the responsible Container. */ public Request createRequest() { Ajp13Request request = new Ajp13Request(this); request.setConnector(this); return (request); } /** * Create (or allocate) and return a Response object suitable for * receiving the contents of a Response from the responsible Container. */ public Response createResponse() { Ajp13Response response = new Ajp13Response(); response.setConnector(this); return (response); } /** * Invoke a pre-startup initialization. This is used to allow connectors * to bind to restricted ports under Unix operating environments. * ServerSocket (we start as root and change user? or I miss something?). */ public void initialize() throws LifecycleException { } // -------------------------------------------------------- Package Methods /** * Recycle the specified Processor so that it can be used again. * * @param processor The processor to be recycled */ void recycle(Ajp13Processor processor) { synchronized(processors) { if (debug > 0) { logger.log("added processor to available processors, available=" + processors.size()); } processors.push(processor); } } // -------------------------------------------------------- Private Methods /** * Create (or allocate) and return an available processor for use in * processing a specific AJP13 request, if possible. If the maximum * allowed processors have already been created and are in use, return * <code>null</code> instead. */ private Ajp13Processor createProcessor() { synchronized (processors) { if (processors.size() > 0) return ((Ajp13Processor) processors.pop()); if ((maxProcessors > 0) && (curProcessors < maxProcessors)) return (newProcessor()); else return (null); } } /** * Create and return a new processor suitable for processing AJP13 * requests and returning the corresponding responses. */ private Ajp13Processor newProcessor() { Ajp13Processor processor = new Ajp13Processor(this, curProcessors++, threadGroup); if (processor instanceof Lifecycle) { try { ((Lifecycle) processor).start(); } catch (LifecycleException e) { logger.log("newProcessor", e); curProcessors--; return (null); } } created.addElement(processor); return (processor); } /** * Open and return the server socket for this Connector. If an IP * address has been specified, the socket will be opened only on that * address; otherwise it will be opened on all addresses. * * @exception IOException if an input/output error occurs */ private ServerSocket open() throws IOException { // Acquire the server socket factory for this Connector ServerSocketFactory factory = getFactory(); // If no address is specified, open a connection on all addresses if (address == null) { logger.log(sm.getString("ajp13Connector.allAddresses")); try { return (factory.createSocket(port, acceptCount)); } catch(Exception ex ) { ex.printStackTrace(); return null; } } // Open a server socket on the specified address try { InetAddress is = InetAddress.getByName(address); logger.log(sm.getString("ajp13Connector.anAddress", address)); return (factory.createSocket(port, acceptCount, is)); } catch (Exception e) { try { logger.log(sm.getString("ajp13Connector.noAddress", address)); return (factory.createSocket(port, acceptCount)); } catch( Exception e1 ) { e1.printStackTrace(); return null; } } } // ---------------------------------------------- Background Thread Methods /** * The background thread that listens for incoming TCP/IP connections and * hands them off to an appropriate processor. */ public void run() { // Loop until we receive a shutdown command while (!stopped) { // Accept the next incoming connection from the server socket Socket socket = null; try { if (debug > 0) { logger.log("accepting socket..."); } socket = serverSocket.accept(); if (debug > 0) { logger.log("accepted socket, assigning to processor."); } /* Warning : * * To be able to close more quickly a connection, it's recommanded * to set linger to a small value. * * AJP13 connection SHOULD be closed under webserver responsability and * in such case it's safe to close socket on Tomcat side without delay, * which may be also the case for HTTP connectors. * * I (henri) recommand to set Linger to 0, making socket closed immediatly * so the OS will free faster the underlying io descriptor and resources. * It's very important under heavy load ! */ if (connectionLinger < 0) socket.setSoLinger(false, 0); else socket.setSoLinger(true, connectionLinger); socket.setKeepAlive(true); /* Warning : * * AJP13 shouldn't use socket timeout on tomcat site since * when Tomcat close a connection after a timeout is reached * the socket stay in half-closed state until the webserver * try to send a request to tomcat and detect the socket close * when it will try to read the reply. * * On many Unix platforms the write() call didn't told * webserver that the socket is closed. */ if (connectionTimeout >= 0) { socket.setSoTimeout(connectionTimeout); } } catch (AccessControlException ace) { logger.log("socket accept security exception: " + ace.getMessage()); continue; } catch (IOException e) { if (started && !stopped) logger.log("accept: ", e); try { if (serverSocket != null) { serverSocket.close(); } if (stopped) { if (debug > 0) { logger.log("run(): stopped, so breaking"); } break; } else { if (debug > 0) { logger.log("run(): not stopped, " + "so reopening server socket"); } serverSocket = open(); } } catch (IOException ex) { // If reopening fails, exit logger.log("socket reopen: ", ex); break; } continue; } // Hand this socket off to an appropriate processor if (debug > 0) { synchronized(processors) { logger.log("about to create a processor, available=" + processors.size() + ", created=" + created.size() + ", maxProcessors=" + maxProcessors); } } Ajp13Processor processor = createProcessor(); if (processor == null) { try { logger.log(sm.getString("ajp13Connector.noProcessor")); socket.close(); } catch (IOException e) { ; } continue; } processor.assign(socket); // The processor will recycle itself when it finishes } // Notify the threadStop() method that we have shut ourselves down synchronized (threadSync) { threadSync.notifyAll(); } } /** * Start the background processing thread. */ private void threadStart() { logger.log(sm.getString("ajp13Connector.starting")); thread = new Thread(threadGroup, this, threadName); thread.setDaemon(true); thread.start(); } /** * Stop the background processing thread. */ private void threadStop() { logger.log(sm.getString("ajp13Connector.stopping")); stopped = true; synchronized (threadSync) { try { threadSync.wait(5000); } catch (InterruptedException e) { ; } } thread = null; } // ------------------------------------------------------ Lifecycle Methods /** * Add a lifecycle event listener to this component. * * @param listener The listener to add */ public void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); } /** * Get the lifecycle listeners associated with this lifecycle. If this * Lifecycle has no listeners registered, a zero-length array is returned. */ public LifecycleListener[] findLifecycleListeners() { return null; // FIXME: lifecycle.findLifecycleListeners(); } /** * Remove a lifecycle event listener from this component. * * @param listener The listener to add */ public void removeLifecycleListener(LifecycleListener listener) { lifecycle.removeLifecycleListener(listener); } /** * Begin processing requests via this Connector. * * @exception LifecycleException if a fatal startup error occurs */ public void start() throws LifecycleException { // Validate and update our current state if (started) throw new LifecycleException (sm.getString("ajp13Connector.alreadyStarted")); if (debug > 0) { debugThread = new DebugThread(); debugThread.setDaemon(true); debugThread.start(); } threadName = "Ajp13Connector[" + port + "]"; threadGroup = new ThreadGroup(threadName); threadGroup.setDaemon(true); logger.setConnector(this); logger.setName(threadName); lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; // Establish a server socket on the specified port try { serverSocket = open(); } catch (IOException e) { throw new LifecycleException(threadName + ".open", e); } // Start our background thread threadStart(); // Create the specified minimum number of processors while (curProcessors < minProcessors) { if ((maxProcessors > 0) && (curProcessors >= maxProcessors)) break; Ajp13Processor processor = newProcessor(); recycle(processor); } } /** * Terminate processing requests via this Connector. * * @exception LifecycleException if a fatal shutdown error occurs */ public void stop() throws LifecycleException { // Validate and update our current state if (!started) throw new LifecycleException (sm.getString("ajp13Connector.notStarted")); lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; // Gracefully shut down all processors we have created for (int i = created.size() - 1; i >= 0; i--) { Ajp13Processor processor = (Ajp13Processor) created.elementAt(i); if (processor instanceof Lifecycle) { try { ((Lifecycle) processor).stop(); } catch (LifecycleException e) { logger.log("Ajp13Connector.stop", e); } } } // Stop our background thread threadStop(); // Close the server socket we were using if (serverSocket != null) { try { serverSocket.close(); } catch (IOException e) { ; } serverSocket = null; } } /** * Debugging thread used to debug thread activity in this * connector. */ private class DebugThread extends Thread { public void run() { while (true) { try { sleep(60 * 1000); } catch (InterruptedException e) { break; } logger.log("active threads=" + threadGroup.activeCount()); System.out.println("==================================="); System.out.println("Ajp13Connector active threads=" + threadGroup.activeCount()); threadGroup.list(); System.out.println("==================================="); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -