您的位置:首页 > 运维架构 > Tomcat

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