quicklinks详解[三]
# 3.1.3 模板解析
# 3.1.3.1 页面链接渲染
在 Ambari 的 QuickLinks 模板渲染体系中,页面实际展示效果高度依赖于集群部署形态。不同部署模式下,QuickLinks 的分组、拼接与展示逻辑都会发生变化。 我们将以 Hadoop 的非 HA(单 NameNode)和 HA(多 NameNode)两种典型场景,完整还原页面生成流程与源码解析路径。
# Hadoop 非 HA 请求过程
在Hadoop 非 HA环境下,NameNode 组件仅部署在单节点,前端从后端 API 获取到的 hosts 只包含一个主机信息。
此时,前端代码会走进 setSingleHostLinks
方法,用于生成归属于单个主机的所有超链接入口。
hosts = [
{
componentName: "NAMENODE",
hostName: "centos1",
publicHostName: "centos1"
}
];
2
3
4
5
6
7
# 非 HA 页面展示效果
这种场景下,所有如 NameNode UI
、NameNode Logs
、NameNode JMX
等 QuickLinks
都会被渲染为“单主机分组”,全部归属 centos1
。
# Hadoop HA 请求结果
在Hadoop HA场景下,NameNode 组件同时部署在多台主机上(如 centos1
和 centos3
),API 返回的 hosts 为两个节点。
此时前端会自动分组,依次为每台主机渲染所有 QuickLinks,并调用 setMultipleHostLinks
方法,实现主机分组显示。
hosts = [
{
componentName: "NAMENODE",
hostName: "centos1",
publicHostName: "centos1"
},
{
componentName: "NAMENODE",
hostName: "centos3",
publicHostName: "centos3"
}
];
2
3
4
5
6
7
8
9
10
11
12
# HA 页面展示效果
页面最终会分成多组,每组归属于一个主机,内部包含全部服务 QuickLinks(如 UI、JMX、日志等),便于集群高可用运维下的节点切换与访问。
# 对比总结
部署形态 | QuickLinks 分组方式 | 页面效果 |
---|---|---|
非 HA | 所有链接归属单一主机 | 单主机分组,入口直观、简洁 |
HA | 链接按主机分组,分别展示 | 多主机分组,便于节点切换与问题定位 |
提示
无论哪种场景,QuickLinks 的拼接、占位符替换和可见性判断,全部由前端 JS 动态处理,确保页面时刻反映集群最新状态。
# QuickLinks 前端关键解析流程
页面最终链接的生成离不开一套严密的“模板+占位符”拼装机制。核心回调如下:
setQuickLinksSuccessCallback: function (response) {
var serviceName = this.get('content.serviceName');
var hosts = this.getHosts(response, serviceName);
// 检查是否配置了 QuickLinks,以及对应主机组件存在
var hasQuickLinks = this.hasQuickLinksConfig(serviceName, hosts);
var hasHosts = false;
var componentNames = hosts.mapProperty('componentName');
componentNames.forEach(function (_componentName) {
var component = App.MasterComponent.find().findProperty('componentName', _componentName)
|| App.SlaveComponent.find().findProperty('componentName', _componentName);
if (component) {
hasHosts = hasHosts || !!component.get('totalCount');
}
});
if (hasQuickLinks && (hasHosts || this.hasOverriddenHost())) {
this.set('showQuickLinks', true);
} else {
this.set('showNoLinks', true);
}
var isMultipleComponentsInLinks = componentNames.uniq().length > 1;
// 不同分组场景自动分派处理方法
if (hosts.length === 0 && !this.hasOverriddenHost()) {
this.setEmptyLinks();
} else if (hosts.length === 1 || isMultipleComponentsInLinks || this.hasOverriddenHost()) {
this.setSingleHostLinks(hosts, response);
} else if (this.get('masterGroups.length') > 1 || this.get('shouldSetGroupedLinks')) {
this.setMultipleGroupLinks(hosts);
} else {
this.setMultipleHostLinks(hosts);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- 判断条件严密:兼容了无主机、单主机、多主机、分组等所有场景
- 方法分派灵活:不同分组场景自动走不同拼装逻辑,保证 UI 适配所有拓扑
# 3.1.3.1 links 处理
# 页面 links 拼接机制
QuickLinks 的拼装本质上是将 JSON 模板中定义的 URL,占位符依次替换成实际参数(协议、主机名、端口等),最终生成可点击的跳转入口。
主要代码实现如下:
setSingleHostLinks: function setSingleHostLinks(hosts, response) {
var quickLinksConfig = this.getQuickLinksConfiguration(); // 取出配置模板
if (!Em.isNone(quickLinksConfig)) {
var quickLinks = [];
var configProperties = this.get('configProperties'); // 关联所有配置信息
var protocol = this.setProtocol(configProperties, quickLinksConfig.get('protocol'));
var links = Em.get(quickLinksConfig, 'links');
links.forEach(function (link) {
var isRelatedComponentInstalled = this.isRelatedComponentInstalled(link);
if (isRelatedComponentInstalled) {
var publicHostName = this.publicHostName(link, hosts, protocol);
if (publicHostName) {
if (link.protocol) {
protocol = this.setProtocol(configProperties, link.protocol);
}
var newItem = this.getHostLink(link, publicHostName, protocol, configProperties, response);
if (!Em.isNone(newItem)) {
quickLinks.push(newItem);
}
}
}
}, this);
this.set('quickLinks', quickLinks);
this.set('isLoaded', true);
} else {
this.set('quickLinks', []);
this.set('isLoaded', false);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# URL
占位符处理
URL 模板:如
%@://%@:%@
动态拼接:
var template = link.url; // "%@://%@:%@" newItem.url = template.fmt(protocol, host, linkPort);
1
2
占位符 | 替换参数 | 示例 |
---|---|---|
%@ | protocol | http /https |
%@ | host | centos1 |
%@ | linkPort | 50070 |
实际渲染效果:
http://centos1:50070
1
# site
属性与多配置文件支持
site
属性指定了参数查找的配置文件(如 hdfs-site)。- 支持 http/https 的不同 property 和默认值,兼容多协议场景。
- 代码会自动从 site 配置文件中查找对应属性,再用正则提取端口,确保链接始终指向有效入口。
# regex
的作用
典型配置:
"port": { "http_property": "dfs.namenode.http-address", "http_default_port": "50070", "regex": "\\w*:(\\d+)", "site": "hdfs-site" }
1
2
3
4
5
6提取逻辑:
var re = new RegExp(regexValue); var portValue = propertyValue.match(re); return portValue[1]; // 返回端口号
1
2
3例如
centos1:50070
匹配结果就是50070
,完全自动化提取。
# 3.1.4 QuickLinks 属性清单
QuickLinks JSON 配置的每个字段都有其独特含义,熟悉这些参数能帮助我们高效定制和排查页面超链接。
属性 | 说明 | 示例值 |
---|---|---|
name | 链接唯一标识,前端用于区分不同超链接。 | namenode_ui |
label | UI 展示名称,提升可用性和易读性。 | NameNode UI |
url | URL 模板,支持多参数占位符,需前端动态拼接。 | %@://%@:%@ |
component_name | 关联的组件名,对应 hosts 数组匹配。 | NAMENODE |
port | 端口参数,定义查找策略、正则、默认值等。 | 见下表 |
visible | 控制前端是否渲染该链接,便于灰度和分阶段上线。 | true |
# 3.1.4.1 Port 属性详细说明
属性 | 说明 | 示例值 |
---|---|---|
http_property | HTTP 模式端口号的配置属性名 | dfs.namenode.http-address |
http_default_port | HTTP 模式下的默认端口号 | 50070 |
https_property | HTTPS 模式下端口号的配置属性名 | dfs.namenode.https-address |
https_default_port | HTTPS 模式下的默认端口号 | 50470 |
regex | 用于从配置属性提取端口号的正则表达式 | \\w*:(\\d+) |
site | 该属性值所在的配置文件 | hdfs-site |
实用总结
- QuickLinks 的渲染流程高度自动化,适配单主机/多主机/HA 等复杂场景,支持所有主流大数据组件的可视化访问。
- 熟练掌握模板参数配置与占位符拼接,是实现平台高可用和可观测运维的必备技能。