add: anowflake email kafka, refa: redis connectg

This commit is contained in:
wwweww
2026-02-25 01:16:13 +08:00
parent fdbcde13b2
commit 300058ad01
67 changed files with 3596 additions and 139 deletions
+266
View File
@@ -0,0 +1,266 @@
# Email Consumer Kafka 投递与日志验证实验手册
## 1. 实验目标
验证 `email-task` consumer 是否能正常消费 Kafka 消息,并在日志中打印消费内容。
本实验同时给出两种验证方式:
1. `kubectl logs` 直接查看 Pod 日志
2. Grafana + Loki 查看聚合日志
---
## 2. 实验前提
### 2.1 需要满足的运行状态
```bash
kubectl -n juwan get pods -l app=email-task
kubectl -n kafka get pods
kubectl -n monitoring get pods
```
预期:
- `email-task` 至少 1 个 Pod 为 `Running`
- Kafka 集群有可用 broker(如 `my-cluster-kafka-pool-0`
- `loki/promtail/grafana``Running`(若需要 Loki 验证)
### 2.2 本次实验使用的关键配置
来自 `app/email/mq/etc/email.yaml`
- Broker: `my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092`
- Topic: `email-task`
- Group: `email-consumer-group`
---
## 3. 实验步骤(详细)
## 步骤 1:确认 Topic 存在
### 目的
避免消息投递到不存在的 Topic,导致消费端无数据。
### 指令
```bash
kubectl -n kafka exec my-cluster-kafka-pool-0 -- \
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server my-cluster-kafka-bootstrap:9092 \
--list
```
### 预期结果
输出中包含:
- `email-task`
---
## 步骤 2:投递一条最小测试消息(纯文本)
### 目的
先验证链路通路(producer -> kafka -> consumer)是否正常,不引入 JSON 转义复杂度。
### 指令
```bash
kubectl -n kafka exec my-cluster-kafka-pool-0 -- /bin/bash -lc \
"printf 'test-email-message\\n' | \
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server my-cluster-kafka-bootstrap:9092 \
--topic email-task"
```
### 预期结果
命令正常返回(通常无额外输出)。
---
## 步骤 3:查看 consumer 日志(kubectl 直查)
### 目的
确认 consumer 实际收到消息并执行日志打印。
### 指令(回看最近日志)
```bash
kubectl -n juwan logs -l app=email-task --tail=120
```
### 指令(实时追踪)
```bash
kubectl -n juwan logs -l app=email-task -f --since=10m
```
### 预期日志示例
```text
Consume get message key: , value: test-email-message
```
说明:
- key 为空是正常的(本次 producer 未设置 key
- value 为投递内容,说明消费链路正常
---
## 步骤 4:投递业务消息(验证码 JSON)
### 目的
模拟真实业务 payload,验证 consumer 对业务消息格式的处理。
### 指令
```bash
kubectl -n kafka exec my-cluster-kafka-pool-0 -- /bin/bash -lc "cat <<'EOF' | \
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server my-cluster-kafka-bootstrap:9092 \
--topic email-task
{\"type\":\"verification_code\",\"email\":\"test@example.com\",\"code\":\"123456\",\"scene\":\"login\",\"expired_minutes\":5}
EOF"
```
### 预期结果
- producer 正常返回
- `email-task` 日志可看到包含 JSON 的消费日志
---
## 步骤 5:投递业务消息(活动通知 JSON)
### 目的
验证另一类业务消息(活动通知)通路。
### 指令
```bash
kubectl -n kafka exec my-cluster-kafka-pool-0 -- /bin/bash -lc "cat <<'EOF' | \
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server my-cluster-kafka-bootstrap:9092 \
--topic email-task
{\"type\":\"activity_notice\",\"email\":\"test@example.com\",\"title\":\"春季活动\",\"content\":\"满100减20\",\"activity_id\":\"A20260225\"}
EOF"
```
### 预期结果
- producer 正常返回
- consumer 日志出现活动消息内容
---
## 步骤 6:使用 Loki/Grafana 验证(可选)
### 目的
确认日志采集链路(Promtail -> Loki -> Grafana)正常,便于后续线上排查。
### 6.1 打开 Grafana
```bash
kubectl port-forward -n monitoring svc/grafana 3000:3000
```
浏览器:`http://localhost:3000`
### 6.2 在 Explore 中查询
使用 Loki 数据源,输入:
```logql
{job="kubernetes-pods", namespace="juwan", app="email-task"} |= "Consume get message"
```
若没有结果:
1. 把时间范围调大到 `Last 6 hours`/`Last 24 hours`
2. 放宽查询条件:
```logql
{job="kubernetes-pods", namespace="juwan", pod=~"email-task-.*"}
```
---
## 4. 一键复现实验命令(顺序执行)
```bash
# 1) 查看 topic
kubectl -n kafka exec my-cluster-kafka-pool-0 -- /opt/kafka/bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9092 --list
# 2) 发测试消息
kubectl -n kafka exec my-cluster-kafka-pool-0 -- /bin/bash -lc "printf 'test-email-message\\n' | /opt/kafka/bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9092 --topic email-task"
# 3) 看 consumer 日志
kubectl -n juwan logs -l app=email-task --tail=120
```
---
## 5. 常见问题与处理
### 问题 1:发消息命令报引号/EOF错误
现象:`unexpected EOF while looking for matching`
原因:Shell 引号转义不正确。
处理:
- 先用纯文本消息验证链路
- JSON 使用 here-doc`cat <<'EOF'`)方式,避免转义混乱
### 问题 2:发了消息但 consumer 无日志
排查顺序:
1. `email-task` 是否 Running
2. Topic 是否正确(`email-task`
3. consumer group 是否一致(`email-consumer-group`
4. 查看 Pod 实时日志(`-f`
5. 若只看 Loki,请放大时间窗口并放宽标签条件
### 问题 3Loki 查不到但 kubectl logs 能看到
说明业务正常,问题在日志采集查询链路:
- 检查 Promtail target 是否 ready
- 检查 Loki 查询标签/时间范围
- 参考 `docs/loki-log-troubleshooting.md`
---
## 6. 实验结论判定标准
满足以下任一即可判定消费链路可用:
1. `kubectl logs` 出现:`Consume get message ...`
2. Grafana Loki 查询出现对应消费日志
若两者都出现,说明:
- Kafka 投递正常
- Consumer 消费正常
- 日志采集与检索链路正常
---
## 7. 关联文档
- Loki 使用:`docs/loki-usage-guide.md`
- Loki 排错:`docs/loki-log-troubleshooting.md`
- Email 部署排错:`docs/email-task-deployment-troubleshooting.md`
@@ -0,0 +1,147 @@
# Email Task 部署故障排查与修复记录
## 1. 问题现象
部署 `email-task` 时出现调度失败:
```text
Warning FailedScheduling 0/1 nodes are available: 1 Insufficient memory.
no new claims to deallocate, preemption: 0/1 nodes are available:
1 No preemption victims found for incoming pod.
```
表现为:
- `Deployment` 期望副本无法全部就绪
- `Pod` 长时间 `Pending`
---
## 2. 排查思路
按以下顺序排查:
1. **看部署配置是否过高请求**`requests/limits` + `replicas`
2. **看节点可分配资源和已分配资源**(确认是否真的是内存不足)
3. **看滚动策略是否会额外拉起新 Pod**`maxSurge` 可能放大内存压力)
4. **看容器健康检查是否匹配服务类型**(任务型服务不一定监听端口)
---
## 3. 关键排查命令
### 3.1 查看节点可分配资源
```powershell
kubectl get nodes -o custom-columns=NAME:.metadata.name,ALLOCATABLE_CPU:.status.allocatable.cpu,ALLOCATABLE_MEM:.status.allocatable.memory
```
### 3.2 查看部署与 Pod 状态
```powershell
kubectl -n juwan get deploy email-task -o wide
kubectl -n juwan get pods -l app=email-task -o wide
kubectl -n juwan describe pod -l app=email-task
```
### 3.3 查看节点资源分配占比
```powershell
kubectl describe node minikube
```
关注输出中的 `Allocated resources`
- `memory requests` 已接近节点上限(本次约 97%
### 3.4 查看部署策略与探针配置
```powershell
kubectl -n juwan get deploy email-task -o yaml
kubectl -n juwan logs deploy/email-task --tail=120
```
---
## 4. 根因分析
本次是**组合问题**
1. **内存请求过高 + 副本过多**
- 原始配置:`replicas=3`
- 每个 Pod 请求 `memory=512Mi`
- 单节点场景下,叠加现有业务后无法继续调度
2. **滚动更新默认 `maxSurge=25%`**
- 更新时可能额外起新 Pod,进一步触发内存不足
3. **探针不匹配服务行为**
- 原配置为 `tcpSocket:8080` 探针
- 实际 `email-task` 是任务型服务,日志显示启动后并未提供该端口服务
- 导致 `Readiness/Liveness` 持续失败
---
## 5. 修复方案
仅修改文件:
- `deploy/k8s/service/email/email.yaml`
### 5.1 降低资源请求与副本基线
- `replicas: 3 -> 1`
- `requests.cpu: 500m -> 100m`
- `requests.memory: 512Mi -> 128Mi`
- `limits.cpu: 1000m -> 500m`
- `limits.memory: 1024Mi -> 512Mi`
### 5.2 调整 HPA 基线与上限
- 两个 HPACPU / Memory)统一:
- `minReplicas: 3 -> 1`
- `maxReplicas: 10 -> 3`
### 5.3 调整滚动发布策略
- `strategy.rollingUpdate.maxSurge: 0`
- `strategy.rollingUpdate.maxUnavailable: 1`
目的:避免滚动期间额外拉起 Pod 造成瞬时内存不足。
### 5.4 移除不适配的 8080 TCP 探针
移除:
- `readinessProbe.tcpSocket:8080`
- `livenessProbe.tcpSocket:8080`
---
## 6. 修复执行命令
```powershell
kubectl apply -f deploy/k8s/service/email/email.yaml
kubectl -n juwan rollout restart deploy/email-task
kubectl -n juwan rollout status deploy/email-task --timeout=180s
kubectl -n juwan get pods -l app=email-task -o wide
kubectl -n juwan describe pods -l app=email-task | Select-String -Pattern 'FailedScheduling|Unhealthy|Warning|Events|Node:'
```
---
## 7. 修复结果
- `Deployment` 滚动成功
- 新 Pod 成功调度并 `Running`
- 无新的 `FailedScheduling``Unhealthy` 事件
---
## 8. 后续建议
1. 若要恢复多副本,先按节点容量逐步上调(建议先 2 副本并观测)。
2. 为任务型服务设计更合适的健康检查方式:
- 可考虑 `exec` 探针或业务自检端点。
3. 在单节点开发环境中统一降低默认 `requests`,防止多个服务叠加后调度失败。
4. 如需高可用,建议扩容节点而不是仅依赖压缩资源。
+216
View File
@@ -0,0 +1,216 @@
# Loki 无日志排查与修复手册
## 背景
现象:Grafana Explore 使用 Loki 数据源查询 `{job="kubernetes-pods"}` 时无结果,页面提示 `No logs found`
影响:日志链路不可用,无法按服务排查线上问题。
链路目标:
- Promtail 采集 Kubernetes Pod 日志
- Loki 存储与检索日志
- Grafana 查询展示日志
---
## 一、排查思路
本次按“组件健康 -> 采集发现 -> 文件可读 -> 入库验证 -> 查询验证”的顺序排查。
### 1) 确认监控组件健康
先确认 Promtail/Loki/Grafana 是否都在 Running,避免在异常状态下排查配置。
### 2) 判断是“没采到”还是“没查到”
通过 Promtail `/targets``/service-discovery` 页面确认是否存在 active target。
-`0/0``0/1 unready`,说明采集端有问题
- 若 target 正常但 Loki 无数据,再看推送或查询标签
### 3) 检查 Promtail 能否访问节点日志文件
重点确认:
- `/var/log/pods` 是否可见
- 采集路径是否匹配
- 是否存在大量 `stat ... no such file or directory`
### 4) 直连 Loki API 验证是否入库
绕过 Grafana,直接访问 Loki API。
- 若 API 无数据,问题在 Promtail 采集/推送链路
- 若 API 有数据,问题在 Grafana 查询条件、时间范围或标签
---
## 二、根因分析
本次属于“Promtail 侧采集链路不完整”,主要问题如下:
1. Kubernetes SD 目标未生效(Promtail targets 显示 `kubernetes-pods (0/0)`)。
2. 即使加入静态采集,目标一度 `0/1 unready`
3. `/var/log/pods` 下日志多为符号链接,真实目标在 `/var/lib/docker/containers`
4. Promtail 容器未挂载 `/var/lib/docker/containers`,导致大量 `stat ... no such file or directory`
5. 标签维度不足,不便于按业务服务名筛选日志。
---
## 三、修复思路
### 1) 强化 Promtail 权限与发现能力
`deploy/k8s/monitoring/promtail.yaml` 中:
- 补充 RBAC 资源权限:
- `nodes`
- `pods`
- `pods/log`
- `services`
- `endpoints`
- `namespaces`
### 2) 增加静态采集兜底
`scrape_configs` 中新增 `kubernetes-pods-static`,路径:
- `/var/log/pods/*/*/*.log`
用于在 Kubernetes SD 临时失效时仍能采集日志。
### 3) 修复宿主机日志访问链路
Promtail DaemonSet 增加:
- `securityContext.runAsUser: 0`
- `securityContext.runAsGroup: 0`
- 挂载 `hostPath: /var/lib/docker/containers`
并挂载到容器内同路径只读。
### 4) 完善标签体系,支持按服务筛选
新增/保留标签:
- `namespace`
- `pod`
- `container`
- `app`
静态采集通过 `pipeline_stages``filename` 解析标签,并从 `pod` 生成 `app`(去除滚动后缀)。
---
## 四、关键变更文件
- `deploy/k8s/monitoring/promtail.yaml`
本次 Loki 主配置与 Grafana 数据源无需改动,核心修复集中在 Promtail 采集侧。
---
## 五、排查与修复命令清单
> 以下命令均在项目根目录执行。
### 1) 组件状态检查
```powershell
kubectl get pods -n monitoring -o wide
kubectl get svc -n monitoring
kubectl logs -n monitoring -l app=promtail --tail=120
kubectl logs -n monitoring -l app=loki --tail=80
```
### 2) Promtail 文件系统与配置检查
```powershell
$pod=(kubectl get pod -n monitoring -l app=promtail -o jsonpath='{.items[0].metadata.name}')
kubectl exec -n monitoring $pod -- sh -c "ls -ld /var/log /var/log/pods /var/log/containers"
kubectl exec -n monitoring $pod -- sh -c "find /var/log/pods -name '*.log' | head -n 20"
kubectl exec -n monitoring $pod -- sh -c "cat /etc/promtail/promtail.yaml"
kubectl exec -n monitoring $pod -- sh -c "cat /run/promtail/positions.yaml | head -n 120"
```
### 3) Promtail Web 诊断页(targets / service-discovery
```powershell
$pod=(kubectl get pod -n monitoring -l app=promtail -o jsonpath='{.items[0].metadata.name}')
$job=Start-Job -ScriptBlock { param($p) kubectl port-forward -n monitoring pod/$p 19080:9080 } -ArgumentList $pod
Start-Sleep -Seconds 3
Invoke-WebRequest -UseBasicParsing http://127.0.0.1:19080/targets | Select-Object -ExpandProperty Content
Invoke-WebRequest -UseBasicParsing http://127.0.0.1:19080/service-discovery | Select-Object -ExpandProperty Content
Stop-Job $job -ErrorAction SilentlyContinue
Remove-Job $job -Force -ErrorAction SilentlyContinue
```
### 4) RBAC 实测
```powershell
kubectl auth can-i list pods --as=system:serviceaccount:monitoring:promtail --all-namespaces
kubectl auth can-i watch pods --as=system:serviceaccount:monitoring:promtail --all-namespaces
kubectl auth can-i list namespaces --as=system:serviceaccount:monitoring:promtail
kubectl auth can-i get nodes --as=system:serviceaccount:monitoring:promtail
```
### 5) 应用修复并滚动重启 Promtail
```powershell
kubectl apply -f deploy/k8s/monitoring/promtail.yaml
kubectl rollout restart ds/promtail -n monitoring
kubectl rollout status ds/promtail -n monitoring --timeout=120s
kubectl logs -n monitoring -l app=promtail --tail=120
```
### 6) Loki API 直连验证
```powershell
$job=Start-Job -ScriptBlock { kubectl port-forward -n monitoring svc/loki 13100:3100 }
Start-Sleep -Seconds 3
Invoke-WebRequest -UseBasicParsing "http://127.0.0.1:13100/loki/api/v1/query_range?query=%7Bjob%3D%22kubernetes-pods%22%7D&limit=10" | Select-Object -ExpandProperty Content
Stop-Job $job -ErrorAction SilentlyContinue
Remove-Job $job -Force -ErrorAction SilentlyContinue
```
### 7) 按 app 标签验证
```powershell
$job=Start-Job -ScriptBlock { kubectl port-forward -n monitoring svc/loki 13100:3100 }
Start-Sleep -Seconds 3
Invoke-WebRequest -UseBasicParsing "http://127.0.0.1:13100/loki/api/v1/query_range?query=%7Bjob%3D%22kubernetes-pods%22%2Capp%3D~%22.+%22%7D&limit=5" | Select-Object -ExpandProperty Content
Stop-Job $job -ErrorAction SilentlyContinue
Remove-Job $job -Force -ErrorAction SilentlyContinue
```
---
## 六、Grafana 查询建议
建议先放大时间范围(Last 6 hours / Last 24 hours),再逐步收敛:
```logql
{job="kubernetes-pods"}
{job="kubernetes-pods", namespace="juwan"}
{job="kubernetes-pods", app="user-rpc"}
{job="kubernetes-pods", app=~"user-rpc|snowflake|email-mq"} |= "error"
```
---
## 七、后续优化建议
1. 当前 Loki 使用 `emptyDir`,重建后数据会丢失;生产建议改 PVC 持久化。
2. 可以补充 Promtail 的 `drop` 规则,减少噪音日志(如健康检查日志)。
3. 建议在 Grafana 中预置业务 Dashboard 与告警规则(按 app + error rate)。
---
## 八、结论
本次无日志的核心问题不在 Loki 或 Grafana,而在 Promtail 采集链路:
- 发现目标不稳定 + 日志文件符号链接目标未挂载
完成上述修复后,已可通过 Loki API 查到日志,并支持按 `app` 维度查询。
+174
View File
@@ -0,0 +1,174 @@
# Loki 使用指南(日志查看)
本文说明在当前项目中如何使用 Loki 查看 Kubernetes 日志,包括 Grafana 查询、LogQL 常用语句、命令行验证与常见排错。
---
## 1. 日志链路说明
当前日志链路:
- Promtail 采集节点日志文件
- Loki 存储与检索日志
- Grafana 作为查询与展示入口
相关配置文件:
- `deploy/k8s/monitoring/promtail.yaml`
- `deploy/k8s/monitoring/loki.yaml`
- `deploy/k8s/monitoring/grafana.yaml`
---
## 2. 快速开始(Grafana 查看日志)
### 步骤 1:确认监控组件运行
```bash
kubectl get pods -n monitoring
```
至少应看到 `promtail``loki``grafana``Running`
### 步骤 2:打开 Grafana
```bash
kubectl port-forward -n monitoring svc/grafana 3000:3000
```
浏览器打开:`http://localhost:3000`
默认账号密码(按现有配置):
- 用户名:`admin`
- 密码:`change-me`
### 步骤 3:进入 Explore 查询
- 左侧菜单进入 **Explore**
- 数据源选择 **Loki**
- 时间范围建议先设为 **Last 6 hours****Last 24 hours**
- 输入 LogQL 查询并点击 **Run query**
---
## 3. 常用 LogQL 查询语句
### 3.1 全量日志
```logql
{job="kubernetes-pods"}
```
### 3.2 按命名空间过滤
```logql
{job="kubernetes-pods", namespace="juwan"}
```
### 3.3 按服务(app 标签)过滤
```logql
{job="kubernetes-pods", app="user-rpc"}
```
### 3.4 多服务联合过滤
```logql
{job="kubernetes-pods", app=~"user-rpc|snowflake|email-mq"}
```
### 3.5 按容器名过滤
```logql
{job="kubernetes-pods", container="user-rpc"}
```
### 3.6 关键字过滤(错误日志)
```logql
{job="kubernetes-pods", namespace="juwan"} |= "error"
```
### 3.7 多关键字正则过滤
```logql
{job="kubernetes-pods", namespace="juwan"} |~ "(error|panic|fatal|timeout)"
```
### 3.8 统计最近 5 分钟错误量(按 app)
```logql
sum by (app) (count_over_time({job="kubernetes-pods"} |~ "(?i)error|panic|fatal" [5m]))
```
---
## 4. 不经过 Grafana 的直连验证(Loki API
用于区分“Grafana 查询问题”与“日志未入库问题”。
### 4.1 端口转发 Loki
```bash
kubectl port-forward -n monitoring svc/loki 3100:3100
```
### 4.2 查询是否有流数据
```bash
curl "http://127.0.0.1:3100/loki/api/v1/query_range?query={job=\"kubernetes-pods\"}&limit=10"
```
### 4.3 查询 app 标签流
```bash
curl "http://127.0.0.1:3100/loki/api/v1/query_range?query={job=\"kubernetes-pods\",app=~\".+\"}&limit=10"
```
如果 API 返回 `result` 非空,说明 Loki 已正常入库。
---
## 5. 常见问题与处理
### 问题 1Grafana 显示 No logs found
建议按顺序检查:
1. 时间范围是否太短(先调大到 6h/24h)
2. 查询标签是否过窄(先用 `{job="kubernetes-pods"}`
3. Promtail 是否正常运行并有 target
4. Loki API 是否能直接查到数据
### 问题 2Promtail 有 Running 但仍无日志
重点检查:
- `promtail` targets 是否 `ready`
- 是否存在 `stat ... no such file or directory`
- 是否挂载日志目录(`/var/log``/var/lib/docker/containers`
- 是否有足够 RBAC 权限(pods/nodes/namespaces 等)
### 问题 3:查不到某个服务日志
建议检查:
- 该服务 pod 是否在运行并产生日志
- `namespace``app` 过滤条件是否正确
- 先用 `namespace` 过滤,再逐步加 `app``container` 条件
---
## 6. 推荐查询习惯
1. 先粗后细:全量 -> namespace -> app -> container -> 关键字
2. 先看时间范围:避免默认 1h 漏查
3. 遇到空结果先用 Loki API 验证入库
4. 保存常用查询到 Grafana Dashboard,便于团队复用
---
## 7. 参考
- Loki 故障排查文档:`docs/loki-log-troubleshooting.md`