在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