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 |