轉載自:https://www.cnblogs.com/barrenlake/p/4364644.htmlhtml
Spark 監控相關的部分有WebUi 及 Metrics System; WebUi用於展現Spark 資源狀態、Metrics System 整合的指標信息。java
Spark集羣啓動以後,咱們能夠經過Web觀察集羣狀態等信息,這一部分工做是Spark WebUi 模塊實現。web
Servlet容器啓動:apache
Master建立時,會經過val webUi = new MasterWebUI(this, webUiPort)建立webUi,json
在啓動Master時(perStart()中)經過webUi.bind()啓動JettyServer,即Servlet容器。app
Master的preStart()的源碼以下所示函數
又webUi.bind()的源碼以下所示:this
建立的MasterWebUI初始化時會添加三個頁面和一個靜態資源處理器,其初始化代碼以下:spa
其中 attachPage方法代碼以下:3d
其在添加頁面時將初始化,頁面地址pagePath,建立並綁定請求處理器,以及指定響應方法page.render(request).
其中createServletHandler實現以下:
此函數中會調用另外一重載方法,其又會調用creatServlet方法,建立Servlet用於對外提供服務。createServlet方法代碼以下所示:
Servlet中doGet方法用來處理get請求, 具體業務邏輯由傳入的servletParams提供。
下面以attachPage(new MasterPage(this))爲例對servletParams進行說明,由上文源碼示例attachPage可知 (request: HttpServletRequest) => page.render(request)爲servletParams。此參數意爲使用page.render(request)對request進行處理。
MasterPage負責對master頁面的請求,請求路徑爲http://master:webUiPort/或http://master:webUiPort/json.
下面http://master:webUiPort/json請求進行說明,當servlet接收到請求後,經過page.renderJson對其進行處理, renderJson源程序代碼以下:
經過分析源代碼可知:renderjson首先向master發送消息RequestMasterState,請求Master的狀態信息. 而後阻塞等待結果,而後將結果轉換成JSON格式、返回。
Master收到RequestMasterState消息後:
將其狀態信息封裝成MasterStateResponse對象發送給請求者。
Spark中的Metrics System 特殊的「實例」建立的,結合數據源、數據匯(接收點)的系統,其做用是按期將數據指標從數據源拉到數據匯。
實例(instance):建立Metrics的實例通常指使用Metrics System的角色。Spark中有多種角色,像master, worker, executor, client Driver,這些角色會建立Metrics System用於監控。因此這裏所說的「實例」表明這些角色。當前,Spark中已實現的實例有:master,worker, executor,driver, applications.
數據源(source): 從哪裏收集數據指標,在Metrics System中存在兩種類型的數據源:
Spark 內部源,像MasterSource, WorkerSource等,這些源會收集Spark組件的狀態,它們與Spark中角色相關,當Metrics System建立後,它們會在Metrics System中註冊。
共用源,經過配製文件配製並經過反射機制進行加載,會收集更底層的狀態指標,像JvmSource。
數據匯(sink):收集的數據指標輸出的目的地,目的地能夠是控制檯,Servlet等。
下面以Master爲入口對Metrics System工做機制作詳細說明:
伴隨Master的建立會建立MetricsSystem、MasterSource、WebUI等對象
在Master啓動時會執行如下動做:
綁定WebUI
將MasterSource註冊到Metrics中,
啓動MetricsSystem,並將其servlethandler綁定到WebUI.
建立MetricsConfig時會建立並初始化MetricsConfig, MetricsConfig將持有一個HashMap類型的propertyCategories,其用來存放處理過的屬性集合。再獲取MetricsConfig實例時都將會今後屬性中取相應的MetricsConfig配製.以下代碼所示:若存在指定key的屬性,則返回;不然返回默認值。
propertyCategories將在MetricsConfig初始化時(initialize())調用時對其賦值,初始化過程以下:
防止沒有屬性文件,添加默認屬性。
檢測spark.metrics.conf是否設置,若未設置則試着去classpath下尋找」metrics.properties」文件。若存在配製文件,則將其屬性載入properties。
而後將properties中內容進行抽取、分類、歸併處理,其代碼以下:
若不存在配製文件的狀況下,系統只有默認添加屬性,經上述代碼處理的結果爲:
applications -> {sink.servlet.class=org.apache.spark.metrics.sink.MetricsServlet, sink.servlet.path=/metrics/applications/json} master -> {sink.servlet.class=org.apache.spark.metrics.sink.MetricsServlet, sink.servlet.path=/metrics/master/json} * -> {sink.servlet.class=org.apache.spark.metrics.sink.MetricsServlet, sink.servlet.path=/metrics/json}
其中subProperties()方法是對properties屬性進行抽取、規類。代碼以下:
當MetricsSystem 在啓動時將會調用註冊數據源函數registerSources(),註冊實例相關的全部數據源。
上面是registerSources相關代碼,其經過getInstance()方法獲取該instance相關的配製屬性。而後經過subProperties方法進行抽取、歸類。而後取出key爲class的屬性,利用java反射機制建立Source對象並進行註冊。默認狀況下不存在Source相關屬性,因此此例中MasterSource惟一數據源。
其經過MetricsConfig的getInstance()方法。該方法會以傳入的instance作爲key 去propertyCategories中取屬性值
MetricsSystem的start()方法經過調用registerSinks()方法來註冊數據匯(數據指標接收點)。程序代碼以下所示:
經過分析此方法的源碼,若未經過配製文件指定MetricsConfig屬性,則將只經過反射建立MetricsServlet,其內部再建立ServletHander交付WebUI使用。但此MetricsServlet並未作爲sink添加到sinks列表,至此 sinks列表仍爲空,MetricsSystem的start()方法中調用sinks.foreach(_.start)時將不執行任何動做。換句話說,在默認狀況下,registerSinks方法只是對MetricsServlet進行實例化用。
MetricsSystem在註冊Sink時, 會建立MetricsServlet, MetricsServlet的映射地址爲propertyCategories是path屬性對應項,其作爲一個web服務,用於對相應請求進行處理。 MetricsServlet會經過調用jettyUtils的createServletHandler方法ServletContextHandler,建立Handler。其核心代碼以下:
此方法將建立以/metrics/master/json爲請求路徑的httpServlet, 影響類型爲JSON串。
而後並將建立的Hander賦值給經過MetircsSystem的getServletHander方法交由WebUi處理。
getServletHander方法程序代碼以下所示: