feat(queue): 增加非文本模型分布式准入队列

使用 PostgreSQL 统一同步与异步非文本任务的并发准入、持久化等待和 Worker 容量分配,并将生产 API 与独立 Worker 角色拆分。

补充策略管理、共享契约、OpenAPI、Kubernetes 双节点 Worker 清单及跨节点验收脚本;未默认启用任何生产 queue_size 策略。

已在原基线完成 Go、前端、迁移、Shell、Kustomize 与长任务容量验收;合入最新主干后将重新执行发布门禁。
This commit is contained in:
2026-07-29 16:15:43 +08:00
parent 2e5a90731b
commit 9e4fc7362d
55 changed files with 4565 additions and 237 deletions
+17 -19
View File
@@ -13,43 +13,41 @@ require_commands base64 jq node
restore_workers() {
cluster_ssh "$CLUSTER_NINGBO_HOST" 'bash -s' <<'REMOTE' || true
set -euo pipefail
k3s kubectl set env deployment/easyai-api-ningbo -n easyai \
AI_GATEWAY_ASYNC_QUEUE_WORKER_ENABLED=true >/dev/null
k3s kubectl set env deployment/easyai-api-hongkong -n easyai \
AI_GATEWAY_ASYNC_QUEUE_WORKER_ENABLED=true >/dev/null
k3s kubectl rollout status deployment/easyai-api-ningbo -n easyai --timeout=300s
k3s kubectl rollout status deployment/easyai-api-hongkong -n easyai --timeout=300s
k3s kubectl scale deployment/easyai-worker-ningbo -n easyai --replicas=1 >/dev/null
k3s kubectl scale deployment/easyai-worker-hongkong -n easyai --replicas=1 >/dev/null
k3s kubectl rollout status deployment/easyai-worker-ningbo -n easyai --timeout=300s
k3s kubectl rollout status deployment/easyai-worker-hongkong -n easyai --timeout=300s
REMOTE
}
trap restore_workers EXIT HUP INT TERM
cluster_ssh "$CLUSTER_NINGBO_HOST" 'bash -s' <<'REMOTE'
set -euo pipefail
k3s kubectl set env deployment/easyai-api-hongkong -n easyai \
AI_GATEWAY_ASYNC_QUEUE_WORKER_ENABLED=true >/dev/null
k3s kubectl rollout status deployment/easyai-api-hongkong -n easyai --timeout=300s
k3s kubectl set env deployment/easyai-api-ningbo -n easyai \
AI_GATEWAY_ASYNC_QUEUE_WORKER_ENABLED=false >/dev/null
k3s kubectl rollout status deployment/easyai-api-ningbo -n easyai --timeout=300s
k3s kubectl scale deployment/easyai-worker-hongkong -n easyai --replicas=1 >/dev/null
k3s kubectl rollout status deployment/easyai-worker-hongkong -n easyai --timeout=300s
k3s kubectl scale deployment/easyai-worker-ningbo -n easyai --replicas=0 >/dev/null
for _ in $(seq 1 60); do
pods=$(k3s kubectl get pods -n easyai \
-l app.kubernetes.io/name=easyai-api,easyai.io/site=ningbo \
-l app.kubernetes.io/name=easyai-worker,easyai.io/site=hongkong \
-o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
pod_count=$(wc -w <<<"$pods" | tr -d ' ')
if [[ $pod_count == 1 ]]; then
pod=$pods
worker_enabled=$(k3s kubectl get pod "$pod" -n easyai \
-o jsonpath='{.spec.containers[0].env[?(@.name=="AI_GATEWAY_ASYNC_QUEUE_WORKER_ENABLED")].value}')
process_role=$(k3s kubectl get pod "$pod" -n easyai \
-o jsonpath='{.spec.containers[0].env[?(@.name=="AI_GATEWAY_PROCESS_ROLE")].value}')
pod_ready=$(k3s kubectl get pod "$pod" -n easyai \
-o jsonpath='{.status.containerStatuses[0].ready}')
if [[ $worker_enabled == false && $pod_ready == true ]]; then
if [[ $process_role == worker && $pod_ready == true ]]; then
break
fi
fi
sleep 1
done
[[ ${pod_count:-0} == 1 && ${worker_enabled:-} == false && ${pod_ready:-} == true ]]
k3s kubectl logs "$pod" -n easyai | grep -q 'asynchronous queue worker disabled for this process'
[[ ${pod_count:-0} == 1 && ${process_role:-} == worker && ${pod_ready:-} == true ]]
[[ $(k3s kubectl get deployment easyai-api-ningbo -n easyai \
-o jsonpath='{.spec.template.spec.containers[0].env[?(@.name=="AI_GATEWAY_PROCESS_ROLE")].value}') == api ]]
[[ $(k3s kubectl get deployment easyai-worker-ningbo -n easyai \
-o jsonpath='{.status.readyReplicas}') == 0 ]]
curl -fsS http://10.77.0.1:31088/api/v1/readyz | grep -q '"ok":true'
curl -fsS http://10.77.0.2:31089/api/v1/readyz | grep -q '"ok":true'
REMOTE
@@ -98,7 +96,7 @@ query() {
}
attempted_by=$(query -c \
"SELECT attempted_by::text FROM river_job WHERE id=(SELECT river_job_id FROM gateway_tasks WHERE id='$task_id'::uuid);")
[[ $attempted_by == *easyai-api-hongkong* ]] || {
[[ $attempted_by == *easyai-worker-hongkong* ]] || {
echo "River attempted_by does not identify Hong Kong: $attempted_by" >&2
exit 1
}