我是靠谱客的博主 忧虑发带,这篇文章主要介绍cat服务端获取路由列表原理解析源码分析总结,现在分享给大家,希望可以做个参考。

Cat客户端上报消息时会先从服务端拉取路由列表。请求URL如:http://127.0.0.1:2281/cat/s/router?domain=strict-kevin-dubbo-test&ip=10.10.135.118&op=json。服务端由com.dianping.cat.system.page.router.Handler类来负责处理请求。

源码分析

请求处理入口,Handler#handleOutbound()方法。

复制代码
1
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
33
@Override @OutboundActionMeta(name = "router") public void handleOutbound(Context ctx) throws ServletException, IOException { Model model = new Model(ctx); Payload payload = ctx.getPayload(); Action action = payload.getAction(); @1 Date start = payload.getDate(); Date end = new Date(start.getTime() + TimeHelper.ONE_DAY); RouterConfig report = m_reportService.queryReport(Constants.CAT, start, end); @2 String domain = payload.getDomain(); switch (action) { case API: String routerInfo = buildRouterInfo(domain, report); model.setContent(routerInfo); break; case JSON: KVConfig config = new KVConfig(); Map<String, String> kvs = config.getKvs(); kvs.put("routers", buildRouterInfo(domain, report)); @3 kvs.put("sample", buildSampleInfo(domain)); @4 model.setContent(new JsonBuilder().toJson(config)); break; case MODEL: if (report != null) { model.setContent(report.toString()); } } ctx.getHttpServletResponse().getWriter().write(model.getContent()); }

代码@1:获取的action就是URL中op的值,这里是json。

代码@2:从dailyreport表中查询每日的router配置信息。

代码@3:构建router信息。

代码@4:构建sample(抽样)信息。

构建router信息

复制代码
1
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
private String buildRouterInfo(String domain, RouterConfig report) { Domain domainConfig = m_configManager.getRouterConfig().findDomain(domain); // @1 if (domainConfig == null || domainConfig.getServers().isEmpty()) {// @2 if (report != null) { // @3 Domain d = report.findDomain(domain); // @4 String str = null; if (d == null) { m_configManager.getRouterConfig().getDefaultServers(); // @5 List<Server> servers = m_configManager.queryServersByDomain(domain); // @6 str = buildServerStr(servers); } else { List<Server> servers = d.getServers(); str = buildServerStr(servers);// @7 } return str; } else { List<Server> servers = m_configManager.queryServersByDomain(domain); return buildServerStr(servers); // @8 } } else { return buildServerStr(domainConfig.getServers()); // @9 } }

代码@1:获取指定应用的路由信息。RouterConfigManager类会在初始化的时候查询config表,加载key为routerConfig的路由配置信息。格式如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?> <router-config backup-server="127.0.0.1" backup-server-port="2280"> <default-server id="127.0.0.1" weight="1.0" port="2280" enable="true"/> <default-server id="10.9.58.58" weight="1.0" port="2280" enable="true"/> <default-server id="10.9.25.34" weight="1.0" port="2280" enable="true"/> <domain id="strict-kevin-dubbo-test" sample="1.0"> <server id="10.9.25.34" port="2280" weight="1.0"/> <server id="10.9.25.35" port="2280" weight="2.0"/> <server id="10.9.25.36" port="2280" weight="3.0"/> </domain> </router-config>

用户可以配置默认的路由信息,也可以为特定的应用配置自己特有的路由信息。比如strict-kevin-dubbo-test就有自己的路由列表信息。

代码@2,@3,@4:如果没有为该应用配置特定的路由列表,并且当日router报表不为空,则从router报表中获取该应用的路由列表。

代码@5:如果当日的router报表中没有配置特定应用的路由信息,就获取配置的默认的router信息(信息)。

代码@6:根据应用名查询router信息。

代码@7:如果当日的router报表中有配置该应用的信息,则构建响应结果并返回。

代码@8:如果当日router报表不存在,则查询config表的router信息并返回。

代码@9:如果config表中配置了该应用的路由信息,则返回响应。

根据应用查询路由列表

复制代码
1
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
public List<Server> queryServersByDomain(String domain) { Domain domainConfig = m_routerConfig.findDomain(domain);// @1 List<Server> result = new ArrayList<Server>(); if (domainConfig == null || domainConfig.getServers().isEmpty()) { List<Server> servers = queryEnableServers(); // @2 int length = servers.size(); int hashCode = domain.hashCode(); if (length > 0) { for (int i = 0; i < 2; i++) { int index = Math.abs((hashCode + i)) % length; addServerList(result, servers.get(index)); // @3 } } addServerList(result, queryBackUpServer()); // @4 } else { for (Server server : domainConfig.getServers()) { result.add(server); // @5 } } return result; }

代码@1:从config表的路由配置中拉取该应用的配置信息。

代码@2:如果该应用没有配置路由信息,则查询所有默认的可用的(enable为true)路由列表。

代码@3:计算domain的hashcode,然后从路由列表中取出两个server添加到路由列表。

代码@4:添加备用server作为路由节点( backup-server配置的值)。

代码@5:如果该应用配置了路由信息,则添加到路由列表并返回。

总结

为了更直观地理解服务端的查询流程,下面给出上述代码的流程图。
在这里插入图片描述

最后

以上就是忧虑发带最近收集整理的关于cat服务端获取路由列表原理解析源码分析总结的全部内容,更多相关cat服务端获取路由列表原理解析源码分析总结内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部