云间漫步 技术博客
type: channel
link: https://blog.esugar.cn/
description: 技术点整理
items: MySQL 5.7 中文字段转拼音完整解决方案
items: Spring Boot 3 多模块项目使用ClassFinal进行代码加密完整指南
items: Docker部署Next AI Draw.io：AI增强的在线绘图工具
items: Docker 私有镜像仓库 Registry 部署与管理
items: 使用PyInstaller将Python图形界面程序打包成EXE文件完整指南
items: Docker之EMQX部署：高可用MQTT消息服务器
items: Java单例模式实现与最佳实践
items: 分布式并发控制五大方案与实践指南
items: 欢迎来到我的博客
items: Git提交记录导出全攻略：从基础命令到高级技巧

MySQL 5.7 中文字段转拼音完整解决方案
type: item
date: 2025-11-12T09:00:00+00:00
description: 在中文应用开发中，经常需要将中文字段转换为拼音，用于搜索优化、排序、生成用户名等场景。本文将详细介绍在 MySQL 5.7 中实现中文字段转拼音的多种解决方案。📋 目录需求场景方案对比纯MySQL解决方案Python应用层方案生产环境建议性能优化常见问题🎯 需求场景在以下场景中，我们需要将中文字段转换为拼音：搜索优化：支持用户通过拼音或首字母搜索中文内容排序功能：按拼音字母顺序对中文数据进行排序用户名生成：自动生成基于拼音的用户名或账号数据去重：识别拼音相同但汉字不同的记录数据导出：需要生成包含拼音的报表或数据文件📊 方案对比方案优点缺点适用场景MySQL存储函数无需外部依赖，SQL直接调用性能较差，多音字处理困难数据量小，简单转换MySQL映射表可维护性较好，支持自定义需要维护映射表，性能一般中等数据量，需要灵活配置Python应用层功能强大，多音字处理优秀需要外部程序，增加复杂度生产环境，大数据量混合方案兼顾性能与功能架构复杂高性能要求场景🛠️ 纯MySQL解决方案1. 创建拼音转换函数-- 创建汉字转拼音函数 DELIMITER $$ CREATE FUNCTION `cn_to_pinyin`(str VARCHAR(255)) RETURNS varchar(255) BEGIN DECLARE i INT DEFAULT 1; DECLARE len INT; DECLARE result VARCHAR(255) DEFAULT ''; DECLARE ch CHAR(1); SET len = CHAR_LENGTH(str); WHILE i <= len DO SET ch = SUBSTRING(str, i, 1); SET result = CONCAT(result, get_pinyin(ch)); SET i = i + 1; END WHILE; RETURN result; END$$ DELIMITER ; -- 创建获取单字拼音函数 DELIMITER $$ CREATE FUNCTION `get_pinyin`(ch CHAR(1)) RETURNS varchar(10) BEGIN DECLARE code VARCHAR(4); DECLARE py VARCHAR(10); SET code = HEX(CONVERT(ch USING gbk)); -- 示例：部分汉字映射（实际需要完整映射表） CASE WHEN code BETWEEN 'B0A1' AND 'B0C4' THEN SET py = 'a'; WHEN code BETWEEN 'B0C5' AND 'B2C0' THEN SET py = 'ai'; WHEN code BETWEEN 'B2C1' AND 'B4ED' THEN SET py = 'an'; -- 此处需要补充完整的拼音映射表 ELSE SET py = ch; END CASE; RETURN py; END$$ DELIMITER ;2. 使用映射表方案-- 创建拼音映射表 CREATE TABLE pinyin_mapping ( id INT AUTO_INCREMENT PRIMARY KEY, hanzi CHAR(1) NOT NULL, pinyin VARCHAR(10) NOT NULL, UNIQUE KEY idx_hanzi (hanzi) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='汉字拼音映射表'; -- 创建基于映射表的转换函数 DELIMITER $$ CREATE FUNCTION `cn_to_pinyin_v2`(str VARCHAR(255)) RETURNS varchar(255) BEGIN DECLARE i INT DEFAULT 1; DECLARE len INT; DECLARE result VARCHAR(255) DEFAULT ''; DECLARE ch CHAR(1); DECLARE py VARCHAR(10); SET len = CHAR_LENGTH(str); WHILE i <= len DO SET ch = SUBSTRING(str, i, 1); -- 从映射表查找拼音，找不到则使用原字符 SELECT COALESCE(MAX(pinyin), ch) INTO py FROM pinyin_mapping WHERE hanzi = ch; SET result = CONCAT(result, py); SET i = i + 1; END WHILE; RETURN result…

Spring Boot 3 多模块项目使用ClassFinal进行代码加密完整指南
type: item
date: 2025-11-02T06:34:00+00:00
description: 📋 一、概述Spring Boot 3.5.8多模块项目使用ClassFinal进行代码加密的完整配置和执行说明。ClassFinal通过字节码加密和Java Agent技术保护代码，配合机器码绑定可防止代码在其他服务器运行。🏗️ 二、项目结构假设your-multi-module-project/ ├── pom.xml (父POM) ├── your-common/ (公共模块) │ └── pom.xml ├── your-service/ (业务模块) │ └── pom.xml └── your-main-app/ (主启动模块，在此配置插件) ├── pom.xml └── src/ └── main/ └── java/ └── com/ └── yourcompany/ └── YourApplication.java⚙️ 三、完整配置步骤步骤1：在主启动模块添加ClassFinal依赖编辑 your-main-app/pom.xml：<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"> <parent> <groupId>com.yourcompany</groupId> <artifactId>your-parent</artifactId> <version>1.0.0</version> </parent> <artifactId>your-main-app</artifactId> <packaging>jar</packaging> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>3.1.5</version> <configuration> <mainClass>com.yourcompany.YourApplication</mainClass> </configuration> </plugin> <plugin> <groupId>net.roseboy</groupId> <artifactId>classfinal-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <password>#</password> <packages>com.yourcompany</packages> <!-- --> <excludes>org.springframework,org.springframewor</excludes> <cfgfiles>application.yml,application-prod.yml</cfgfiles> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>classFinal</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>步骤2：第一次打包（获取机器码）# 1. 进入主启动模块目录 cd your-multi-module-project/your-main-app # 2. 执行打包（跳过测试） mvn clean package -DskipTests # 3. 查看生成的文件 ls -la target/*.jar # 应该看到两个文件： # - your-main-app-1.0.0.jar (原始包) # - your-main-app-1.0.0-encrypted.jar (临时加密包，用于获取机器码)步骤3：获取目标服务器机器码# 在目标服务器上执行（生产服务器） # 将临时加密包上传到服务器，或直接在服务器上打包 # 运行临时加密包获取机器码 java -jar your-main-app-1.0.0-encrypted.jar # 控制台输出示例： # ======================================== # ClassFinal 机器码: 89F6A5C8D3E1B7A2 # （程序将在5秒后退出...） # ========================================记录机器码：89F6A5C8D3E1B7A2（你的实际机器码会不同）步骤4：更新配置并…

Docker部署Next AI Draw.io：AI增强的在线绘图工具
type: item
date: 2025-11-01T08:44:00+00:00
description: 概述Next AI Draw.io 是一款集成了AI能力的在线绘图工具，它基于著名的draw.io开源项目构建，并加入了AI智能绘图和文本生成功能。通过Docker部署，你可以快速搭建自己的AI绘图平台，支持流程图、UML图、网络拓扑图等多种图表类型，并利用AI进行智能辅助设计。快速部署命令docker run -d \ -p 3000:3000 \ --restart=always \ -e AI_PROVIDER=deepseek \ -e AI_MODEL=deepseek-chat \ -e DEEPSEEK_API_KEY=sk-xxx \ --name next-ai-draw-io \ ghcr.io/dayuanjiang/next-ai-draw-io:latest参数详解参数说明示例值-p 3000:3000端口映射（主机端口:容器端口）3000:3000--restart=always容器异常退出时自动重启alwaysAI_PROVIDERAI服务提供商deepseekAI_MODEL使用的AI模型deepseek-chatDEEPSEEK_API_KEYDeepSeek API密钥sk-...--name容器名称next-ai-draw-io高级配置选项1. 持久化数据存储（推荐）# 创建数据目录 mkdir -p /home/next-ai-draw-io/data # 部署带数据持久化的容器 docker run -d \ -p 3000:3000 \ --restart=always \ -e AI_PROVIDER=deepseek \ -e AI_MODEL=deepseek-chat \ -e DEEPSEEK_API_KEY=sk-xxx \ -v /home/next-ai-draw-io/data:/app/data \ --name next-ai-draw-io \ ghcr.io/dayuanjiang/next-ai-draw-io:latest2. 多AI提供商支持除了DeepSeek，还支持以下AI提供商：# 使用OpenAI docker run -d \ -p 3000:3000 \ --restart=always \ -e AI_PROVIDER=openai \ -e AI_MODEL=gpt-4 \ -e OPENAI_API_KEY=your-openai-api-key \ --name next-ai-draw-io \ ghcr.io/dayuanjiang/next-ai-draw-io:latest # 使用Anthropic Claude docker run -d \ -p 3000:3000 \ --restart=always \ -e AI_PROVIDER=anthropic \ -e AI_MODEL=claude-3-opus-20240229 \ -e ANTHROPIC_API_KEY=your-anthropic-api-key \ --name next-ai-draw-io \ ghcr.io/dayuanjiang/next-ai-draw-io:latest3. 自定义配置环境变量docker run -d \ -p 3000:3000 \ --restart=always \ -e AI_PROVIDER=deepseek \ -e AI_MODEL=deepseek-chat \ -e DEEPSEEK_API_KEY=sk-xxx \ -e MAX_FILE_SIZE=10485760 \ # 最大文件大小（10MB） -e SESSION_SECRET=your-secret-key \ # 会话密钥 -e LOG_LEVEL=info \ # 日志级别 --name next-ai-draw-io \ ghcr.io/dayuanjiang/next-ai-draw-io:latest访问和使用1. 访问Web界面部署完成后，通过浏览器访问：http://你的服务器IP:30002. AI功能使用示例Next AI Draw.io 提供以下AI增强功能：智能图表生成：用自然语言描述图表，AI自动生成文本转图表：将文本描述转换为流程图、时序图等图表优化建议：AI分析现有图表并提供改进建议代码生成：从图表生成对应代码框架3. API接口使用// 示例：使用AI生成图表 fetch('http://localhost:3000/api/ai/generate', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON…

Docker 私有镜像仓库 Registry 部署与管理
type: item
date: 2025-11-01T03:58:00+00:00
description: Docker 私有镜像仓库 Registry 部署与管理一、快速部署命令基础部署docker run -d \ -p 5000:5000 \ -v /home/registry:/var/lib/registry \ --restart always \ --name registry \ registry:2参数解析参数说明重要性-p 5000:5000端口映射（主机:容器）必选-v /home/registry数据持久化目录强烈推荐--restart always自动重启策略生产环境建议registry:2官方Registry v2镜像必选二、配置优化与自定义1. 进入容器修改配置# 进入容器 docker exec -it registry sh # 编辑配置文件 vi /etc/docker/registry/config.yml2. 完整配置文件示例version: 0.1 log: fields: service: registry # 存储配置 storage: delete: enabled: true # 启用删除功能 cache: blobdescriptor: inmemory # 内存缓存 filesystem: rootdirectory: /var/lib/registry # 存储根目录 # HTTP服务配置 http: addr: :5000 # 监听端口 headers: X-Content-Type-Options: [nosniff] Access-Control-Allow-Origin: ['*'] # 允许跨域 Access-Control-Allow-Methods: ['HEAD','GET','OPTIONS','DELETE'] Access-Control-Allow-Headers: ['Authorization','Accept'] Access-Control-Expose-Headers: ['Docker-Content-Digest'] # 健康检查 health: storagedriver: enabled: true interval: 10s # 检查间隔 threshold: 3 # 失败阈值3. 重启服务# 退出容器 exit # 重启Registry docker restart registry # 验证重启状态 docker logs --tail 10 registry三、生产环境增强配置1. 带认证的部署# config.yml 中添加认证配置 http: addr: :5000 auth: htpasswd: realm: Registry Realm path: /auth/htpasswd创建认证文件：# 生成密码文件 docker run --entrypoint htpasswd \ registry:2 -Bbn username password > auth/htpasswd # 重新部署带认证的容器 docker run -d \ -p 5000:5000 \ -v /home/registry:/var/lib/registry \ -v $(pwd)/auth:/auth \ -e REGISTRY_AUTH=htpasswd \ -e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ --restart always \ --name registry \ registry:22. HTTPS安全配置# 准备SSL证书 mkdir -p /home/registry/certs # 将证书放入 certs 目录 # 启动带HTTPS的Registry docker run -d \ -p 5000:5000 \ -v /home/registry:/var/lib/registry \ -v /home/registry/certs:/certs \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ --restart always \ --name registry \ registry:23. 性能优化配置# config.yml 添加性能相关配置 storage: filesystem: maxthreads: 100 # 最大线程数 cache: blobdescriptor: redis # 使用Redis缓存 redis…

使用PyInstaller将Python图形界面程序打包成EXE文件完整指南
type: item
date: 2025-09-03T10:11:00+00:00
description: 使用PyInstaller将Python图形界面程序打包成EXE文件完整指南前言在日常开发中，我们经常需要将Python程序分享给没有Python环境的用户。PyInstaller是一个强大的工具，可以将Python程序打包成独立的可执行文件。本文将详细介绍如何使用PyInstaller打包图形界面程序，特别是基于PyQt5的应用程序。环境准备安装必要的库首先确保安装了所需的Python库：pip install pyqt5 matplotlib numpy pyinstaller如果遇到网络问题，可以使用国内镜像源：pip install pyqt5 matplotlib numpy pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple/示例程序：时间戳文件生成器下面是一个完整的PyQt5应用程序示例，功能包括生成时间戳命名的文件和文件夹：import sys import os from datetime import datetime from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QFileDialog, QWidget, QMessageBox) from PyQt5.QtCore import Qt import matplotlib.pyplot as plt import numpy as np class TimestampGeneratorApp(QMainWindow): def __init__(self): super().__init__() self.selected_directory = "" self.current_sidewindow_folder = "" self.initUI() def initUI(self): # 界面初始化代码 self.setWindowTitle('时间戳文件生成器') self.setGeometry(300, 300, 500, 300) central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout() central_widget.setLayout(main_layout) # 目录选择区域 dir_layout = QHBoxLayout() self.dir_label = QLabel('未选择目录') self.dir_label.setStyleSheet("QLabel { background-color: #f0f0f0; padding: 8px; border: 1px solid #ccc; }") self.dir_label.setMinimumHeight(40) select_dir_btn = QPushButton('选择目录') select_dir_btn.clicked.connect(self.select_directory) select_dir_btn.setMinimumHeight(40) dir_layout.addWidget(self.dir_label, 4) dir_layout.addWidget(select_dir_btn, 1) # 功能按钮区域 btn_layout = QVBoxLayout() self.generate_image_btn = QPushButton('生成卡口图片') self.generate_image_btn.setMinimumHeight(50) self.generate_image_btn.clicked.connect(self.generate_timestamp_image) self.generate_image_btn.setStyleSheet("QPushButton { background-color: #4CAF50; color: white; font-size: 14px; }") self.generate_folder_btn = QPushButton('生成侧窗文件夹') self.generate_folder_btn.setMinimumHeight(50) self.generate_folder_btn.clicked.connect(self.generate_timestamp_folder) self.generate_folder_btn.setStyleSh…

