how tomcat work之第十四章:server and service

回顾


在前面的章节中,你已经知道了如何有一个servlet容器,通过一个连接器和一个容器并使之彼此关联。一旦一个连接器可以使用,接下来就是在端口号8080上接受HTTP请求。你不会再需要一个连接器来服务HTTPS请求。


另外,与前面章节相关联的应用程序都缺少一件事情:一个好的启动和关闭servlet容器的机制。在这一章节,我们将看另外两个组件,提供了这两种机制:server和service


Server


org.apache.catalina.Server接口表示了整个Catalina servlet容器和所有其他组件。一个server是非常重要的因为他提供了一个优雅的机制来启动和关闭整个系认。不必再分开启动连接器和容器。


这里是启动和停止机制如何工作的。当你启动一个server,在里面启动了所有的组件。之后就等待一个关闭指令。如果你想关闭系统,你就发送一个指定端口的关闭指令。这个将发送到server并且其如果接受到正确的关闭指令,就会关闭所有的组件。



一个服务器使用另一个组件,一个service,来保持组件比如一个容器和一个或者更多的连接器。



Server接口代码如下:





shutdown属性持有一个字符串必须发送到一个服务器的实例来关闭它。port属性定义了一个服务器等待关闭命令的端口。你可以增加service对象给server,通过调用它的addService方法。稍后,通过调用removeService方法来移除一个service。findServices方法返回现有server中的所有service。initialize方法包含了必须在启动前执行的代码。


StandardServer


org.apache.catalian.core.StandardServer类是一个server的标准实现。我们要注意的是这个类提供的关闭机制,也是这个类中的最重要的功能。许多方法与server 配置相关的都存储在一个server xml文件中,但是这里不讨论。


一个服务器可以有一个或者多个services,StandardServer提供了addService,removeService和findService的实现。


与StandardServer的生命周期相关的四个方法是:initialize,start,stop和await。就像其他组件,你启动和开启一个server,紧跟着stop方法需要调用await方法。这个await方法不返回直到在指定端口上接受一个关闭命令。当await方法返回的时候,运行stop方法来关闭所有的子组件。在这一章节相关联的应用中,你将学会如何实现关闭的机制。




the initialize method


initialize方法用来初始化添加到这个server实例的services,Tomcat 4中的initialize方法代码如下:



注意这个initialize方法指定了一个名字为initialized的布尔,来避免这个服务被初始化两次。在Tomcat 5中,虽然initialize方法相似,但是了也包含了与JMX相关联的核心代码。stop方法不重置initialized的值,这样如果服务器关闭再开启后,它的initialize方法不会再被调用。


the start method

调用start方法来启动服务。在StandardServer中的这个方法的实现启动了所有的服务,其中轮流启动所有其他组件,比如连接器和容器。清单14.3显示了start方法。




start方法指定了一个start 布尔变量来阻止一个服务器开启两次。stop方法重置这个值。



the stop method


stop方法停止这个服务。清单14.4显示了这个方法。



调用stop方法停止所有的服务并重置started值。这样服务器可以再次启动。


the await method


await方法为整个tomcat的部署的停止机制负责。代码清单如下:

public  void  await(){
	//Set up a server to wait on
        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.accpet();
		socket.setTimeout(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
	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){
		;
	}
    }
}



await方法创建了一个ServerSockt对象,并指定了端口号,之后在一个while循环中调用accept方法。如果在指定的端口上有来到的消息这个accep方法才会返回。每条消息将与shutdown命令匹配。如果匹配了,就跳出while循环并关闭serverSocket。如果不匹配,控制始终停留在while循环中直到另一个消息的到来。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值