`
z283464598
  • 浏览: 22918 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论
阅读更多
Tomcat的模块结构设计的相当好,而且其Web 容器的性能相当出色。JBoss直接就使用了Tomcat的web容器,WebLogic的早期版本也是使用了Tomcat的代码。
Web容器的工作过程在下面的第二个参考文档中的文档已经说得相当清楚,我也就不再重复说了。如果不清楚调用过程,需要先看这个文档。这里分析一下Connector的处理过程。
1. 一个简单的Web Server示例
这个例子也是从网上找得,不知道原作者,也就不在参考资料中引用了。
这个启动服务的主程序。
public class HttpServer {
public static void main(String args[]) {
  int port;
  ServerSocket server_socket; // 读取服务器端口号
  try {
   port = Integer.parseInt(args[0]);
  } catch (Exception e) {
   port = 8080;
  }
  try {
   // 监听服务器端口,等待连接请求
   server_socket = new ServerSocket(port);
   System.out.println(”httpServer running on port “
     + server_socket.getLocalPort());
   // 显示启动信息
   while (true) {
    Socket socket = server_socket.accept();
    System.out.println(”New connection accepted “
      + socket.getInetAddress() + “:” + socket.getPort());
    // 创建分线程
    try {
     HttpRequestHandler request = new HttpRequestHandler(socket);
     Thread thread = new Thread(request);
     // 启动线程
     thread.start();
    } catch (Exception e) {
     System.out.println(e);
    }
   }
  } catch (IOException e) {
   System.out.println(e);
  }
}
}

下面是创建输出的线程
public class HttpRequestHandler implements Runnable {
final static String CRLF = “\r\n”;
Socket socket;
InputStream input;
OutputStream output;
BufferedReader br;
// 构造方法
public HttpRequestHandler(Socket socket) throws Exception {
  this.socket = socket;
  this.input = socket.getInputStream();
  this.output = socket.getOutputStream();
  this.br = new BufferedReader(new InputStreamReader(socket
    .getInputStream()));
}

// 实现Runnable 接口的run()方法
public void run() {
  try {
   processRequest();
  } catch (Exception e) {
   System.out.println(e);
  }
}

private void processRequest() throws Exception {
  while (true) {
   // 读取并显示Web 浏览器提交的请求信息
   String headerLine = br.readLine();
   System.out.println(”The client request is ” + headerLine);
   if (headerLine.equals(CRLF) || headerLine.equals(”"))
    break;
   StringTokenizer s = new StringTokenizer(headerLine);
   String temp = s.nextToken();
   if (temp.equals(”GET”)) {
    String fileName = s.nextToken();
    fileName = “.” + fileName;
    // 打开所请求的文件
    FileInputStream fis = null;
    boolean fileExists = true;
    try {
     fis = new FileInputStream(”D:/workspace/tomcat/bin/”+fileName);
    } catch (FileNotFoundException e) {
     fileExists = false;
    }
    // 完成回应消息
    String serverLine = “Server: a simple java httpServer”;
    String statusLine = null;
    String contentTypeLine = null;
    String entityBody = null;
    String contentLengthLine = “error”;
    if (fileExists) {
     statusLine = “HTTP/1.0 200 OK” + CRLF;
     contentTypeLine = “Content-type: ” + contentType(fileName) + CRLF;
     contentLengthLine = “Content-Length: “
       + (new Integer(fis.available())).toString() + CRLF;
    } else {
     statusLine = “HTTP/1.0 404 Not Found” + CRLF;
     contentTypeLine = “text/html”;
     entityBody = “<HTML>”
       + “<HEAD><TITLE>404 Not Found</TITLE></HEAD>” + “<BODY>404 Not Found” + “<br>usage:http://yourHostName:port/” + “fileName.html</BODY></HTML>”;
    }
    // 发送到服务器信息
    output.write(statusLine.getBytes());
    output.write(serverLine.getBytes());
    output.write(contentTypeLine.getBytes());
    output.write(contentLengthLine.getBytes());
    output.write(CRLF.getBytes());
    // 发送信息内容
    if (fileExists) {
     sendBytes(fis, output);
     fis.close();
    } else {
     output.write(entityBody.getBytes());
    }
   }
  }
  // 关闭套接字和流
  try {
   output.close();
   br.close();
   socket.close();
  } catch (Exception e) {
  }
}

private static void sendBytes(FileInputStream fis, OutputStream os)
   throws Exception {
  // 创建一个 1K buffer
  byte[] buffer = new byte[1024];
  int bytes = 0;
  // 将文件输出到套接字输出流中
  while ((bytes = fis.read(buffer)) != -1) {
   os.write(buffer, 0, bytes);
  }
}

private static String contentType(String fileName) {
  if (fileName.endsWith(”.htm”) || fileName.endsWith(”.html”)) {
   return “text/html”;
  }
  return “fileName”;
}
}
这个简单的例子说明的web服务的基本实现。Tomcat在此之上模块化出线程池,网络连接和WebHttp协议3个包。线程池可独立使用,网络连接使用池化,WebHttp直接从网络连接池中获取即可。
2. 线程池的实现
这个功能的实现在包 org.apache.tomcat.util.thread 中。
ThreadPool是线程池,是这个功能实现的核心。它使用了所有的其他类进行工作。在类图中,所有的其他类都是被此类的使用关系。
我们来看此类是如何工作得。
启动连接池的方法:
public synchronized void start() {
  stopThePool = false;
  currentThreadCount = 0;
  currentThreadsBusy = 0;

  adjustLimits();
  pool = new ControlRunnable[maxThreads];
  openThreads(minSpareThreads);
  if (maxSpareThreads < maxThreads) {
   monitor = new MonitorRunnable(this);
  }
}
方法中,根据配置情况,初始化所有线程进入备用状态。
首先定义maxThreads数目的数组,但是仅仅初始化其中minSpareThreads个。MonitorRunnable用于检查,是否空闲数目超过 maxSpareThreads个。
currentThreadCount 是当前初始化可以使用的线程数目,而currentThreadsBusy 是当前正在使用的线程数目。
使用连接池的方法:
public void runIt(ThreadPoolRunnable r) {
  if (null == r) {
   throw new NullPointerException();
  }
  ControlRunnable c = findControlRunnable();
  c.runIt(r);
}
该方法中,先寻找可用的线程,找到后在其中运行即可。
找可用线程的方法也很简单,就是将线程数组中第 currentThreadCount - currentThreadsBusy - 1 个元素取出返回,然后将此元素设成null。
线程运行完毕后,设置currentThreadsBusy– ,然后将 currentThreadCount - currentThreadsBusy - 1 的线程放回就可以了。
线程不够用就等待,等待失败就抛出异常。
说明一下上面未提到的类的功能:
ThreadPoolRunnable 这是一个接口,规定了一个线程运行时需要运行的一些动作。这里需要写一些业务逻辑的代码了。
ThreadWithAttributes 这个类从上面的代码中没有看到,这个类标识当前运行线程的一些特征,比如记录当前运行线程的一些状态。
ThreadPoolListener 用于监控ThreadPool中新增线程的情况。
ControlRunnable 这个类是ThreadPool的内部类,用于运行ThreadPoolRunnable 。当ThreadPoolRunnable 运行完毕后,通知ThreadPool回收线程。它时刻处于备用状态。此对象实例化后,就一直在死循环检查是否有它需要运行的东西。
3. 网络连接功能的实现
这个功能的实现在包 org.apache.tomcat.util.net 中。
网络连接功能构建于线程池之上,实现了一个连接服务模型。服务器打开端口,池化进入连接,为进入的连接创建工作线程。
Tomcat的网络连接两个主要的应用是1. 自己提供的web应用。2. 给Apache提供的web应用。这两个过程的解析过程都是一样的。仅仅在于网络连接协议有差别而已。两个应用都使用此包的功能实现。

PoolTcpEndpoint是核心,它使用了ThreadPool。TcpWorkerThread通过调用接口TcpConnectionHandler来完成一次连接需要完成的工作。TcpConnection标识了一个连接对象。
PoolTcpEndpoint的初始化方法代码很简单,在构建器中创建或引用ThreadPool,在初始化时创建ServerSocket,用于侦听客户端连接。
下面是初始化方法
public void initEndpoint() throws IOException, InstantiationException {
  try {
   if (factory == null)
    factory = ServerSocketFactory.getDefault();
   if (serverSocket == null) {
    try {
     if (inet == null) {
      serverSocket = factory.createSocket(port, backlog);
     } else {
      serverSocket = factory
        .createSocket(port, backlog, inet);
     }
    } catch (BindException be) {
     throw new BindException(be.getMessage() + “:” + port);
    }
   }
   if (serverTimeout >= 0)
    serverSocket.setSoTimeout(serverTimeout);
  } catch (IOException ex) {
   // log(”couldn’t start endpoint”, ex, Logger.DEBUG);
   throw ex;
  } catch (InstantiationException ex1) {
   // log(”couldn’t start endpoint”, ex1, Logger.DEBUG);
   throw ex1;
  }
  initialized = true;
}

启动的方法同样简单,仅仅将TcpWorkerThread作为线程池的工作线程,启动连接池,就大功告成了。
public void startEndpoint() throws IOException, InstantiationException {
  if (!initialized) {
   initEndpoint();
  }
  if (isPool) {
   tp.start();
  }
  running = true;
  paused = false;
  if (isPool) {
   listener = new TcpWorkerThread(this);
   tp.runIt(listener);
  } else {
   log.error(”XXX Error - need pool !”);
  }
}

侦听的细节包装在TcpWorkerThread类中。运行时,它在ServerSocket端口侦听。当发现有连接进入后,立刻开启一个新线程继续侦听,本线程开始处理连接。下面是代码:
public void runIt(Object perThrData[]) {
  // Create per-thread cache
  if (endpoint.isRunning()) {
   // Loop if endpoint is paused
   while (endpoint.isPaused()) {
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     // Ignore
    }
   }
   // Accept a new connection
   Socket s = null;
   try {
    s = endpoint.acceptSocket();
   } finally {
    // Continue accepting on another thread…
    if (endpoint.isRunning()) {
     endpoint.tp.runIt(this);
    }
   }
   // Process the connection
   if (null != s) {
    TcpConnection con = null;
    int step = 1;
    try {
     // 1: Set socket options: timeout, linger, etc
     endpoint.setSocketOptions(s);
     // 2: SSL handshake
     step = 2;
     if (endpoint.getServerSocketFactory() != null) {
endpoint.getServerSocketFactory().handshake(s);
     }
     // 3: Process the connection
     step = 3;
     con = (TcpConnection) perThrData[0];
     con.setEndpoint(endpoint);
     con.setSocket(s);
endpoint.getConnectionHandler().processConnection(con,
       (Object[]) perThrData[1]);
    } catch (SocketException se) {
……
4. 协议 web http的实现
这个功能的实现在包 org.apache.coyote.http11 中。
对于Http协议的实现核心类是Http11Protocol。具体功能的实现类有MXPoolListener(实现ThreadPoolListener),Http11ConnectionHander(实现TcpConnectionHandler)。
Http11Protocol的初始化方法比较简单,就是设置一下让网络连接开始运行。
Http11ConnectionHander则初始化类Http11Processor,由它解析请求的字符串,交给生成此Connection的Connector的Container,也就是Engine完成。Engine通过递归,解析应返回用户的数据。这个过程在参考文档中有介绍了。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/aking21alinjuju/archive/2009/05/17/4195929.aspx
分享到:
评论

相关推荐

    tomcat7,tomcat8,tomcat9

    Tomcat7、Tomcat8和Tomcat9是不同版本的Tomcat,每个版本都有其特性和改进。 **Tomcat7**: Tomcat7是2011年发布的,它主要支持Java Servlet 3.0和JSP 2.2规范。这个版本引入了一些重要改进,包括增强的安全性、更...

    tomcat7tomcat8tomcat9

    Tomcat是Apache软件基金会下的一个开源项目,是一个广泛使用的Java Servlet容器,特别因为其轻量级、高效能和稳定性而闻名。它实现了Java Servlet和JavaServer Pages(JSP)规范,使得开发者能够用Java语言来编写...

    tomcat 7 和 tomcat 8

    Tomcat 7 和 Tomcat 8 是两个非常重要的版本,它们是Apache软件基金会开发的开源Java Servlet容器,主要用于运行Java Web应用程序。这两个版本都遵循Java EE(Enterprise Edition)规范,但各自具有不同的特点和改进...

    Tomcat7.0 tomcat最新版本

    Apache Tomcat 7.0是Java Servlet和JavaServer Pages(JSP)的开源Web应用程序服务器,由Apache软件基金会开发和维护。它是最流行的轻量级应用服务器,特别适合部署Java Web应用程序。Tomcat 7.0是7.x系列的一个版本...

    Linux(CentOS7)安装Tomcat与设置Tomcat为开机启动项(tomcat8为例)

    在Linux(CentOS7)操作系统中安装Apache Tomcat并将其设置为开机启动是一项常见的任务,特别是在部署Java web应用时。本篇文章将详细讲解如何在CentOS7上安装Tomcat8并将其配置为自启动服务。 首先,我们来了解...

    tomcat6,用于idea适配低版本的tomcat

    标题中的“tomcat6”指的是Apache Tomcat 6,这是一个开源的应用服务器,主要用来部署和运行Java Servlet和JavaServer Pages(JSP)应用程序。在Java Web开发领域,Tomcat是应用最广泛的轻量级服务器之一,尤其对于...

    tomcat打补丁方法

    ### Tomcat打补丁方法详解 #### 一、前言 Apache Tomcat是一款开源的Servlet容器,它能够作为Web服务器独立运行,也可以与Apache等其他Web服务器配合使用。Tomcat因其简单性和灵活性,在中小型项目中得到了广泛...

    tomcat-redis-session-manager的jar包-包含Tomcat7和Tomcat8

    《深入理解Tomcat-Redis-Session-Manager:在Tomcat7和Tomcat8中的应用》 在现代Web应用程序开发中,session管理是一个至关重要的环节,它涉及到用户会话的持久化和跨请求的数据共享。传统的session管理方式在高...

    tomcat-redis-session-manager-1.2-tomcat-7-java-7

    tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-...

    idea tomcat runner插件

    **Idea Tomcat Runner插件详解** 在Java开发领域,IntelliJ IDEA是一款备受推崇的集成开发环境(IDE),尤其以其高效、智能的代码编辑功能和丰富的插件生态而著称。对于使用Java Web应用的开发者来说,Tomcat服务器...

    tomcat-juli.jar,tomcat-juli-adapters.jar,log4j-1.2.12.jar tomcat 6日志输出

    在Java Web应用服务器Tomcat 6中,日志管理是一个至关重要的部分,它帮助开发者跟踪应用程序的运行状态,排查问题,以及记录系统活动。这里提到的`tomcat-juli.jar`、`tomcat-juli-adapters.jar`和`log4j-1.2.12.jar...

    apache-tomcat-7.0.52 解压免安装版tomcat7

    Apache Tomcat 7.0.52 是一个广泛使用的开源软件,它是一个实现了Java Servlet、JavaServer Pages(JSP)和Java EE的Web应用程序容器。这个版本是免安装的,这意味着用户无需经过复杂的安装过程,只需解压到指定目录...

    tomcat 7 最新版本 apache-tomcat-7.0.109

    Apache Tomcat 7是Apache软件基金会的一个开源项目,专门用于实现Java Servlet和JavaServer Pages(JSP)技术的标准,以及Java EE的Web应用程序部署。这个最新版本,即7.0.109,包含了对先前版本的改进和修复,旨在...

    tomcat5.5tomcat最新客户端

    tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat...

    tomcat-jdbc数据源所需jar包tomcat-jdbc.jar+tomcat-juli.jar

    在Java Web应用中,Tomcat是一个广泛使用的开源应用服务器,它提供了Servlet容器和JSP引擎等核心功能。在处理数据库连接方面,Tomcat提供了一种高效且可管理的数据源实现,名为“tomcat-jdbc数据源”。这个数据源是...

    Tomcat 修改内存大小

    Tomcat 修改内存大小 Tomcat 是一个流行的基于 Java 的 Web 应用服务器,为了确保 Tomcat 的稳定运行,需要根据实际情况调整 Tomcat 的内存大小。下面将介绍如何修改 Tomcat 的内存大小,在 Windows 和 Linux 两个...

    最新版 tomcat 9.0.10

    这是Apache Tomcat Servlet /JSP容器的文档包的顶级入口点。Apache Tomcat 9版本实现了Java社区过程中的Servlet 4和JavaServer页面2.3规范,并包含了许多额外的特性,使其成为开发和部署Web应用程序和Web服务的有用...

    java代码启动tomcat

    Java 代码启动 Tomcat 在 Java 中,使用 Tomcat 服务器来发布 Web 应用程序是一种常见的做法。下面,我们将详细介绍如何使用 Java 代码来启动 Tomcat 服务器,并实现远程控制 Tomcat。 标题: Java 代码启动 ...

    apache-tomcat-8.5.23-windows-x64.zip 【Tomcat服务器,Tomcat8.5 windows 64位版】

    Apache Tomcat是一个开源的Java Servlet容器,主要用于运行Java Web应用程序,包括JSP和Servlet。Tomcat8.5.23是该服务器的一个特定版本,专为Windows 64位操作系统设计,提供高效、稳定和安全的平台来部署Web服务。...

    tomcat windows版本下载

    Apache Tomcat是一款开源的Java Servlet容器,主要用于部署和运行Java Web应用程序,包括JSP和Servlet。在Windows操作系统上安装和配置Tomcat对于开发者来说是一项基本技能。以下将详细讲解"tomcat windows版本下载...

Global site tag (gtag.js) - Google Analytics