在hadoop中很多地方都用到了servlet,并且使用jetty作为servlet的容器来提供http的服务,其主要是通过org.apache.hadoop.http.HttpServer类实现的,HttpServer类是对Jetty的简单封装,通过调用HttpServer类的addServlet方法增加可以实现增加servlet到jetty的功能:

  public void addServlet(String name, String pathSpec,
      Class<? extends HttpServlet> clazz) {     //名称,url访问路径,处理类
    addInternalServlet(name, pathSpec, clazz, false);
    addFilterPathMapping(pathSpec, webAppContext);
  }

默认在HttpServer的构造函数中,会调用addDefaultServlets添加需要增加的servlets:

 public HttpServer(String name, String bindAddress, int port,
      boolean findPort, Configuration conf, AccessControlList adminsAcl,
      Connector connector, String[] pathSpecs) throws IOException {
....
    webAppContext = new WebAppContext();
    webAppContext.setDisplayName(name);
    webAppContext.setContextPath( "/");
    webAppContext.setWar(appDir + "/" + name);
....
   addDefaultServlets();
....

启动addDefaultServlets定义了默认加载的servlet:

  protected void addDefaultServlets() {
    // set up default servlets
    addServlet("stacks" , "/stacks" , StackServlet.class);
    addServlet("logLevel", "/logLevel", LogLevel.Servlet.class);
    addServlet("metrics", "/metrics", MetricsServlet.class);
    addServlet("jmx", "/jmx", JMXJsonServlet.class);
    addServlet("conf", "/conf", ConfServlet.class);
  }

hadoop在多个地方都用到了HttpServer这个类:

比如在org.apache.hadoop.hdfs.server.datanode.DataNode类中:

DataNode的构造函数--->startDataNode-->initDataXceiver+startInfoServer

其中startInfoServer就是调用HttpServer类启动jetty的:

private HttpServer infoServer = null;
...
private void startInfoServer(Configuration conf) throws IOException {
  // create a servlet to serve full-file content
  InetSocketAddress infoSocAddr = DataNode.getInfoAddr(conf);
  String infoHost = infoSocAddr.getHostName();
  int tmpInfoPort = infoSocAddr.getPort();
  this.infoServer = (secureResources == null)
     ? new HttpServer("datanode", infoHost, tmpInfoPort, tmpInfoPort == 0,
         conf, new AccessControlList(conf.get(DFS_ADMIN, " ")))
     : new HttpServer("datanode", infoHost, tmpInfoPort, tmpInfoPort == 0,
         conf, new AccessControlList(conf.get(DFS_ADMIN, " ")),
         secureResources.getListener());
  LOG.info("Opened info server at " + infoHost + ":" + tmpInfoPort);
.....
  this.infoServer.addInternalServlet(null, "/streamFile/*", StreamFile.class); //添加datanode专属的servlet
  this.infoServer.addInternalServlet(null, "/getFileChecksum/*",
      FileChecksumServlets.GetServlet.class);
  this.infoServer.setAttribute("datanode", this);
  this.infoServer.setAttribute(JspHelper.CURRENT_CONF, conf);
  this.infoServer.addServlet(null, "/blockScannerReport",
                             DataBlockScanner.Servlet.class);
  if (WebHdfsFileSystem.isEnabled(conf, LOG)) {
    infoServer.addJerseyResourcePackage(DatanodeWebHdfsMethods.class
        .getPackage().getName() + ";" + Param.class.getPackage().getName(),
        WebHdfsFileSystem.PATH_PREFIX + "/*");
  }
  this.infoServer.start();
}

小结如下:

1)HttpServer是对Jetty的简单封装

2)hadoop各个组件都会用到HttpServer,datanode/namenode,resourcemanager等

其主要功能有:Hadoop的内部状态显示,运行和管理

3)HttpServer的addDefaultServlets方法定义了通用的几个servlet(比如更改日志级别的servlet),在每个类中又会定义属于自己的servlet