Docker之EMQX部署：高可用MQTT消息服务器
type: item
date: 2025-09-01T09:47:00+00:00
description: Docker之EMQX部署：高可用MQTT消息服务器核心部署命令# 创建并授权数据目录 mkdir -p /home/emqx/data /home/emqx/log chown -R 1000:1000 /home/emqx/data /home/emqx/log # 启动EMQX容器 docker run -d \ --restart=always \ --name emqx \ -v /home/emqx/data:/opt/emqx/data \ -v /home/emqx/log:/opt/emqx/log \ -p 1883:1883 \ -p 8083:8083 \ -p 8084:8084 \ -p 8883:8883 \ -p 18083:18083 \ emqx/emqx:5.10.0端口详解端口协议用途说明1883MQTTTCP协议默认端口8083MQTTWebSocket协议端口8084MQTTSSL/TLS WebSocket端口8883MQTTSSL/TLS TCP协议端口18083HTTP管理控制台端口目录权限说明# 关键权限配置 chown -R 1000:1000 /home/emqx/data /home/emqx/log1000:1000：EMQX容器默认用户UID:GUID数据目录：存储运行状态、消息持久化数据日志目录：存储运行日志、错误日志生产环境优化配置1. 资源限制与网络优化docker run -d \ --restart=always \ --name emqx \ --memory=2g \ --cpus=2 \ --network=host \ # 高性能场景使用host模式 -v /home/emqx/data:/opt/emqx/data \ -v /home/emqx/log:/opt/emqx/log \ -v /home/emqx/etc:/opt/emqx/etc \ # 挂载配置文件 -p 1883:1883 \ -p 18083:18083 \ emqx/emqx:5.10.02. 自定义配置文件# 创建配置目录 mkdir -p /home/emqx/etc # 生成默认配置 docker run --rm emqx/emqx:5.10.0 cat /opt/emqx/etc/emqx.conf > /home/emqx/etc/emqx.conf # 关键配置修改 echo " # 允许匿名连接（生产环境建议关闭） mqtt.allow_anonymous = true # 最大连接数 mqtt.max_connections = 100000 # 消息大小限制（单位：字节） mqtt.max_packet_size = 10MB " >> /home/emqx/etc/emqx.conf访问验证1. 控制台访问地址：http://服务器IP:18083默认账号：admin默认密码：public2. 服务健康检查# 检查容器状态 docker ps | grep emqx # 查看服务日志 docker logs -f emqx # 测试MQTT连接 docker exec -it emqx emqx ctl status集群部署方案1. 多节点集群配置# 节点1 docker run -d --name emqx1 \ -e EMQX_NODE_NAME=emqx@node1 \ -e EMQX_CLUSTER__DISCOVERY_STRATEGY=static \ -e EMQX_CLUSTER__STATIC__SEEDS="[emqx@node1,emqx@node2]" \ emqx/emqx:5.10.0 # 节点2 docker run -d --name emqx2 \ -e EMQX_NODE_NAME=emqx@node2 \ -e EMQX_CLUSTER__DISCOVERY_STRATEGY=static \ -e EMQX_CLUSTER__STATIC__SEEDS="[emqx@node1,emqx@node2]" \ emqx/emqx:5.10.02. Kubernetes部署apiVersion: apps/v1 kind: StatefulSet metadata: name: emqx spec: serviceName: emqx replicas: 3 template: spec: containers: - name: emqx image: emqx/emqx:5.10.0 env: - name: EMQX_NODE_NAME value: "emqx@$(POD_NAME).emqx"安全加固建议…

