网站注册界面,网站目录管理模版,个人网站推广 公司,wordpress手机端网站模板背景
在《分布式领域扩展点设计稿》一文中#xff0c;我们提到针对业务横向扩展点和纵向扩展点的编排能力。
那有这样的一种场景#xff1a;针对于一次会话#xff0c;同时会调很多外部服务#xff0c;同时这些RPC服务会有多种直接或间接的关系#xff0c;是否有更高效的…背景
在《分布式领域扩展点设计稿》一文中我们提到针对业务横向扩展点和纵向扩展点的编排能力。
那有这样的一种场景针对于一次会话同时会调很多外部服务同时这些RPC服务会有多种直接或间接的关系是否有更高效的方式能够让我们的一次会话时间变得更高效同时也能够保证系统的相对稳定性呢
设计思想
如果开发者在设计之初对于领域边界以及子域能力划分比较清晰那我们编排的业务扩展点就不会杂乱无章。
在SpringBoot启动时伴随着IOC容器的初始化领域扩展点容器也随之完成全量向量视图初始化、向量深度视图初始化、拓扑排序之后的容器初始化。
基于动态线程池思想可以通过扩展点容器中的编排任务动态调整线程池根据拓扑排序后的结果异步执行编排的任务完成召回、过滤以及核心业务逻辑。
设计图 详细设计
容器初始化时从云端配置中心拉取扩展点编排配置文件本地编排配置文件可以做兜底也可以调节两者权重拿到编排数据源之后渲染本地向量广度视图以及向量深度视图通过Kahn算法将两个视图清洗成拓扑排序之后的容器通过权衡算法初始化动态线程池并预热核心线程将上述操作数据上传到我们的扩展点监控中心通过监控水位线可动态配置线程池相关核心参数当一次会话开始时会通过拓扑排序并发去执行扩展点任务通过向量视图可以针对所有扩展点做召回和过滤处理
核心算法伪代码
/*** Kahn算法** author issavior*/
public class KahnTopologicalSort {/*** 向量广度视图*/private final MapInteger, ListInteger adjList new HashMap();/*** 向量深度视图*/private final MapInteger, Integer inDegree new HashMap();/*** 拓扑排序结果*/private final ListInteger topoOrder new ArrayList();/*** 渲染向量视图和向量深度** param u 向量头* param v 向量尾*/public void addEdge(int u, int v) {// 渲染视图adjList.putIfAbsent(u, new ArrayList());adjList.get(u).add(v);// 更新入度 inDegree.put(v, inDegree.getOrDefault(v, 0) 1);inDegree.putIfAbsent(u, 0);}/*** 拓扑排序** return 业务节点顺序*/public ListInteger topologicalSort() {QueueInteger queue new LinkedList();// 将所有入度为0的节点加入队列 for (Map.EntryInteger, Integer entry : inDegree.entrySet()) {if (entry.getValue() 0) {queue.offer(entry.getKey());}}while (!queue.isEmpty()) {int current queue.poll();topoOrder.add(current);// 遍历当前节点的所有邻接点 for (int neighbor : adjList.getOrDefault(current, Collections.emptyList())) {// 减少邻接点的入度 int newInDegree inDegree.get(neighbor) - 1;inDegree.put(neighbor, newInDegree);// 如果邻接点的入度变为0则加入队列 if (newInDegree 0) {queue.offer(neighbor);}}}// 检查是否所有节点都被访问过若为有环图初始化报错if (topoOrder.size() ! inDegree.size()) {throw new IllegalStateException(Graph has a cycle and cannot be topologically sorted.);}return topoOrder;}
}