tomcat源码解析(七):server和service
2016-08-25 18:35
316 查看
server和service的作用是什么?
Catalina主要包括connector和container两个模块,connector负责接收请求,传递给container,而container负责处理请求。service的作用是统一管理connector和container,一个service可以包括多个connector和一个container。而server的作用是,管理所有的service,一个server可以包括多个service。server负责管理所有service的生命周期,这样就管理了所有的connector和container,以及connector和container的所有内部组件。这样就不需要单独对connector和container单独进行开启或关闭了。
主要流程
初始化server/** * Invoke a pre-startup initialization. This is used to allow connectors * to bind to restricted ports under Unix operating environments. */ public void initialize() throws LifecycleException { if (initialized) throw new LifecycleException ( sm.getString("standardServer.initialize.initialized")); initialized = true; // Initialize our defined Services for (int i = 0; i < services.length; i++) { services[i].initialize(); } }
初始化service
/** * Invoke a pre-startup initialization. This is used to allow connectors * to bind to restricted ports under Unix operating environments. */ public void initialize() throws LifecycleException { if (initialized) throw new LifecycleException ( sm.getString("standardService.initialize.initialized")); initialized = true; // Initialize our defined Connectors synchronized (connectors) { for (int i = 0; i < connectors.length; i++) { connectors[i].initialize(); } } }
启动server,调用service.start()
/** * Prepare for the beginning of active use of the public methods of this * component. This method should be called before any of the public * methods of this component are utilized. It should also send a * LifecycleEvent of type START_EVENT to any registered listeners. * * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void start() throws LifecycleException { // Validate and update our current component state if (started) throw new LifecycleException (sm.getString("standardServer.start.started")); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; // Start our defined Services synchronized (services) { for (int i = 0; i < services.length; i++) { if (services[i] instanceof Lifecycle) ((Lifecycle) services[i]).start(); } } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
启动service,会调用connector和container的start(),这样connector和container都启动啦。
/** * Prepare for the beginning of active use of the public methods of this * component. This method should be called before any of the public * methods of this component are utilized. It should also send a * LifecycleEvent of type START_EVENT to any registered listeners. * * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void start() throws LifecycleException { // Validate and update our current component state if (started) { throw new LifecycleException (sm.getString("standardService.start.started")); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); System.out.println (sm.getString("standardService.start.name", this.name)); lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; // Start our defined Container first if (container != null) { synchronized (container) { if (container instanceof Lifecycle) { ((Lifecycle) container).start(); } } } // Start our defined Connectors second synchronized (connectors) { for (int i = 0; i < connectors.length; i++) { if (connectors[i] instanceof Lifecycle) ((Lifecycle) connectors[i]).start(); } } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
server.await(),监听8005端口消息,若收到shutdown命令,就关闭serversocket,并返回。Bootstrap.main()中,从StandardServer.await()返回后,会执行StandardServer.stop(),就可以关闭所有service了。
/** * Wait until a proper shutdown command is received, then return. */ public void await() { // Set up a server socket to wait on // 监听8005端口 ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1")); } catch (IOException e) { System.err.println("StandardServer.await: create[" + port + "]: " + e); e.printStackTrace(); System.exit(1); } // Loop waiting for a connection and a valid command while (true) { // Wait for the next connection Socket socket = null; InputStream stream = null; try { socket = serverSocket.accept(); socket.setSoTimeout(10 * 1000); // Ten seconds stream = socket.getInputStream(); } catch (AccessControlException ace) { System.err.println("StandardServer.accept security exception: " + ace.getMessage()); continue; } catch (IOException e) { System.err.println("StandardServer.await: accept: " + e); e.printStackTrace(); System.exit(1); } // Read a set of characters from the socket StringBuffer command = new StringBuffer(); int expected = 1024; // Cut off to avoid DoS attack while (expected < shutdown.length()) { if (random == null) random = new Random(System.currentTimeMillis()); expected += (random.nextInt() % 1024); } while (expected > 0) { int ch = -1; try { ch = stream.read(); } catch (IOException e) { System.err.println("StandardServer.await: read: " + e); e.printStackTrace(); ch = -1; } if (ch < 32) // Control character or EOF terminates loop break; command.append((char) ch); expected--; } // Close the socket now that we are done with it try { socket.close(); } catch (IOException e) { ; } // Match against our command string System.out.println("[StandardServer] command: " + command); boolean match = command.toString().equals(shutdown); if (match) { break; } else System.err.println("StandardServer.await: Invalid command '" + command.toString() + "' received"); } // Close the server socket and return try { serverSocket.close(); } catch (IOException e) { ; } }
一个service可以包括多个connector和一个container,一个connector收到请求后将它发给container处理,service怎么样将connector和container关联起来呢?
在service.setContainer()中,会关联二者。
/** * Set the <code>Container</code> that handles requests for all * <code>Connectors</code> associated with this Service. * * @param container The new Container */ public void setContainer(Container container) { Container oldContainer = this.container; if ((oldContainer != null) && (oldContainer instanceof Engine)) ((Engine) oldContainer).setService(null); this.container = container; if ((this.container != null) && (this.container instanceof Engine)) ((Engine) this.container).setService(this); if (started && (this.container != null) && (this.container instanceof Lifecycle)) { try { ((Lifecycle) this.container).start(); } catch (LifecycleException e) { ; } } synchronized (connectors) { for (int i = 0; i < connectors.length; i++) connectors[i].setContainer(this.container); } if (started && (oldContainer != null) && (oldContainer instanceof Lifecycle)) { try { ((Lifecycle) oldContainer).stop(); } catch (LifecycleException e) { ; } } // Report this property change to interested listeners support.firePropertyChange("container", oldContainer, this.container); }
从await()返回后,调用server.stop()。
// Start the new server if (server instanceof Lifecycle) { try { server.initialize(); ((Lifecycle) server).start(); server.await(); // the program waits until the await method returns, // i.e. until a shutdown command is received. } catch (LifecycleException e) { e.printStackTrace(System.out); } } // Shut down the server if (server instanceof Lifecycle) { try { ((Lifecycle) server).stop(); } catch (LifecycleException e) { e.printStackTrace(System.out); } }
socket
socket一直不是太明白,等我弄明白了再来补充。相关文章推荐
- tomcat源码解析(一)--启动与Server.xml文件的解析
- Tomcat7.0源码分析——server.xml文件的加载与解析
- Tomcat源码的catalina中利用Digester解析conf/server.xml
- 【Web容器】Tomcat源码分析(2)-server.xml文件的加载与解析
- Tomcat源码的catalina中利用Digester解析conf/server.xml
- Tomcat源码分析——SERVER.XML文件的加载与解析
- tomcat源码分析 StandardServer初始化过程
- 【Tomcat】Tomcat源码解读系列(一)——server.xml文件的配置
- tomcat 解析包含中文的cookie 抛警告源码分析
- Tomcat 请求过程源码解析(二)
- Degister源码解析及在tomcat中的应用
- Tomcat中的Service Server
- tomcat解析(九)StandardServer.initialize.start
- tomcat配置文件web.xml与server.xml解析--重要
- 源码解析IntentService的好处
- Tomcat Server.xml解析
- 解析Server.xml apache-tomcat/congf/server.xml
- tomcat解析(十)StandardService.initialize.start
- Tomcat 警告:[SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source...的解决方法
- tomcat5源码解析一 PoolTcpEndpoint类