在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