Java单例模式实现与最佳实践
type: item
date: 2025-08-01T11:56:00+00:00
description: Java单例模式实现与最佳实践单例模式是Java设计模式中最常用但也最容易用错的一种，本文将深入探讨各种实现方式、原理及其在真实场景下的应用。什么是单例模式？单例模式（Singleton Pattern）确保一个类只有一个实例，并提供一个全局访问点。这在需要控制资源访问、配置管理、线程池等场景中非常有用。基础实现方式1. 饿汉式（Eager Initialization）public class EagerSingleton { // 类加载时就创建实例 private static final EagerSingleton INSTANCE = new EagerSingleton(); // 私有构造方法防止外部实例化 private EagerSingleton() { // 防止反射攻击 if (INSTANCE != null) { throw new RuntimeException("单例对象已被创建！"); } } // 全局访问点 public static EagerSingleton getInstance() { return INSTANCE; } // 业务方法示例 public void doSomething() { System.out.println("饿汉式单例方法执行"); } }优点：实现简单，线程安全无锁性能高缺点：类加载时就创建，可能造成资源浪费不能延迟加载2. 懒汉式（Lazy Initialization）public class LazySingleton { private static LazySingleton instance; private LazySingleton() { // 防止反射攻击 if (instance != null) { throw new RuntimeException("单例对象已被创建！"); } } // 基础懒加载 - 线程不安全！ public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } }线程安全的单例实现3. 同步方法懒汉式public class SynchronizedSingleton { private static SynchronizedSingleton instance; private SynchronizedSingleton() {} // 线程安全但性能差 public static synchronized SynchronizedSingleton getInstance() { if (instance == null) { instance = new SynchronizedSingleton(); } return instance; } }缺点： 每次获取实例都需要同步，性能瓶颈4. 双重检查锁（Double-Checked Locking）public class DoubleCheckedSingleton { // 使用volatile防止指令重排序 private static volatile DoubleCheckedSingleton instance; private DoubleCheckedSingleton() { if (instance != null) { throw new RuntimeException("单例对象已被创建！"); } } public static DoubleCheckedSingleton getInstance() { if (instance == null) { // 第一次检查 synchronized (DoubleCheckedSingleton.class) { if (instance == null) { // 第二次检查 instance = new DoubleCheckedSingleton(); } } } return instance; } }关键点：volatile 关键字防止指令重排序两次null检查确保线程安全只在第一次创建时同步，性能较好推荐的实现方式5. 静态内部类（Static Inner Class）public class InnerClassSingleton { private InnerClassSingleton() { // 防止反射攻击 if (SingletonHolder.INSTANCE != null) { throw new RuntimeException("单例对象已被创建！");…

分布式并发控制五大方案与实践指南
type: item
date: 2025-06-26T03:58:00+00:00
description: 分布式并发控制的五大核心方案与实践在分布式系统中，如何有效控制并发操作是保证系统一致性和可靠性的关键挑战。本文将深入探讨分布式并发控制的五大核心技术方案，包括实现细节、适用场景和最佳实践。1. 分布式锁的实现方案1.1 Redisson实现Redisson是基于Redis的Java客户端，提供了丰富的分布式锁功能：// 获取锁 RLock lock = redisson.getLock("orderLock"); try { // 尝试加锁，最多等待100秒，上锁后30秒自动解锁 boolean res = lock.tryLock(100, 30, TimeUnit.SECONDS); if (res) { // 业务逻辑 } } finally { lock.unlock(); }关键特性：Watchdog机制自动续期（默认30秒续期一次）可重入锁设计支持公平锁和非公平锁提供联锁（MultiLock）和红锁（RedLock）实现1.2 Zookeeper实现Zookeeper通过临时顺序节点实现分布式锁：InterProcessMutex lock = new InterProcessMutex(client, "/locks/order"); try { if (lock.acquire(30, TimeUnit.SECONDS)) { // 业务逻辑 } } finally { lock.release(); }实现原理：实践建议：Redis锁适合高性能场景，Zookeeper锁适合强一致性要求场景必须设置合理的锁超时时间，避免死锁实现锁的自动续期机制，防止业务未完成锁已过期考虑锁的可重入性，避免同一线程多次获取锁导致死锁2. 分布式乐观锁变种实现传统乐观锁在分布式环境下需要特殊处理：2.1 基于版本号的实现// 更新时检查版本号 UPDATE products SET stock = stock - 1, version = version + 1 WHERE id = 1001 AND version = 5;2.2 基于CAS的分布式实现// Redis Lua脚本实现CAS String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " + " return redis.call('set', KEYS[1], ARGV[2]) " + "else " + " return 0 " + "end"; Long result = redisTemplate.execute( new DefaultRedisScript<>(script, Long.class), Collections.singletonList("product:1001"), oldVersion, newVersion);实践建议：高并发场景下乐观锁可能导致大量重试，需配合限流使用版本号字段需建立索引提高查询效率考虑使用时间戳+随机数组合作为版本号，降低冲突概率对于读多写少场景，乐观锁性能优势明显3. 分布式事务的CAP妥协方案3.1 常见分布式事务模式对比模式一致性可用性分区容错适用场景2PC强一致低中传统银行交易TCC最终高高电商订单SAGA最终高高长事务流程本地消息表最终高高异步通知场景最大努力通知弱高高非核心业务3.2 Seata框架实现AT模式示例@GlobalTransactional public void purchase(String userId, String commodityCode, int orderCount) { // 1. 创建订单 orderService.create(userId, commodityCode, orderCount); // 2. 扣减库存 storageService.deduct(commodityCode, orderCount); // 3. 扣减余额 accountService.debit(userId, orderCount * price); }执行流程：实践建议：根据业务容忍度选择合适的事务模式2PC适合短事务，SAGA适合长事务事务日志需要持久化存储设置合理的事务超时时间，避免资源长时间占用4. 分库分表下的并发控制4.1 全局ID生成策略// Snowflake算法实现 public synchronized long nextId() { long timestamp = timeGen(); if (timestamp < lastTimestamp) { throw new RuntimeException("时钟回拨异常"); } if (lastTimestamp == timest…

欢迎来到我的博客
type: item
date: 2025-06-26T00:59:00+00:00
description: 个人随笔，记录，复用逐渐的将个人笔记一些笔记搬到博客上

Git提交记录导出全攻略：从基础命令到高级技巧
type: item
date: 2025-01-07T11:57:00+00:00
description: 在日常开发和项目管理中，导出和分析Git提交记录是一项常见但重要的任务。本文将带你全面掌握Git提交记录的导出技巧。为什么要导出Git提交记录？Git提交记录不仅仅是代码变更的历史，更是：项目进展跟踪：了解团队开发节奏和进度工作报告生成：为周报、月报提供数据支持代码审查辅助：分析代码变更模式和质量问题排查依据：追溯bug引入的时间和原因基础导出命令1. 基本提交记录导出# 导出最近的100条提交记录 git log -n 100 > commit_log.txt # 导出指定时间范围的记录 git log --since="2025-01-01" --until="2025-11-21" > commit_log.txt2. 简洁单行格式# 单行显示，更紧凑的格式 git log --oneline -n 100 > commit_log.txt # 带分支图的单行显示 git log --oneline --graph -n 100 > commit_log.txt高级筛选与过滤1. 按作者筛选# 导出特定作者的提交 git log --since="2025-01-01" --author="zhangsan" > zhangsan_commits.txt # 按邮箱筛选 git log --author=".*@company.com" > company_commits.txt2. 按文件路径筛选# 只关注特定目录的变更 git log --since="2025-01-01" -- src/ > src_changes.txt # 关注特定文件的变更历史 git log -- README.md > readme_history.txt3. 按提交信息筛选# 搜索包含特定关键词的提交 git log --grep="bugfix" --since="2025-01-01" > bugfixes.txt # 同时排除某些关键词 git log --grep="feature" --invert-grep --since="2025-01-01" > no_feature_commits.txt自定义输出格式1. 格式化输出# 自定义输出格式 git log --pretty=format:"%h - %an, %ad : %s" --date=short > formatted_log.txt # 更详细的格式 git log --pretty=format:"%C(yellow)%h%Creset %ad | %s%d [%an]" --graph --date=short > detailed_log.txt常用格式占位符：%h：简短提交哈希%an：作者姓名%ad：作者日期%s：提交说明%d：引用名称2. 提取特定信息# 只提取提交时间和描述（适合报告生成） git log --since="2025-01-01" --pretty=format:"%ad: %s" --date=short > simple_log.txt # 提取结构化数据（适合导入Excel） git log --pretty=format:'"%h","%an","%ad","%s"' --date=short > commits.csv实战案例：规范化提交记录的提取在实际项目中，我们通常使用规范化的提交格式：案例：提取标准化提交信息# 假设提交格式为： # 【详细描述】：功能描述 【提交类型】：feat 【需求/问题单】：PROJ-123 # 提取所有功能需求 git log --since="2025-01-01" --pretty=format:"%s" | grep "【提交类型】：feat" > features.txt # 提取详细描述并去重 git log --since="2025-01-01" --pretty=format:"%s" | \ sed -n 's/.*【详细描述】：\([^【]*\).*/\1/p' | \ awk 'NF && !seen[$0]++' > unique_descriptions.txt性能优化技巧1. 限制输出范围提升性能# 只获取最近一年的记录（提升大仓库性能） git log --since="1 year ago" --oneline > recent_commits.txt # 使用--simplify-by-decoration加速 git log --oneline --simplify-by-decoration -n 1000 > important_commits.txt2. 分批导出大量记录# 分批导出，避免内存问题 git log --since="2024-01-…