From 5d682e6b30778bff662e8ff7408ec237ad8d390e Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Mon, 28 Jul 2025 21:28:41 +0800 Subject: [PATCH] =?UTF-8?q?Commit=20on=202025/07/28=20=E5=91=A8=E4=B8=80?= =?UTF-8?q?=2021:28:40.93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 后端学习/力扣Hot 100题.md | 93 ++++++++++++-------- 杂项/mermaid画图.md | 152 ++++++++++++++++++++++++++++++++ 科研/mermaid画图.md | 32 ------- 项目/拼团交易系统.md | 177 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 380 insertions(+), 74 deletions(-) create mode 100644 杂项/mermaid画图.md delete mode 100644 科研/mermaid画图.md diff --git a/后端学习/力扣Hot 100题.md b/后端学习/力扣Hot 100题.md index 6631f30..b199544 100644 --- a/后端学习/力扣Hot 100题.md +++ b/后端学习/力扣Hot 100题.md @@ -2079,9 +2079,9 @@ public boolean canFillBackpack(int[] weights, int capacity) { dp[j] 表示从数组中选取若干个数,使得这些数的和正好为 j 的方法数。 状态转移: -对于数组中的每个数字 numnumnum,从 dp 数组后向前(逆序)遍历,更新: +对于数组中的每个数字 `num`,从 dp 数组后向前(逆序)遍历,更新: -dp[j]=dp[j]+dp[j−num] +`dp[j]=dp[j]+dp[j−num]` 这里的意思是: @@ -2102,7 +2102,7 @@ dp[j]=dp[j]+dp[j−num] #### 0/1背包(一) -描述:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。**每件物品只能用一次**,求解将哪些物品装入背包里物品价值总和最大。 +描述:有n件物品和一个最多能背重量为 w 的背包。第 i 件物品的重量是 weight[i],得到的价值是 value[i] 。**每件物品只能用一次**,求解将哪些物品装入背包里物品价值总和最大。 image-20250411163635562 @@ -2116,18 +2116,18 @@ dp[j]=dp[j]+dp[j−num] **2. 确定递推公式** -考虑dp\[i][j],有两种情况: +考虑 `dp[i][j]`,有两种情况: -- **不放物品i**:背包容量为j,里面不放物品i的最大价值是 dp\[i - 1][j]。 -- **放物品i**:背包空出物品i的容量后,背包容量为 j - weight[i],dp\[i - 1][j - weight[i]] 为背包容量为j - weight[i]且不放物品i的最大价值,那么dp\[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值 +- **不放物品i**:背包容量为 `j` ,里面不放物品 `i` 的最大价值是 `dp[i - 1][j]`。 +- **放物品i**:背包空出物品i的容量后,背包容量为 `j - weight[i]`,`dp[i - 1][j - weight[i]]` 为背包容量为`j - weight[i]` 且不放物品i的最大价值,那么`dp[i - 1][j - weight[i]] + value[i]` (物品i的价值),就是背包放物品i得到的最大价值 递归公式: `dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);` **3. dp数组如何初始化** -(1)首先从dp\[i][j]的定义出发,如果背包容量j为0的话,即dp\[i][0],无论是选取哪些物品,背包价值总和一定为0。 +(1)首先从 `dp[i][j]` 的定义出发,如果背包容量 `j` 为0的话,即 `dp[i][0]` ,无论是选取哪些物品,背包价值总和一定为0。 -(2)由状态转移方程 `dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);` 可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化。 +(2)由状态转移方程 `dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);` 可以看出`i` 是由 `i-1` 推导出来,那么 `i` 为0的时候就一定要初始化。 此时就看存放编号0的物品的时候,各个容量的背包所能存放的最大价值。 @@ -2156,7 +2156,7 @@ for(int i = 1; i < weight.size(); i++) { // 遍历物品 **代码:** -``` +```java public int knapsack(int[] weight, int[] value, int capacity) { int n = weight.length; // 物品的总个数 @@ -2202,11 +2202,11 @@ for(int i = 1; i < weight.size(); i++) { // 遍历物品 1.状态转移只依赖于之前的状态(例如上一行或上一个层次),而不是当前行中动态更新的状态。 -- 例如在 0/1 背包问题中,二维 dp\[i][j] 只依赖于 dp\[i-1][j] 和 dp\[i-1][j - weight[i]]。 +- 例如在 0/1 背包问题中,二维 `dp[i][j]` 只依赖于 `dp[i-1][j]` 和 `dp[i-1][j - weight[i]]`。 2.存在确定的遍历顺序(例如逆序或正序)能够确保在更新一维 dp 时,所依赖的值不会被当前更新覆盖。 -- **逆序遍历**:例如 0/1 背包问题,为了防止同一个物品被重复使用,需要对容量 j 从大到小遍历,确保 dp[j - weight] 的值还是上一轮(上一行)的。 +- **逆序遍历**:例如 0/1 背包问题,为了防止同一个物品被重复使用,需要对容量 j 从大到小遍历,确保 `dp[j - weight]` 的值还是上一轮(上一行)的。 - **正序遍历**:在一些问题中,如果状态更新不会导致当前状态被重复利用(例如完全背包问题),可以顺序遍历。 @@ -2219,12 +2219,12 @@ for(int i = 1; i < weight.size(); i++) { // 遍历物品 使用一维 dp 数组 `dp[j]` 表示「在当前考虑的物品下,背包容量为 j 时能够获得的最大价值」。 **2.确定递推公式** -当考虑当前物品 i(重量为 weight[i],价值为 value[i])时,有两种选择: +当考虑当前物品 `i` (重量为 `weight[i]`,价值为 `value[i]`)时,有两种选择: - **不选当前物品 i:** - 此时的最大价值为 dp[j](即前面的状态没有变化)。 + 此时的最大价值为 `dp[j]`(即前面的状态没有变化)。 - **选当前物品 i:** - 当背包容量至少为 weight[i] 时,如果选择物品 i,剩余容量变为 j - weight[i],则最大价值为 dp[j - weight[i]] 加上 value[i]。 + 当背包容量至少为 `weight[i]` 时,如果选择物品 `i` ,剩余容量变为 `j - weight[i]`,则最大价值为 `dp[j - weight[i]]` 加上 `value[i]`。 因此,状态转移方程为: $$ @@ -2234,7 +2234,7 @@ $$ `dp[0] = 0`,表示当背包容量为 0 时,能获得的最大价值自然为 0。 -对于其他容量 dp[j],初始值也设为 0,dp数组在推导的时候一定是取价值最大的数,如果题目给的价值都是正整数那么非0下标都初始化为0就可以了。确保值不被初始值覆盖即可。 +对于其他容量 `dp[j]` ,初始值也设为 0,dp数组在推导的时候一定是取价值最大的数,如果题目给的价值都是正整数那么非0下标都初始化为0就可以了。确保值不被初始值覆盖即可。 **4.一维dp数组遍历顺序** @@ -2242,7 +2242,7 @@ $$ 内层遍历背包容量(**逆序遍历**): 遍历容量从 capacity 到当前物品的重量,进行状态更新。 -- 逆序遍历的目的在于确保当前物品在更新过程中只会被使用一次,因为 dp[j - weight[i]] 代表的是上一轮(当前物品未使用前)的状态,不会被当前物品更新后的状态覆盖。 +- 逆序遍历的目的在于确保当前物品在更新过程中只会被使用一次,因为 `dp[j - weight[i]]` 代表的是上一轮(当前物品未使用前)的状态,不会被当前物品更新后的状态覆盖。 @@ -2308,7 +2308,7 @@ dp\[i][j] 表示从下标为[0-i]的物品,每个物品可以取无限次, **2. 确定递推公式** - **不放物品i**:背包容量为j,里面不放物品i的最大价值是dp\[i - 1][j]。 -- **放物品i**:背包空出物品i的容量后,背包容量为j - weight[i],dp\[i][j - weight[i]] 为背包容量为j - weight[i]且不放物品i的最大价值,那么dp\[i][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值 +- **放物品i**:背包空出物品i的容量后,背包容量为`j - weight[i]`,`dp[i][j - weight[i]]` 为背包容量为`j - weight[i]`且不放物品i的最大价值,那么`dp[i][j - weight[i]] + value[i]` (物品i的价值),就是背包放物品i得到的最大价值 递推公式: `dp[i][j] = max(dp[i - 1][j], dp[i][j - weight[i]] + value[i]);` @@ -2318,17 +2318,18 @@ dp\[i][j] 表示从下标为[0-i]的物品,每个物品可以取无限次, ```java for (int i = 1; i < n; i++) { - for (int j = 0; j <= capacity; j++) { - // 不选物品 i,价值不变 - dp[i][j] = dp[i - 1][j]; - // 如果当前背包容量 j 能放下物品 i,则考虑选取物品 i(完全背包内层循环正序或逆序都可以,但这里通常建议正序) - if (j >= weight[i]) { - // 注意:这里选取物品 i 后仍然可以继续选取物品 i, - // 所以状态转移方程为 dp[i][j] = max(dp[i - 1][j], dp[i][j - weight[i]] + value[i]) - dp[i][j] = Math.max(dp[i][j], dp[i][j - weight[i]] + value[i]); - } - } + for (int j = 0; j <= capacity; j++) { + // 不选物品 i,价值不变 + dp[i][j] = dp[i - 1][j]; + // 如果当前背包容量 j 能放下物品 i,则考虑选取物品 i(完全背包内层循环正序或逆序都可以,但这里通常建议正序) + if (j >= weight[i]) { + // 注意:这里选取物品 i 后仍然可以继续选取物品 i, + // 所以状态转移方程为 dp[i][j] = max(dp[i - 1][j], dp[i][j - weight[i]] + value[i]) + dp[i][j] = Math.max(dp[i][j], dp[i][j - weight[i]] + value[i]); } + } +} + ``` **3. dp数组如何初始化** @@ -2338,13 +2339,13 @@ for (int i = 1; i < n; i++) { ```java for (int j = 0; j <= capacity; j++) { - // 当 j 小于第 0 个物品重量时,无法选取,所以价值为 0 - if (j < weight[0]) { - dp[0][j] = 0; - } else { - // 完全背包允许多次使用物品 0,所以递归地累加 - dp[0][j] = dp[0][j - weight[0]] + value[0]; - } + // 当 j 小于第 0 个物品重量时,无法选取,所以价值为 0 + if (j < weight[0]) { + dp[0][j] = 0; + } else { + // 完全背包允许多次使用物品 0,所以递归地累加 + dp[0][j] = dp[0][j - weight[0]] + value[0]; + } } ``` @@ -2362,12 +2363,32 @@ for (int j = 0; j <= capacity; j++) { 压缩成一维,即`dp[j] = max(dp[j], dp[j - weight[i]] + value[i])` -- 根据题型选择先遍历物品或者背包,**如果求组合数就是外层for循环遍历物品,内层for遍历背包**。**如果求排列数就是外层for遍历背包,内层for循环遍历物品**。 - **组合不强调元素之间的顺序,排列强调元素之间的顺序**。 +- 根据题型选择先遍历物品或者背包, + **如果求组合数就是外层for循环遍历物品,内层for遍历背包**。 + **如果求排列数就是外层for遍历背包,内层for循环遍历物品**。 + **组合数**(顺序不同的序列视为相同)**排列数**(顺序不同的序列视为不同)排列数大于等于组合数!!!。 - 内层循环正序,不要逆序!因为要利用已经更新的dp数组,允许同一物品重复使用! 注意,完全背包和0/1背包的一维dp形式的递推公式一样,但是遍历顺序不同!! +```java +public int completeKnapsack(int[] weight, int[] value, int capacity) { + int n = weight.length; + // dp[j] 表示容量为 j 时的最大价值,初始化为 0 + int[] dp = new int[capacity + 1]; + + // 遍历每件物品 + for (int i = 0; i < n; i++) { + // 完全背包:正序遍历容量 + for (int j = weight[i]; j <= capacity; j++) { + // 如果拿 i 号物品,更新 dp[j] + dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]); + } + } + return dp[capacity]; +} +``` + #### 多重背包 diff --git a/杂项/mermaid画图.md b/杂项/mermaid画图.md new file mode 100644 index 0000000..5815658 --- /dev/null +++ b/杂项/mermaid画图.md @@ -0,0 +1,152 @@ +# mermaid画图 + +```mermaid +graph TD + A[多智能体随机网络结构分析] --> B[多智能体协同学习与推理] + + A --> A1["谱参数实时估算"] + A1 --> A11["卡尔曼滤波"] + A1 --> A12["矩阵扰动理论"] + A1 --> A13["输出:谱参数"] + A --> A2["网络拓扑重构"] + A2 --> A21["低秩分解重构"] + A2 --> A22["聚类量化"] + A2 --> A23["输出:邻接矩阵、特征矩阵"] + + + + + +``` + +```mermaid +graph TD + B[多智能体协同学习与推理] + B --> B1["联邦学习、强化学习"] + B1 --> B11["谱驱动学习率调整"] + B1 --> B12["自适应节点选择策略"] + B --> B2["动态图神经网络"] + B2 --> B21["动态图卷积设计"] + B2 --> B22["一致性推理"] +``` + +```mermaid +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 +``` + +```mermaid +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 + +``` + +```mermaid +flowchart LR + %% ===================== 左侧:模板模式块 ===================== + subgraph Template["设计模式 - 模板"] + direction TB + SM["StrategyMapper + 策略映射器"] + SH["StrategyHandler + 策略处理器"] + ASR["AbstractStrategyRouter + 策略路由抽象类"] + + 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; + +``` + diff --git a/科研/mermaid画图.md b/科研/mermaid画图.md deleted file mode 100644 index 1933395..0000000 --- a/科研/mermaid画图.md +++ /dev/null @@ -1,32 +0,0 @@ -# mermaid画图 - -```mermaid -graph TD - A[多智能体随机网络结构分析] --> B[多智能体协同学习与推理] - - A --> A1["谱参数实时估算"] - A1 --> A11["卡尔曼滤波"] - A1 --> A12["矩阵扰动理论"] - A1 --> A13["输出:谱参数"] - A --> A2["网络拓扑重构"] - A2 --> A21["低秩分解重构"] - A2 --> A22["聚类量化"] - A2 --> A23["输出:邻接矩阵、特征矩阵"] - - - - - -``` - -```mermaid -graph TD - B[多智能体协同学习与推理] - B --> B1["联邦学习、强化学习"] - B1 --> B11["谱驱动学习率调整"] - B1 --> B12["自适应节点选择策略"] - B --> B2["动态图神经网络"] - B2 --> B21["动态图卷积设计"] - B2 --> B22["一致性推理"] -``` - diff --git a/项目/拼团交易系统.md b/项目/拼团交易系统.md index 9ea7404..e19eb57 100644 --- a/项目/拼团交易系统.md +++ b/项目/拼团交易系统.md @@ -115,8 +115,6 @@ crowd_tags_job 人群标签任务 | create_time | 创建时间 | | update_time | 更新时间 | - - - 拼团活动表:设定了拼团的成团规则,人群标签的使用可以限定哪些人可见,哪些人可参与。 - 折扣配置表:拆分出拼团优惠到一个新的表进行多条配置。如果折扣还有更多的复杂规则,则可以配置新的折扣规则表进行处理。 - 人群标签表:专门来做人群设计记录的,这3张表就是为了把符合规则的人群ID,也就是用户ID,全部跑任务到一个记录下进行使用。比如黑玫瑰人群、高净值人群、拼团履约率90%以上的人群等。 @@ -313,7 +311,7 @@ EndNode.apply() → 组装结果并返回 TrialBalanceEntity ## 拼团结算 -d56fcfb9708eb0d99600c751808bb843 +![image-20250725110745607](https://pic.bitday.top/i/2025/07/25/ib8gj1-0.png) @@ -376,6 +374,51 @@ EndNode.apply() → 组装结果并返回 TrialBalanceEntity +## 逆向工程:退单 + +image-20250725105608390 + +逆向的流程,要分析用户是在哪个流程节点下进行中断行为。包括3个场景; + +**已锁单、未支付** + +- **用户行为**:完成锁单后未发起支付。 +- **结果**:订单超时自动关单。 +- 补偿 + - 若用户在临界时刻支付,则需执行“逆向退款”流程——退还支付金额并告知“优惠已过期,请重新参与”。 + - 否则该订单自动失效,释放拼团名额给后续用户。 + +**已锁单、已支付,但拼团未成团** + +- **用户行为**:完成支付,组团人数不足暂未成团。 + +- 补偿策略 + + (可配置优先级): + + 1. **先退拼团,再退款,** + 2. **先退款,再退拼团** + +- 具体执行哪种方式,可由拼团活动策略决定——“优先保障个人”或“优先保障成团”。 + +**已锁单、已支付,且拼团已成团** + +- **用户行为**:支付成功,且组团人数已凑齐。 +- 补偿流程 + - 先退还用户支付金额; + - 再撤销对应的拼团完成量。 +- **注意**:已成团订单视为“已完成含退单”,仍然成团、不再开放新用户参与,确保团队成团状态一致。 + + + +### 策略模板应用 + +根据订单状态和拼团状态动态选择退单策略。 + + + + + ## 收获 ### 实体对象 @@ -727,7 +770,7 @@ while 循环: ### 规则树流程 -![8d9ca81791b613eb7ff06b096a3d7c4a](https://pic.bitday.top/i/2025/06/24/pgcnns-0.png) +!![image-20250725120957709](https://pic.bitday.top/i/2025/07/25/k01knr-0.png) **整体分层思路** @@ -814,10 +857,10 @@ private Map discountCalculateServiceMap; **字段类型**:`Map` -- key—— Bean 的名字 +- key—— **Bean 的名字** - 默认是类名首字母小写 (`mjCalculateService`) - 或者你在实现类上显式写的 `@Service("MJ")` -- **value** —— 那个实现类对应的实例 +- **value** —— 那个实现类对应的**实例** - **Spring 机制**: 1. 启动时扫描所有实现 `IDiscountCalculateService` 的 Bean。 2. 把它们按 “BeanName → Bean 实例” 的映射注入到这张 `Map` 里。 @@ -1624,3 +1667,125 @@ List list = getFromCacheOrDb( | 运维依赖 | **无**:不依赖外部组件 | **有**:需维护高可用的 Redis 集群,增加运维成本 | 目前本项目使用的是分布式限流,用Redisson + + + +### 日志系统 + +#### 输出流向一览 + +输出到3个地方:控制台、本地文件、ELK日志(服务器上内存不足无法部署!) + +| 日志级别 | 控制台 | 本地文件(异步) | Logstash (TCP) | +| ----------- | ------ | ----------------------------- | -------------- | +| TRACE/DEBUG | — | — | — | +| INFO | ✔ | `log_info.log` | ✔ | +| WARN | ✔ | `log_info.log``log_error.log` | ✔ | +| ERROR/FATAL | ✔ | `log_info.log``log_error.log` | ✔ | + +> 注意:实际写文件时,都是通过 ASYNC_FILE_INFO/ERROR 两个异步 Appender 执行,以免日志写盘阻塞业务线程。 + +#### ELK日志系统 + +本地文件每台机器都会在自己 `/data/log/...` 目录下滚动输出自己的日志,互相之间不会合并。 + +如果你希望跨多台服务器**统一管理**,就需要把日志推到中央端——ELK日志系统 + +ELK=Elasticsearch(存储&检索)+ Logstash(采集&处理)+ Kibana(可视化) + +docker-compose.yml: + +```yml +version: '3' +services: + elasticsearch: + image: elasticsearch:7.17.28 + ports: ['9201:9200','9300:9300'] + environment: + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms512m -Xmx512m + volumes: + - ./data:/usr/share/elasticsearch/data + logstash: + image: logstash:7.17.28 + ports: ['4560:4560','9600:9600'] + volumes: + - ./logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf + environment: + - LS_JAVA_OPTS=-Xms1g -Xmx1g + kibana: + image: kibana:7.17.28 + ports: ['5601:5601'] + environment: + - elasticsearch.hosts=http://elasticsearch:9200 +networks: + default: + driver: bridge + +``` + +kibana配置: + +```yml +# +# ** THIS IS AN AUTO-GENERATED FILE ** +# + +# Default Kibana configuration for docker target +server.host: "0" +server.shutdownTimeout: "5s" +elasticsearch.hosts: [ "http://elasticsearch:9200" ] # 记得修改ip +monitoring.ui.container.elasticsearch.enabled: true +i18n.locale: "zh-CN" +``` + +logstash配置: + +```conf +input { + tcp { + mode => "server" + host => "0.0.0.0" + port => 4560 + codec => json_lines + type => "info" + } +} +filter {} +output { + elasticsearch { + action => "index" + hosts => "es:9200" + index => "group-buy-market-log-%{+YYYY.MM.dd}" + } +} +``` + +自己的项目: + +```java + + + + + + + ${LOG_STASH_HOST}:4560 + + +``` + +```xml + + net.logstash.logback + logstash-logback-encoder + 7.3 + +``` + +**使用** + +检查索引:curl http://localhost:9201/_cat/indices?v3 + +打开 Kibana:浏览器访问 `http://localhost:5601`,新建 索引模式(如 `app-log-*`),即可在 Discover/Visualize 中查看与分析日志。 +