09b04469eeb72b7b8531a8aa0a32b2a16f42b39f
\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\346\236\266\346\236\204\346\226\271\346\241\210\350\256\276\350\256\241\345\210\235\347\250\277.md
... | ... | @@ -1,8 +1,8 @@ |
1 | -### 分布式系统架构技术方案 |
|
1 | +## 分布式系统架构技术方案 |
|
2 | 2 | |
3 | -#### 1. 现状分析 |
|
3 | +### 1. 现状分析 |
|
4 | 4 | |
5 | -##### 1.1 引擎到 Sidecar 到 Dapr 的多次转发 |
|
5 | +#### 1.1 引擎到 Sidecar 到 Dapr 的多次转发 |
|
6 | 6 | |
7 | 7 | 当前架构中(引擎 --> sidecar(修改url中的域名) --> dapr --> app服务),引擎通过 Sidecar 进行URL 域名修改后,再转发到 Dapr。这种设计导致了两次不必要的网络转发,增加了延迟和复杂性,同时这些转发对应用并不透明,比如对stream流的支持。 |
8 | 8 | ```java |
... | ... | @@ -29,7 +29,7 @@ |
29 | 29 | } |
30 | 30 | ``` |
31 | 31 | |
32 | -##### 1.2 引擎转发逻辑问题 |
|
32 | +#### 1.2 引擎转发逻辑问题 |
|
33 | 33 | |
34 | 34 | 引擎的转发逻辑是:如果目标app在本地容器中,则直接处理;如果不在本地容器中,则转发请求。 |
35 | 35 | 然而,如果访问一个不存在的应用,则会导致死循环(业务中反馈的出现 loop call 问题),因为每个节点都觉得不在本容器内就转发,没有停止的条件。一般来说,路由应该是确定性的,如果app存在则访问,否则直接报错不存在。 |
... | ... | @@ -70,7 +70,7 @@ |
70 | 70 | } |
71 | 71 | ``` |
72 | 72 | |
73 | -##### 1.3 应用安装的复杂性 |
|
73 | +#### 1.3 应用安装的复杂性 |
|
74 | 74 | |
75 | 75 | 在当前架构中,应用安装过程由引擎完成一份部分, Sidecar 完成另一部分,需要相互协调和等待回调。这种设计增加了复杂性和不确定性。理想情况下,应用的安装和卸载应该由一个组件独立完成。 |
76 | 76 | 比如回调逻辑可能会因为异常出现死循环: |
... | ... | @@ -138,7 +138,7 @@ sidecar 回调,如果不成功会一直尝试: |
138 | 138 | } |
139 | 139 | ``` |
140 | 140 | |
141 | -1.4 内存同步遇到的问题 |
|
141 | +#### 1.4 内存同步遇到的问题 |
|
142 | 142 | |
143 | 143 | - 一致性 |
144 | 144 | |
... | ... | @@ -157,9 +157,9 @@ sidecar 回调,如果不成功会一直尝试: |
157 | 157 | 以上问题当确定网关也就是master节点的地位以后,就变得非常简单了。简单来说master节点永远是主节点,其他业务节点只是从节点,而且内存同步的发起方永远是master,那么master节点只需要把需要操作的内存信息以http请求方式广播给所有的从节点就可以了,http本身是同步且待ack确认的。 |
158 | 158 | |
159 | 159 | |
160 | -#### 2. 新的实现方案 |
|
160 | +### 2. 新的实现方案 |
|
161 | 161 | |
162 | -##### 2.1 使用网关进行统一管理 |
|
162 | +#### 2.1 使用网关进行统一管理 |
|
163 | 163 | |
164 | 164 | 网关服务可以通过固定的 service 名称(如 `master`)来实现统一管理,确保先启动并完成所有内置应用的表结构初始化、种子数据初始化等只需要一个容器一次性初始化任务。这些任务只需要一个容器执行,无需在所有容器中重复执行。 |
165 | 165 | |
... | ... | @@ -199,7 +199,7 @@ sidecar 回调,如果不成功会一直尝试: |
199 | 199 | |
200 | 200 | 这里应该插入架构图的,但是不知道咋插入 ₍ᐢ..ᐢ₎ todo |
201 | 201 | |
202 | -##### 2.2 MySQL 维护应用和容器服务的关系 |
|
202 | +#### 2.2 MySQL 维护应用和容器服务的关系 |
|
203 | 203 | |
204 | 204 | 在 MySQL 中维护app和其所在容器服务的关系。每个 Pod 中可在进程内缓存这些关系,并设置有效期(如 5 分钟)。如果缓存未过期但访问失败,则强制从 MySQL 读取,以确保数据的正确性。 |
205 | 205 | |
... | ... | @@ -247,7 +247,7 @@ public class WatchExample { |
247 | 247 | ``` |
248 | 248 | 通过 watch 服务变化,及时主动更新内存中的 service 和应用对应关系,确保数据的一致性和实时性。 |
249 | 249 | |
250 | -##### 2.3 安装和卸载应用的一致性 |
|
250 | +#### 2.3 安装和卸载应用的一致性 |
|
251 | 251 | |
252 | 252 | |
253 | 253 | 安装和卸载功能可以由一个独立的内置app管理和创建容器。为了确保一致性,可以采用以下策略: |
... | ... | @@ -337,7 +337,7 @@ public class GenericClientExample { |
337 | 337 | 可能有人会感觉容器的管理和维护,应该是属于运维层面的事情,不应该放到业务中来处理,确实是的,其实最佳做法还是按照业界的做法,编写operator来完成所有的容器操作,而且这个操作是一致的,尤其是再涉及到多个资源的情况,比如有service、deployment、configmap、pvc、secret等,如何保证创建、删除和修改这些资源的一致性呢? |
338 | 338 | k8s已经给出了答案,通过operaotr即可做到 https://kubernetes.io/zh-cn/docs/concepts/extend-kubernetes/operator/ 以及如何管理依赖和引用:https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/ |
339 | 339 | |
340 | -#### 3. 总结 |
|
340 | +### 3. 总结 |
|
341 | 341 | |
342 | 342 | 通过上述改进方案,可以解决当前架构中的多个问题: |
343 | 343 |