首页
关于
Search
1
同步本地Markdown至Typecho站点
88 阅读
2
微服务
41 阅读
3
苍穹外卖
32 阅读
4
JavaWeb——后端
25 阅读
5
消息队列MQ
20 阅读
后端学习
项目
杂项
科研
论文
默认分类
登录
找到
12
篇与
杂项
相关的结果
2025-10-29
Cursor使用
Cursor 编辑器界面 ┌────────────────────────────────────────────┐ │ 顶部菜单栏(File / 编辑 / 选择 / 查看...)│ ├────────────────────────────────────────────┤ │ 左侧侧边栏(文件树 / 项目 / Git 等) │ ├────────────────────────────────────────────┤ │ 中间主编辑区(代码编辑) │ ├────────────────────────────────────────────┤ │ 右侧 AI 面板(Cursor 智能助手 / Chat) │ ├────────────────────────────────────────────┤ │ 底部状态栏(分支 / 文件类型 / 行列信息等) │ └────────────────────────────────────────────┘ 如何使用 Cursor 的 AI 功能 功能 作用 快捷键(默认) 🧠 Inline Edit 选中一段代码 → Ctrl + K(或右键 “Ask Cursor”)→ 输入自然语言指令(如“优化正则表达式”) Ctrl + K 🤖 Agent 面板 打开一个“聊天窗口”,直接和 Cursor 对话(如“帮我写个登录验证函数”) Ctrl + I ✨ Tab 补全 在代码中输入时,Cursor 自动预测后续内容 Tab 🔁 重新生成建议 当灰色提示出现但不理想时,按 `Alt + ``(或右键 “Regenerate”) `Alt + `` 选择一段代码+CTRL+K 修改指定的代码,直接在代码编辑区弹出修改窗口调用大模型。CTRL+ENTER 或者鼠标点击 应用修改 CTRL+N 或者 **鼠标点击 **拒绝修改 CTRL+I 1)图中设置的Auto表示自动选择模型; 2)@ 可以添加文件、文件夹到当前对话上下文,如果你在代码编辑区选择一段代码再 CTRL+I 或者 CTRL+L,也会自动将它添加进来。还可以直接拖拽资源管理器中的文件到AI对话框中。 3)+Browser 模式可以让模型看到整个项目文件 任务 你可以直接问 Cursor 找函数定义 “verifyPassword 函数定义在哪个文件?” 查找引用 “verifyCode 被调用了多少次?” 理解架构 “帮我总结整个项目的模块结构。” 改代码 “把所有 JS 文件里的 var 改成 let。” 生成文档 “根据这个项目代码生成一份 README。” 4)对话模式 Agent模式,默认的对话模式,功能最全,AI 不仅能回答,还会“主动思考、规划和执行”。可以理解为:“帮我干活”的模式。 Plan 模式,它可以浏览整个项目文件,但不会直接改代码,而是会:把你的需求拆分成多个步骤;告诉你“下一步该干什么”;有时生成一份修改计划或脚本方案。 Ask 模式:问答模式,和网页版使用大模型一样。 TAB 一般注释起手,如果出现灰色预测文字时,直接 Tab 就能接受 AI 自动补全 ,按ESC可以拒绝这个建议;否则就是普通的缩进。 触发逻辑 传统 IDE(比如 VS Code、IntelliJ) 的补全是词法或语法级触发: 你输入 “pri” → 提示 “print()”; 它只是基于关键字匹配。 而 Cursor 的补全 是“语义级”的: AI 根据上下文 推断你下一步可能在做什么。 它会综合考虑: 当前光标前后的代码; 注释 / 函数签名; 文件名; 项目中的其他定义; 甚至最近你在这个 Tab 里做的事。 阶段 触发动作 AI 响应 检测阶段 监听输入变化(按键、换行、注释等) 分析上下文语义树(AST) 预测阶段 生成“意图向量” 模型推断用户下一步目标 展示阶段 在光标后显示灰色 ghost text 等待你按 Tab 接受 触发时机 类型 触发条件 示例 行为 函数触发 输入 function / def function check... 预测参数和函数体 控制语句触发 输入 if / for 等 if (phone) 预测条件或逻辑块 注释触发 输入 //、#、/** // 校验邮箱格式 按注释生成实现 模板触发 class / import / try class User 预测类体、导入内容 上下文模仿 类似已有代码块 第二个函数定义 模仿风格 文件结构触发 同名模块、utils utils. 补出函数名 空行预测 新行、缩进后 空一行 猜测下一个合逻辑语句 Index&Docs Codebase Indexing(代码索引): Cursor 会扫描整个项目文件夹; 提取文件路径、函数定义、类名、依赖关系; 生成语义向量(embeddings)并存储(只保存索引,不上传源代码)。 界面说明:索引完成度100%;已被索引的文件数量为 78; Index New Folders: 当你创建或添加新文件夹时,Cursor 是否自动索引它。 Ignore Files in .cursorignore: 告诉 Cursor 哪些文件不要被索引。类似.gitignore Docs(文档索引): 可以手动添加官方文档、API 文档、开发指南,让它当作参考知识。 添加一个 README.md 或内部 API 规范; 或添加外部文档(如一个 SDK 的文档网站); 之后在 Chat 里用 @doc 引用 如何撤销修改 在AI编辑窗口提问,应用修改,点击Accept 应用完之后,若想回退版本,可以点击提问右边的回撤箭头。 整体思路(重要) 1)先打开项目,然后用browser模式,让AI对这个项目生成一个 .cursorignore 文件,自动忽略哪些文件无需添加进上下文。 2)打开设置,Index&docs,重新索引一下。 3)把项目相关的需求文档、接口文档、技术文档,全部录入到docs中,作为知识库以作备用。这与项目代码文件夹解耦的。 4)在项目根目录下创建 .cursorrules 文件,不需要 @ 引用,自动生效。 .cursorrules 就是 Cursor 的 AI 指令与代码风格规则文件,用来告诉 AI:在这个项目里写代码、命名、注释、格式化时都按照这些规则来做。是一个 系统级提示词 。 eg: ai_behavior: - 所有回答必须使用中文 - 代码中添加必要的注释 style: indentation: 4 spaces naming_convention: variables: camelCase AI 背后接收到的系统指令:你是一个 Java 开发助手。 遵循以下项目规则: 所有回答必须使用中文。 代码中添加必要的注释。 使用 4 空格缩进。 变量名使用 camelCase。 用户请求: 「写一个计算阶乘的 Java 函数」。
杂项
zy123
10月29日
0
2
0
2025-09-08
K8S
Kubernetes (K8S) Kubernetes 是一个开源的容器编排平台,用于自动化部署、扩缩容(Pod 数量多了/少了自动调整)和自愈(坏掉的 Pod 会被自动重建) 基本架构 一个 Kubernetes 集群 (Cluster) = 控制平面 + 工作节点 的组合。要使用K8S,要先搭建集群,deployment.yaml 和 service.yaml 要提交到 K8S 集群,由它调度和运行。 控制平面 (Control Plane) 负责管理整个集群,不直接跑应用。 组件 作用 比喻 API Server 接收命令(kubectl)、提供统一接口 前台服务员 etcd 存储集群所有状态(配置、Pod 列表等) 账本/数据库 Scheduler 决定 Pod 跑在哪个 Node 上 领班 Controller Manager 保证实际状态符合预期(补 Pod、重建失败的 Pod) 经理 工作节点 (Worker Nodes) 实际跑应用容器。 组件 作用 Kubelet 负责跟 API Server 沟通,并启动/管理容器 容器运行时 运行容器(Docker、containerd) Kube-Proxy 管理网络规则,实现 Service 的负载均衡 graph TD A[控制平面] --> B[Node 1] A --> C[Node 2] A --> D[Node 3] B --> E[Pod] B --> F[Pod] C --> G[Pod] D --> H[Pod] K8S 核心概念 Pod 最小运行单元,一个 Pod 里可以有 1 个或多个容器。 共享网络和存储空间 Deployment 管 Pod 的「副本数」和「版本」。 支持滚动更新、回滚 Service 提供稳定的网络入口(因为 Pod IP 会变)。 负载均衡到一组 Pod。 ConfigMap & Secret ConfigMap:存储配置信息(非敏感)。 Secret:存储敏感信息(密码、Token),会加密。 基本使用方式 Deployment(定义 Pod 模板 + 副本数) apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 # 要 3 个 Pod selector: matchLabels: app: my-app template: # Pod 模板 metadata: labels: app: my-app #给 Pod 打标签,Service 用 selector 找到这些 Pod 做负载均衡 spec: containers: - name: my-app #Pod名 image: my-registry/my-app:v1 # ← 指向 CI 推送后的镜像(仓库/名称:标签) ports: - containerPort: 8080 #容器对外提供服务的端口 Pod名可能是:my-app-6f7c9d7c5d-abcde,它里面的容器名:my-app 映射关系: kind: Deployment → 创建一个「Pod 管理器」 replicas: 3 → 保证始终有 3 个 Pod template → Pod 的样子(运行哪个镜像、开哪个端口) Service(提供统一访问入口) apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app # 找到所有带 app=my-app 标签的 Pod ports: - port: 80 # Service 入口端口 targetPort: 8080 # Pod 里容器的端口 type: LoadBalancer # 暴露给外部访问 映射关系: selector → 绑定到 Deployment 创建的 Pod,根据 Pod 的标签(my-app) ports → 用户访问 80 端口,会转发到 Pod 的 8080 type: LoadBalancer → 提供一个外部 IP 供用户访问 典型工作流程 sequenceDiagram 开发者->>Git: 提交代码 Git->>CI/CD: 触发构建 CI/CD->>镜像仓库: 构建Docker镜像 CI/CD->>K8S: kubectl apply K8S->>K8S: 创建/更新Pod K8S->>K8S: 健康检查 K8S->>用户: 服务可用 sequenceDiagram 开发者->>API Server: kubectl apply -f xxx.yaml API Server->>etcd: 写入期望状态 API Server->>Scheduler: 请求调度 Scheduler->>Node: 分配 Pod 到合适的节点 Node->>Kubelet: 启动容器 Controller Manager->>Cluster: 监控状态并修复 Service->>用户: 提供统一访问入口 👉 过程总结: 提交 YAML → API Server 接收并存到 etcd。 Scheduler 决定 Pod 去哪个 Node。 Node 上的 Kubelet 把容器启动。 Controller Manager 盯着数量,缺了就补。 Service 统一出口,用户不用关心 Pod IP。 常用操作 前提是1:集群必须已经搭好(minikube/kind/k3s/云厂商的 K8S)。 2:kubectl 已经配置好 kubeconfig 3:镜像能拉取到 如果是公有镜像(比如 Docker Hub),直接写就行。 如果是私有仓库,需要配 imagePullSecrets。 # 部署应用 kubectl apply -f deployment.yaml kubectl apply -f service.yaml # 查看集群资源 kubectl get pods -o wide kubectl get deployments kubectl get services # 扩缩容 kubectl scale deployment/my-app --replicas=5 # 滚动更新 kubectl set image deployment/my-app my-app=my-registry/my-app:v2 # 回滚 kubectl rollout undo deployment/my-app
杂项
zy123
9月8日
0
2
0
2025-09-06
CICD
CI/CD 自动部署项目 使用Gitea Actions 1)启用Gitea Actions: 编辑你的Gitea服务器配置文件 app.ini(通常位于 /etc/gitea/或 Gitea 安装目录),添加: [actions] ENABLED = true 然后重启Gitea服务。 2)在部署服务器上安装Runner: # 1. 下载并安装 act_runner (需要sudo) sudo wget https://gitea.com/gitea/act_runner/releases/download/v0.2.10/act_runner-0.2.10-linux-amd64 -O /usr/local/bin/act_runner sudo chmod +x /usr/local/bin/act_runner # 2. 为Runner创建专用工作目录(推荐使用绝对路径) sudo mkdir -p /opt/gitea-runner sudo chown $USER:$USER /opt/gitea-runner # 将目录所有权给当前用户 cd /opt/gitea-runner # 3. 注册Runner(重要:必须添加labels标签) act_runner register --no-interactive \ --instance https://你的gitea域名.com \ --token <你的令牌> \ --name my-runner \ --labels self-hosted,linux # 这个标签必须与工作流文件中的runs-on匹配 # 4. 启动Runner(后台运行) nohup act_runner daemon > runner.log 2>&1 & # 5. 查看运行状态和日志 tail -f runner.log ps aux | grep act_runner 3)令牌获取: 如果你想给整个实例用 → 站点管理员设置 → Actions → Runners。 如果只想给某个仓库用 → 进入该仓库 → Settings → Actions → Runners。 点击 New Runner,系统会生成一个 TOKEN。 例如:abcdef1234567890 还是设置整个实例好!! 4)将act_runner注册为服务自启动 sudo vim /etc/systemd/system/act_runner.service 写入以下内容: [Unit] Description=Gitea Actions Runner After=network.target [Service] ExecStart=/usr/local/bin/act_runner daemon WorkingDirectory=/opt/gitea-runner User=zy123 Restart=always RestartSec=5 [Install] WantedBy=multi-user.target ExecStart 指向你安装的 act_runner 路径(你已经放在 /usr/local/bin/ 了)。 WorkingDirectory 可以写你打算存放 Runner 缓存的目录(比如 /home/zy123/act_runner,你已经在这里 register 过了)。 User=zy123 保证 Runner 以你当前用户运行,而不是 root。 重新加载 systemd 配置: sudo systemctl daemon-reexec 启动并开机自启: sudo systemctl enable --now act_runner 查看运行状态: systemctl status act_runner 5)在后端仓库根目录下,新建目录和文件: .gitea/workflows/deploy.yml 写入以下内容: name: Deploy Backend on: push: branches: [ "master" ] # master 分支推送时触发 jobs: build-and-deploy: runs-on: self-hosted steps: - name: Checkout code uses: actions/checkout@v3 - name: Create application-local.yml run: | mkdir -p src/main/resources/ cat << 'EOF' > src/main/resources/application-local.yml ${{ secrets.APPLICATION_LOCAL_YML }} EOF - name: Build and restart smile-picture run: | cd docs/tags/picture-v1.0 docker compose -f docker-compose-app-v1.0.yml build smile-picture-backend docker compose -f docker-compose-app-v1.0.yml up -d smile-picture-backend - name: Cleanup dangling images run: docker image prune -f 特别注意,application-local没有用git管理,把它存在了Actions的密钥中: 然后deploy.yml中可以把里面的内容复制过去。 6)工作原理 1.Runner 接收任务 当你 push 到 main 分支时: Gitea 会触发 workflow(.gitea/workflows/deploy.yml)。 服务器上的 act_runner 会接收到这个任务,并开始执行 jobs.build-and-deploy。 2.actions/checkout@v3 这一行的作用是:它会把你刚刚 push 的最新代码 完整克隆 到 Runner 的工作目录。 /home/<你的用户>/actions-runner/_work/<repo名>/<repo名>/ 所以,这时候你的项目在 Runner 的临时目录里已经是最新代码了,不需要 git pull。 3.后续 cd docs/tag/group-buy-v3.0 都是在 这个临时目录 里执行的。 相当于你在服务器上的临时副本中: 用 docker compose build 构建镜像 用 docker compose up -d 启动/更新容器 4.Runner 每次执行 workflow 时,工作目录都会 重新 checkout 最新代码。 默认不会自动清理旧目录,但可以在 workflow 里加 actions/checkout 的参数来控制,比如 clean: true。. 7)git push之后
杂项
zy123
9月6日
0
4
0
2025-07-30
mermaid画图
mermaid画图 graph TD A[多智能体随机网络结构分析] --> B[多智能体协同学习与推理] A --> A1["谱参数实时估算"] A1 --> A11["卡尔曼滤波"] A1 --> A12["矩阵扰动理论"] A1 --> A13["输出:谱参数"] A --> A2["网络拓扑重构"] A2 --> A21["低秩分解重构"] A2 --> A22["聚类量化"] A2 --> A23["输出:邻接矩阵、特征矩阵"] graph TD B[多智能体协同学习与推理] B --> B1["联邦学习、强化学习"] B1 --> B11["谱驱动学习率调整"] B1 --> B12["自适应节点选择策略"] B --> B2["动态图神经网络"] B2 --> B21["动态图卷积设计"] B2 --> B22["一致性推理"] graph TD %% 颜色和样式定义 classDef startEnd fill:#e6ffe6,stroke:#333,stroke-width:2px classDef operation fill:#fff,stroke:#000,stroke-width:1px classDef decision fill:#ffcccc,stroke:#000,stroke-width:1px classDef update fill:#ccffcc,stroke:#000,stroke-width:1px %% 节点定义(严格按图片顺序) A([开始]):::startEnd B[交易信息\n外部订单号]:::operation C{判断是否为锁单订单}:::decision D[查询拼团组队信息]:::operation E[更新订单详情\n状态为交易完成]:::update F[更新拼团组队进度]:::update G{拼团组队完结\n目标量判断}:::decision H[写入回调任务表]:::operation I([结束]):::startEnd %% 流程连接(完全还原图片走向) A --> B B --> C C -->|是| D D --> E E --> F F --> G G -->|是| H H --> I C -->|否| I G -->|否| I %% 保持原图连接线样式 linkStyle 0,1,2,3,4,5,6,7,8 stroke-width:1px graph TD A[用户发起退单请求] --> B{检查拼团状态} B -->|拼团未完成| C1[场景1:拼团中退单] C1 --> D1{是否已支付?} D1 -->|未支付| E1[取消订单] E1 --> F1[更新订单状态为2] F1 --> G1[通知拼团失败] G1 --> H1[退单完成] D1 -->|已支付| I1[发起退款] I1 --> F1 B -->|拼团已完成| C2[场景2:完成后退单] C2 --> D2{是否超时限?} D2 -->|未超时| E2[发起退款] E2 --> F2[更新订单状态] F2 --> H1 D2 -->|超时| G2[退单失败] style A fill:#f9f,stroke:#333 style B fill:#66f,stroke:#333 style C1 fill:#fbb,stroke:#f66 style C2 fill:#9f9,stroke:#090 flowchart LR %% ===================== 左侧:模板模式块 ===================== subgraph Template["设计模式 - 模板"] direction TB SM["StrategyMapper 策略映射器"] SH["StrategyHandler 策略处理器"] ASR["AbstractStrategyRouter<T, D, R> 策略路由抽象类"] SM -->|实现| ASR SH -->|实现| ASR end %% ===================== 右侧:策略工厂与支持类 ===================== DASFactory["DefaultActivityStrategyFactory 默认的拼团活动策略工厂"] AGMS["AbstractGroupBuyMarketSupport 功能服务支撑类"] DASFactory --> AGMS AGMS -->|继承| ASR %% ===================== 业务节点链路 ===================== Root["RootNode 根节点"] Switch["SwitchRoot 开关节点"] Market["MarketNode 营销节点"] End["EndNode 结尾节点"] Other["其他节点"] AGMS --> Root Root --> Switch Switch --> Market Market --> End Switch -.-> Other Other --> End %% ===================== 样式(可选) ===================== classDef green fill:#DFF4E3,stroke:#3B7A57,stroke-width:1px; classDef red fill:#E74C3C,color:#fff,stroke:#B03A2E; classDef purple fill:#7E60A2,color:#fff,stroke:#4B3B6B; classDef blue fill:#3DA9F5,color:#fff,stroke:#1B6AA5; class SM,SH,Root,Switch,Market,End,Other green; class DASFactory red; class AGMS purple; class ASR blue; style Template stroke-dasharray: 5 5; sequenceDiagram participant A as 启动时 participant B as BeanPostProcessor participant C as 管理后台 participant D as Redis Pub/Sub participant E as RTopic listener participant F as Bean 字段热更新 A->>B: 扫描 @DCCValue 标注的字段 B->>B: 写入默认值 / 读取 Redis B->>B: 注入字段值 B->>B: 缓存 key→Bean 映射 A->>A: Bean 初始化完成 C->>D: publish("myKey,newVal") D->>E: 订阅频道 "dcc_update" E->>E: 收到消息,更新 Redis E->>E: 从 Map 找到 Bean E->>E: 反射注入新值到字段 E->>F: Bean 字段热更新完成 sequenceDiagram participant A as 后台/系统 participant B as Redis Pub/Sub participant C as DCC监听器 participant D as Redis数据库 participant E as 反射更新字段 participant F as Bean实例 A->>B: 发布消息 ("cutRange:50") B->>D: 将消息 "cutRange:50" 写入 Redis B->>C: 触发订阅者接收消息 C->>D: 更新 Redis 中的 "cutRange" 配置值 C->>F: 根据映射找到对应的 Bean C->>E: 通过反射更新 Bean 中的字段 E->>C: 更新成功,字段值被同步 C->>A: 配置变更更新完成 flowchart LR A[请求进入链头 Head] --> B[节点1: 日志LogLink] B -->|继续| C[节点2: 权限AuthLink] B -->|直接返回/终止| R1[返回结果] C -->|通过→继续| D[节点3: 审批ApproveLink] C -->|不通过→终止| R2[返回失败结果] D --> R3[返回成功结果] classDef node fill:#eef,stroke:#669; classDef ret fill:#efe,stroke:#393; class A,B,C,D node; class R1,R2,R3 ret; flowchart LR subgraph mall["小型支付商城"] style mall fill:#ffffff,stroke:#333,stroke-width:2 A[AliPayController<br/>发起退单申请]:::blue C[订单状态扭转<br/>退单中]:::grey E[RefundSuccessTopicListener<br/>接收MQ消息<br/>执行退款和订单状态变更]:::green end subgraph pdd["拼团系统"] style pdd fill:#ffffff,stroke:#333,stroke-width:2 B[MarketTradeController<br/>接收退单申请]:::yellow D[TradeRefundOrderService<br/>退单策略处理]:::red F[TradeRepository<br/>发送MQ消息]:::purple G([MQ消息队列<br/>退单成功消息]):::orange H[RefundSuccessTopicListener<br/>接收MQ消息<br/>恢复库存]:::green end A -- "1. 发起退单请求" --> B B -- "2. 处理退单" --> D D -- "3. 发送MQ消息" --> F F -- "4. 发布消息 (异步+本地消息表补偿)" --> G F -- "5. 返回结果" --> C G -- "6. 消费消息 (恢复库存)" --> H G -. "7. 消费消息 (执行退款)" .-> E classDef blue fill:#dbe9ff,stroke:#6fa1ff,stroke-width:1; classDef grey fill:#e5e5e5,stroke:#9e9e9e,stroke-width:1; classDef green fill:#d6f2d6,stroke:#76b076,stroke-width:1; classDef yellow fill:#fef3cd,stroke:#f5c700,stroke-width:1; classDef red fill:#f8d7da,stroke:#e55353,stroke-width:1; classDef purple fill:#e4dbf9,stroke:#9370db,stroke-width:1; classDef orange fill:#ffecca,stroke:#ffa500,stroke-width:1; sequenceDiagram participant Client as 前端 participant WS as WebSocket 服务器 participant Auth as 权限校验 participant Dispatcher as 消息分发器 participant Handler as 消息处理器 Client->>WS: 请求建立 WebSocket 连接 WS->>Auth: 校验用户权限 Auth-->>WS: 校验通过,保存用户和图片信息 WS-->>Client: 连接成功 Client->>WS: 发送消息(包含消息类型) WS->>Dispatcher: 根据消息类型分发 Dispatcher->>Handler: 执行对应的消息处理逻辑 Handler-->>Dispatcher: 返回处理结果 Dispatcher-->>WS: 返回处理结果 WS-->>Client: 返回处理结果给客户端 Client->>WS: 断开连接 WS-->>Client: 删除 WebSocket 会话,释放资源 sequenceDiagram participant Client as Client(浏览器) participant WS as WebSocket Endpoint participant Producer as PictureEditEventProducer participant RB as RingBuffer participant Worker as PictureEditEventWorkHandler participant Handler as PictureEditHandler Client->>WS: 发送 PictureEditRequestMessage WS->>Producer: publishEvent(msg, session, user, pictureId) Producer->>RB: next() 获取序号,写入事件字段 Producer->>RB: publish(sequence) 发布 RB-->>Worker: 回调 onEvent(event) Worker->>Worker: 解析 type -> PictureEditMessageTypeEnum alt ENTER_EDIT Worker->>Handler: handleEnterEditMessage(...) else EXIT_EDIT Worker->>Handler: handleExitEditMessage(...) else EDIT_ACTION Worker->>Handler: handleEditActionMessage(...) else 其他/异常 Worker->>WS: sendMessage(ERROR 响应) end Worker-->>Client: 业务处理后的响应(通过 WS) sequenceDiagram participant Client as WebSocket Client participant IO as WebSocket I/O线程 participant Biz as 业务逻辑(耗时) Client->>IO: 收到消息事件(onMessage) IO->>Biz: 执行业务逻辑(耗时3s) Biz-->>IO: 返回结果 IO->>Client: 发送响应 Note over IO: I/O线程被业务阻塞3s 不能处理其他连接的消息 sequenceDiagram participant Client as WebSocket Client participant IO as WebSocket I/O线程 participant Disruptor as RingBuffer队列 participant Worker as Disruptor消费者线程 participant Biz as 业务逻辑(耗时) Client->>IO: 收到消息事件(onMessage) IO->>Disruptor: 发布事件(快速) Disruptor-->>IO: 立即返回 IO->>Client: (继续处理其他连接消息) Worker->>Biz: 异步执行业务逻辑(耗时3s) Biz-->>Worker: 返回结果 Worker->>Client: 通过WebSocket发送响应 flowchart TD A[客户端发起WebSocket连接] --> B[HTTP握手阶段] B --> C[WsHandshakeInterceptor.beforeHandshake] C -->|校验失败| D[拒绝握手 连接关闭] C -->|校验成功| E[建立WebSocket连接] E --> F[PictureEditHandler] F --> G[处理WebSocket消息 收发数据] flowchart TD A([接收请求]) --> B{查询本地缓存 Caffeine} B -- 命中 --> C[返回本地缓存数据] C --> End1(((结束))) B -- 未命中 --> D{查询分布式缓存 Redis} D -- 命中 --> E[更新本地缓存] E --> F[返回 Redis 缓存数据] F --> End2(((结束))) D -- 未命中 --> G[查询数据库] G --> H[更新本地缓存和 Redis 缓存] H --> I[返回数据库数据] I --> End3(((结束))) classDiagram class ImageSearchApiFacade { +searchImage(localImagePath) } class GetImagePageUrlApi { +getImagePageUrl(localImagePath) } class GetImageFirstUrlApi { +getImageFirstUrl(imagePageUrl) } class GetImageListApi { +getImageList(imageFirstUrl) } ImageSearchApiFacade --> GetImagePageUrlApi : Calls ImageSearchApiFacade --> GetImageFirstUrlApi : Calls ImageSearchApiFacade --> GetImageListApi : Calls erDiagram 用户 { BIGINT 用户ID VARCHAR 用户名 } 角色 { BIGINT 角色ID VARCHAR 角色名称 VARCHAR 描述 } 权限 { BIGINT 权限ID VARCHAR 权限名称 VARCHAR 描述 } 用户 }o--o{ 角色 : 拥有 角色 }o--o{ 权限 : 赋予 classDiagram class Collection { <<interface>> +add() +remove() +clear() +size() } class Set { <<interface>> } class List { <<interface>> } class Queue { <<interface>> } class Map { <<interface>> } class HashSet { <<class>> } class TreeSet { <<class>> } class ArrayList { <<class>> } class LinkedList { <<class>> } class PriorityQueue { <<class>> } class HashMap { <<class>> } class TreeMap { <<class>> } Collection <|-- Set Collection <|-- List Collection <|-- Queue Set <|-- HashSet Set <|-- TreeSet List <|-- ArrayList List <|-- LinkedList Queue <|-- LinkedList Queue <|-- PriorityQueue Map <|-- HashMap Map <|-- TreeMap sequenceDiagram participant U as 用户 participant O as 下单服务 participant P as 拼团/优惠服务 participant R as 风控/库存校验 U ->> O: 请求锁单(userId, goodsId, activityId, teamId) activate O %% Step 1 幂等查询 O ->> P: 幂等查询(out_trade_no 是否已有锁单) P -->> O: 存在则直接返回该条记录 %% Step 2 拼团人数校验 O ->> P: 校验拼团人数(再次拉取,避免前端滞后) P -->> O: 校验结果 %% Step 3 优惠试算 O ->> P: 优惠试算(activityId, goodsId) P -->> O: 返回拼团优惠价格 %% Step 4 人群限定 O ->> R: 校验是否在目标人群范围 R -->> O: 校验结果(非目标人群直接拒绝) %% Step 5 锁单责任链 O ->> P: 活动有效性校验 O ->> P: 用户参与次数校验 O ->> R: 剩余库存校验 O -->> U: 返回锁单结果(成功/失败) deactivate O flowchart TD A[initialize @PostConstruct] --> B[fetchAllPictureTableNames] B -->|查询 SpaceService| C[组装所有表名 picture + picture_xxx] C --> D[updateShardingTableNodes] D --> E[getContextManager] E --> F[获取 ShardingSphereRuleMetaData] F --> G[更新 ShardingRuleConfiguration.actual-data-nodes] G --> H[alterRuleConfiguration + reloadDatabase] subgraph 动态建表 I[createSpacePictureTable] --> J{space 是否旗舰团队?} J -- 否 --> K[不建表] J -- 是 --> L[SqlRunner 创建新表 picture_xxx] L --> D end flowchart TD %% 定义节点 Publisher[Publisher<br/>消息发布者] Exchange[fanout Exchange<br/>扇形交换机] Queue1[Queue1] Queue2[Queue2] Queue3[Queue3] Consumer1[Consumer1] Consumer2[Consumer2] Consumer3[Consumer3] Msg[msg] %% 消息流向 Publisher -->|发布消息| Exchange Exchange -->|广播消息| Queue1 Exchange -->|广播消息| Queue2 Exchange -->|广播消息| Queue3 Queue1 -->|投递消息| Consumer1 Queue2 -->|投递消息| Consumer2 Queue3 -->|投递消息| Consumer3 %% 确认回执 Consumer1 -->|ack<br/>成功处理,删除消息| Queue1 Consumer2 -->|nack<br/>处理失败,重新投递| Queue2 Consumer3 -->|reject<br/>处理失败并拒绝,删除消息| Queue3 %% 样式定义 classDef publisher fill:#e1f5fe,stroke:#01579b; classDef exchange fill:#d1c4e9,stroke:#4527a0; classDef queue fill:#f8bbd0,stroke:#880e4f; classDef consumer fill:#c8e6c9,stroke:#1b5e20; class Publisher publisher; class Exchange exchange; class Queue1,Queue2,Queue3 queue; class Consumer1,Consumer2,Consumer3 consumer; flowchart TD subgraph 运营 A1[配置拼团] end subgraph 用户 B1[查看商品] end subgraph 用户A/B C1[参与拼团] end %% 运营流程 A1 --> A2[拼团折扣] A2 --> A3[团长优惠] A3 --> A4[人群标签] %% 用户查看拼团 B1 --> B2[查看拼团] B2 --> B3[优惠试算] B3 --> B4[展示拼团] %% 用户参与拼团 C1 --> D1[商品支付 / 折扣支付] D1 --> D2[展示拼团 + 分享] D1 --> D3[拼团系统] D3 --> D4[记录拼团/多人拼团] D4 --> D5[团购回调/回调地址] D3 --> D6[拼团超时/拼团失败] D6 --> D7[发起退单] D7 --> D8[团购回调/回调地址] %% 拼团后逻辑 D1 --> E1[拼团订单 暂不发货] E1 --> E2[免拼下单 直接成单] E2 --> E3[拼团完成 商品发货] D6 --> F1[拼团失败 商品退单] E1 --> E4[直接购买 放弃拼团] E4 --> F1 E3 -->|成功| End1([结束]) F1 -->|失败| End2([结束]) flowchart TD A[Throwable] --> B[Error] A --> C[Exception] B --> D[虚拟机错误<br>VirtualMachineError] B --> E[内存溢出错误<br>OutOfMemoryError] B --> F[栈溢出错误<br>StackOverflowError] C --> G[IOException] C --> H[RuntimeException] C --> I[检查异常<br>Checked Exception<br>(除RuntimeException外的Exception)] G --> J[FileNotFoundException] G --> K[EOFException] H --> L[空指针异常<br>NullPointerException] H --> M[数组越界异常<br>ArrayIndexOutOfBoundsException] H --> N[类型转换异常<br>ClassCastException] H --> O[算术异常<br>ArithmeticException] flowchart TD A[请求进入方法] --> B{@DCCValue("rateLimiterSwitch:open") == "close"?} B -- 是 --> Z[直接放行<br>不执行限流逻辑] --> END[方法正常返回] B -- 否 --> C[@RateLimiterAccessInterceptor 拦截方法] C --> D[解析注解参数<br>获取限流维度 key] D --> E[反射提取方法参数中的字段值<br>如 userId] E --> F[生成 Redis Key<br>rl:limiter:userId] F --> G{是否在黑名单中?} G -- 是 --> H[调用 fallbackMethod<br>执行降级逻辑] --> END G -- 否 --> I[通过 RRateLimiter 尝试获取令牌] I -- 成功获取令牌 --> J[执行目标方法] --> END I -- 未获取令牌 --> K[记录拒绝次数<br>RAtomicLong 自增] K --> L{拒绝次数 > blacklistCount?} L -- 是 --> M[加入黑名单<br>设置 Key: rl:bl:userId<br>过期24小时] --> N[调用 fallbackMethod] L -- 否 --> N[调用 fallbackMethod] N --> END[降级逻辑返回结果]
杂项
zy123
7月30日
0
7
0
2025-03-21
matlab
matlab笔记 命令行窗口 clc:清屏(命令行窗口) clear all:把命名的变量删掉,不是命令行窗口 命名规则: 变量命名以字母开头,不可以下划线,变量是区分字母大小写的 脚本 %% xxx 注释(百分号+一个空格) % xxx 也是注释 s='a' '"aaaa",字符串 abs(s) 字符s的ascii码,为97 char(97), 输出'a' numtostr(65) ans='65',数字转字符串 length(str),字符串的长度 矩阵 A=[1 2 3 ;4 5 6 ;7 8 9] 分号换行 B=A‘ ,矩阵转置 C=A(:) ,将矩阵拉成一列,按列存储,第一列拼接第二列拼接第三列 D=inv(A) 求逆矩阵 E=zeros(10,5,3) 生成10行5列3维0矩阵 元胞数组 A=cell(1,6),生成1行6列的小格子,每个小格子可以存放各种数据 eye(3),生成3x3的单位阵 A{2}=eye(3),matlab数组从1开始,不是0
杂项
zy123
3月21日
0
4
0
1
2
3
下一页