\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