tomcat源码解析(七):server和service
来源:互联网 发布:监控网络接入设备 编辑:程序博客网 时间:2024/05/11 13:51
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 serverif (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 serverif (server instanceof Lifecycle) { try { ((Lifecycle) server).stop(); } catch (LifecycleException e) { e.printStackTrace(System.out); }}
socket
socket一直不是太明白,等我弄明白了再来补充。
- tomcat源码解析(七):server和service
- Tomcat Session管理机制(Tomcat源码解析七)
- Tomcat Session管理机制(Tomcat源码解析七)
- (七)Tomcat源码解析 - Servlet 工作原理解析
- Tomcat源码解析(三):service服务组件
- tomcat源码浅析(二)之server.xml的解析
- Android源码解析之Binder中Server和Client获得Service Manager接口
- Volley源码解析<七> ResponseDelivery和ExecutorDelivery
- Tomcat源码解析(十):启动和关闭
- tomcat源码解析(一)
- Tomcat 源码解析(1)
- Tomcat源码解析(1)
- Tomcat源码解析(2)
- Tomcat源码解析(3)
- Tomcat源码解析(4)
- Tomcat源码解析(5)
- Tomcat源码解析(6)
- Tomcat源码解析(7)
- The word 'localhost' is not correctly spelled 这个问题怎么解决
- c++构造函数和析构函数的区别?
- hdu 3996 Gold Mine【最大权闭包-----最小割最大流Dinic】
- error:LNK2005 已经在*.obj中定义
- Impala实践之十四:一次Impala节点故障记录(不能启动)
- tomcat源码解析(七):server和service
- JPA学习1-5
- android断点续传下载文件
- POJ 2955 Brackets (区间DP)
- 使用phonegap检测网络状态
- 简单爬虫的实现与学习笔记(完)(8/31)
- leetcode 225. Implement Stack using Queues
- Tomcat的 虚拟目录&虚拟主机 配置放方法
- BL1和BL2