背景:
公司自建IDC機房,基於IDC機房構建大數據集羣;須要對集羣資源進行監控,集羣採用的是CDH集羣,採集主要分兩塊進行:javaHDFS和YARN相關的指標進行採集
IDC機器自身的指標進行採集
注意: 也許有人會有疑惑,CM界面已經提供了監控的圖表,爲何還須要本身進行展現。緣由在於,這些信息須要集成到內部的數據平臺上面去,作成對應的數據報表,可視化的方式展現在本身的數據平臺上spring實現思路大體能夠分爲兩種:sql
使用CM所提供的Java API去獲取 使用CM提供的REST API去獲取其實二者本質上是同樣的,CM所提供的Java API也是按照REST API那套來實現的,二者是保持一致的api
核心代碼以下:ide
public class IdcHostResource { private static final Logger LOGGER = LoggerFactory.getLogger(IdcHostResource.class); static RootResourceV18 apiRoot; // TODO... 寫死了,須要改進 static { apiRoot = new ClouderaManagerClientBuilder() .withHost("cm ip") .withPort(7180) .withUsernamePassword("user", "passwd") .build() .getRootV18(); } /** * 固定獲取Host的基本資源信息 */ public static List<IdcHostBasicInfo> getAllHostResource() { List<IdcHostBasicInfo> hosts = new ArrayList<IdcHostBasicInfo>(); HostsResourceV10 hostsResourceV10 = apiRoot.getHostsResource(); List<ApiHost> hostLists = hostsResourceV10.readHosts(DataView.SUMMARY).getHosts(); LOGGER.info("Total" + hostLists.size() + "Host"); for (ApiHost hostList : hostLists) { IdcHostBasicInfo host = formatHost(hostsResourceV10.readHost(hostList.getHostId())); LOGGER.info("Host Name:" + host.getHostName()); LOGGER.info("Host Health Summary:" + host.gethostHealthSummary()); LOGGER.info("Host Physical Memory:" + host.getTotalPhysMemBytes()); hosts.add(host); } return hosts; } public static IdcHostBasicInfo formatHost(ApiHost apiHost) { IdcHostBasicInfo idcHostBasicInfo = new IdcHostBasicInfo(); idcHostBasicInfo.sethostHealthSummary(apiHost.getHealthSummary().toString()); idcHostBasicInfo.setHostName(apiHost.getHostname()); idcHostBasicInfo.setTotalPhysMemBytes(apiHost.getTotalPhysMemBytes()); return idcHostBasicInfo; } /** * 經過tsquery來動態獲取對應的metrics info * * @param query * @param startTime * @param endTime * @return */ public static List<IdcMetricInfo> getHostMetrics(String query, String startTime, String endTime) throws ParseException { TimeSeriesResourceV11 timeSeriesResourceV11 = apiRoot.getTimeSeriesResource(); ApiTimeSeriesResponseList responseList = timeSeriesResourceV11.queryTimeSeries(query, startTime, endTime); List<ApiTimeSeriesResponse> apiTimeSeriesResponseList = responseList.getResponses(); List<IdcMetricInfo> metrics = formatApiTimeSeriesResponseList(apiTimeSeriesResponseList); return metrics; } public static List<IdcMetricInfo> formatApiTimeSeriesResponseList(List<ApiTimeSeriesResponse> apiTimeSeriesResponseList) throws ParseException { List<IdcMetricInfo> metrics = new ArrayList<IdcMetricInfo>(); DateUtils dateUtils = new DateUtils(); for (ApiTimeSeriesResponse apiTimeSeriesResponse : apiTimeSeriesResponseList) { List<MetricData> dataList = new ArrayList<MetricData>(); List<ApiTimeSeries> apiTimeSeriesResponseLists = apiTimeSeriesResponse.getTimeSeries(); for (ApiTimeSeries apiTimeSeries : apiTimeSeriesResponseLists) { LOGGER.info("query sql is: " + apiTimeSeries.getMetadata().getExpression()); IdcMetricInfo metric = new IdcMetricInfo(); metric.setMetricName(apiTimeSeries.getMetadata().getMetricName()); metric.setEntityName(apiTimeSeries.getMetadata().getEntityName()); metric.setStartTime(apiTimeSeries.getMetadata().getStartTime().toString()); metric.setEndTime(apiTimeSeries.getMetadata().getEndTime().toString()); for (ApiTimeSeriesData apiTimeSeriesData : apiTimeSeries.getData()) { MetricData data = new MetricData(); // 在Data中插入EntityName,避免重複數據的產生 data.seHostname(apiTimeSeries.getMetadata().getEntityName()); // CM默認獲得的時間格式爲 EEE MMM dd HH:mm:ss 'CST' yyyy,轉換時間格式爲 yyyy-MM-dd HH:mm:ss data.setTimestamp(dateUtils.parse(apiTimeSeriesData.getTimestamp().toString())); data.setType(apiTimeSeriesData.getType()); data.setValue(apiTimeSeriesData.getValue()); dataList.add(data); } metric.setData(dataList); metrics.add(metric); } } return metrics; }
注意:測試
代碼中涉及到的DateUtils須要本身去進行實現
經過這部分代碼能夠經過傳入tsquery的方式去獲取對應的idc集羣的metric信息;接下來的代碼咱們只須要經過ServiceImpl去實現對應的監控指標的獲取代碼便可
若是想經過cm api與spring boot整合的,這其中還會遇到2個問題:
依賴衝突問題,主要表如今jackson與cxf的衝突;經過排jar包的方式能夠解決大數據正則解析錯誤,該問題爲cm使用過程當中的一個坑,目前仍在排查當中,具體表現形式爲:ui
這裏面有個空格,所以在編譯的過程當中直接會報正則解析的錯誤;可是咱們能夠發如今cm 6.x的api版本中已經沒有這個問題了:
code
所以能夠直接升級api的版原本解決該問題,可是隨之帶來的問題就是與線上運行的cm版本不一致(線上的版本爲5.13.2),所以對於如何解決仍然須要思考;不過通過測試發現,使用cm 6.x版本的api,對於目前線上那套版本的相關指標並不影響orm