分类 后端 下的文章 - CorePlayers
首页
我的项目
708 智能控制台
Ethan认证中心
Ethan's ToDoList
Ethan's Tech Blog
好友链接
妙站分享
联系站长
搜 索
1
2026技术架构新趋势:从微服务回调到AI原生架构设计
45 阅读
2
DDD领域驱动设计:从底层原理到生产级全链路落地实战
41 阅读
3
Go + 云原生2026:从微服务到AI Infra的实战架构
35 阅读
4
事件驱动架构(EDA):从理论到项目落地的完整实践
34 阅读
5
2026 AI编程范式演进:从Vibe Coding到Spec-Driven Development再到Harness Engineering
31 阅读
ALL
(78)
AI
(20)
前端
(24)
后端
(23)
Dify/Coze
(7)
架构设计
(6)
登录
/
注册
搜 索
标签搜索
AI Agent
边缘计算
RSC
虚拟线程
Java
Spring Boot 4
Vibe Coding
AI原生
SDD
全栈开发
高并发
Project Loom
性能优化
2026趋势
协议标准
工具调用
MCP协议
多Agent协作
CrewAI
Spring AI
EthanCcc
累计撰写
78
篇文章
累计收到
1
条评论
首页
栏目
ALL
AI
前端
后端
Dify/Coze
架构设计
页面
我的项目
708 智能控制台
Ethan认证中心
Ethan's ToDoList
Ethan's Tech Blog
好友链接
妙站分享
联系站长
用户登录
登录
注册
后端
2025-06-05
Redis + Caffeine 多级缓存架构与分布式锁实战
缓存是高并发系统的基石。单靠 Redis 已经不足以应对极致性能需求——本地缓存 + 分布式缓存的多级架构才是最优解。本文深入 Redis 核心机制、Caffeine 本地缓存、多级缓存设计和分布式锁实战。Redis 核心数据结构与使用场景 数据结构底层实现典型场景 StringSDS缓存对象、计数器、分布式锁 Hashziplist / hashtable存储对象属性 Listquicklist消息队列、最新列表 Setinset / hashtable标签、共同好友 ZSetziplist / skiplist排行榜、延迟队列 Streamradix tree + listpack消息队列(支持消费组) 缓存穿透、击穿、雪崩:三板斧1. 缓存穿透:查不存在的数据// 布隆过滤器 BF.RESERVE userFilter 0.01 1000000 BF.ADD userFilter "user:999999" // 查询前先判断布隆过滤器:不存在则直接拒绝 // 缓存空值 String value = redis.get(key); if (value == null) { value = db.query(key); if (value == null) { redis.setex(key, 60, "NULL"); // 缓存空值 60 秒 return null; } redis.set(key, value, 300); }2. 缓存击穿:热点 Key 过期public String getWithMutex(String key) { String value = redis.get(key); if (value != null) return value; String lockKey = "lock:" + key; if (redis.setnx(lockKey, "1")) { redis.expire(lockKey, 10); try { value = db.query(key); redis.set(key, value, 300); } finally { redis.del(lockKey); } return value; } else { Thread.sleep(50); return getWithMutex(key); // 递归重试 } }3. 缓存雪崩:大量 Key 同时过期// TTL 加随机偏移 int ttl = 300 + ThreadLocalRandom.current().nextInt(60); // 300~360秒 redis.setex(key, ttl, value); // 多级缓存兜底 public Object get(String key) { Object val = caffeine.get(key); // L1: 本地缓存 if (val != null) return val; val = redis.get(key); // L2: Redis if (val != null) { caffeine.put(key, val); // 回填 L1 return val; } val = db.query(key); // L3: 数据库 redis.set(key, val, ttl + random(60)); // 回填 L2 caffeine.put(key, val); // 回填 L1 return val; }Caffeine 本地缓存配置Cache<String, Object> cache = Caffeine.newBuilder() .maximumSize(10000) // 最大条目数 .expireAfterWrite(5, TimeUnit.MINUTES) .expireAfterAccess(3, TimeUnit.MINUTES) .recordStats() // 开启统计(命中率监控) .build();Redis 分布式锁:Redisson 实战@Autowired private RedissonClient redisson; public void processOrder(String orderId) { RLock lock = redisson.getLock("order:" + orderId); try { // 尝试加锁,最多等待 10 秒,锁 30 秒后自动释放 if (lock.tryLock(10, 30, TimeUnit.SECONDS)) { // 业务逻辑 orderService.process(orderId); } } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } } } // Redisson 的 WatchDog 机制:自动续期 // 如果业务还没执行完,WatchDog 每隔 10 秒自动续期到 30 秒Redis 哨兵集群搭建# sentinel.conf sentinel monitor mymaster 192.168.1.10 6379 2 # 2 个哨兵同意才判定下线 sentinel down-after-milliseconds mymaster 5000 # 5 秒无响应判定主观下线 sentinel failover-timeout mymaster 60000 # 故障转移超时 60 秒 sentinel parallel-syncs mymaster 1 # 一次只同步一台新主库总结多级缓存架构的核心思想是"近处快,远处稳"。Caffeine 提供微秒级响应但空间有限,Redis 提供毫秒级响应且可共享,数据库是最后的兜底。分布式锁的关键在于原子性(SETNX)、防死锁(过期时间)、防误删(Lua 脚本校验值)和可重入(Redisson WatchDog)。
2025年06月05日
10
0
1
2025-05-17
Rust vs Go:2025 微服务性能基准测试深度对比
在构建微服务架构时,Rust 和 Go 是两个最受关注的后端语言选择。本文基于 2025 年最新版本(Rust 1.75 和 Go 1.22)的实际基准测试,深入对比两者在微服务场景下的性能表现。测试环境 组件规格 CPUAMD Ryzen 9 7950X (16核32线程) 内存64GB DDR5-6000 系统Ubuntu 24.04 LTS Rust1.75.0 (Axum框架) Go1.22.3 (Gin框架) HTTP 服务性能对比 指标Rust (Axum)Go (Gin)差异 吞吐量 (req/s)187,450142,380Rust +31.7% P50 延迟 (ms)0.520.68Rust -23.5% P99 延迟 (ms)1.271.85Rust -31.4% 内存使用 (MB)18.327.6Rust -33.7% 关键性能差异分析1. P99 延迟尖峰问题Go 在 P99 延迟上出现了明显的尖峰,主要原因是垃圾回收(GC)的 Stop-The-World 暂停。尽管 Go 1.22 显著改进了 GC 延迟,但在高并发场景下仍可观察到周期性的延迟抖动。Rust 的无 GC 所有权模型从根本上避免了这一问题。2. 内存使用效率Rust 的零成本抽象模型使其在内存使用上比 Go 节省约 33.7%。对于大规模部署而言,这意味着在相同硬件上可以运行更多实例,直接转化为云成本的节约。3. 并发处理能力Go 的 Goroutine 调度器极为高效,10,000 个并发连接的测试中两者均表现优异。但在 CPU 密集型计算场景下,Rust 的 async/await 模型展现出更好的可预测性能。Rust 常见陷阱 学习曲线陡峭:所有权和生命周期概念需要时间消化 编译时间较长:大型项目的增量编译仍需优化 异步生态碎片化:需要在 Tokio、async-std 等运行时之间做选择 Go 常见陷阱 GC 延迟抖动:对延迟敏感的应用需特别注意 零值陷阱:nil 指针和零值可能导致隐蔽的 bug 没有枚举类型:缺乏完善的代数数据类型支持 选型建议选择 Rust 的场景:需要极致性能和可预测延迟的系统级组件、高频交易系统、边缘计算节点、数据密集型管道处理。选择 Go 的场景:快速迭代的 API 服务、团队开发效率优先的项目、需要简单运维的云原生微服务、初创团队的 MVP 开发。
2025年05月17日
10
0
1
2025-05-10
MySQL 性能调优实战:索引优化、SQL 调优与分库分表策略
数据库性能问题是后端开发中最常见的瓶颈。然而,很多开发者的"优化"就是在字段上加个索引——然后发现还是慢。本文将系统梳理 MySQL 性能调优的三个核心维度:索引优化、SQL 调优和分库分表,并介绍 Druid 监控工具的使用。索引优化的本质:数据结构的选择B+Tree 为什么是 MySQL 的首选?B+Tree 的所有数据都存在叶子节点,非叶子节点只存索引——这让单次磁盘 I/O 能检索更多索引键。在 16KB 的 InnoDB 页中,假设主键是 BIGINT(8字节)+ 指针(6字节),一个非叶子节点大约能存 16KB / 14B ≈ 1170 个索引键。三层 B+Tree(根→中间→叶子)约能索引 1170 × 1170 × 16 ≈ 两千万行。这意味着绝大多数 OLTP 查询只需 1~3 次磁盘 I/O。最左前缀原则:面试必问CREATE INDEX idx_a_b_c ON users(a, b, c); -- 走索引(匹配最左前缀) SELECT * FROM users WHERE a = 1; SELECT * FROM users WHERE a = 1 AND b = 2; -- 不走索引(跳过了 a) SELECT * FROM users WHERE b = 2; SELECT * FROM users WHERE c = 3; -- 部分走索引(a 走索引,c 不走) SELECT * FROM users WHERE a = 1 AND c = 3;索引失效的常见场景-- 1. 函数操作(索引列参与计算) SELECT * FROM orders WHERE DATE(create_time) = '2025-01-01'; -- 失效! -- 改为:WHERE create_time >= '2025-01-01' AND create_time < '2025-01-02'; -- 2. 隐式类型转换 SELECT * FROM users WHERE phone = 13800138000; -- phone 是 VARCHAR,失效! -- 3. LIKE 前置模糊 SELECT * FROM articles WHERE title LIKE '%MySQL%'; -- 完全失效 -- 4. OR 条件不全有索引 SELECT * FROM users WHERE name = 'ABC' OR age = 25; -- age 没有索引覆盖索引:最优雅的性能优化CREATE INDEX idx_name_age ON users(name, age); SELECT name, age FROM users WHERE name = 'ABC'; -- 不需要回表!SQL 执行计划分析(EXPLAIN 必看项)EXPLAIN SELECT * FROM orders WHERE user_id = 100 AND status = 'paid'; -- 关键指标 -- type: const > eq_ref > ref > range > index > ALL(绝对不能出现 ALL) -- key: 实际使用的索引 -- rows: 扫描行数(越小越好) -- Extra: Using filesort / Using temporary(出现就说明需要优化)慢查询分析:找到瓶颈-- 开启慢查询日志 SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 1; -- 用 mysqldumpslow 分析 mysqldumpslow -s t -t 10 /var/log/mysql/slow.logDruid SQL 监控// Spring Boot 集成 Druid spring: datasource: druid: stat-view-servlet: enabled: true url-pattern: /druid/* login-username: admin login-password: admin filter: stat: enabled: true slow-sql-millis: 1000 log-slow-sql: true通过 /druid/index.html 可视化查看:SQL 执行次数、耗时分布、连接池状态、慢查询列表。分库分表策略垂直分库:按业务拆分用户库(user_db)、订单库(order_db)、商品库(product_db),各库独立部署、独立扩容。水平分表:ShardingSphere-JDBC 配置# sharding.yml rules: - !SHARDING tables: t_order: actualDataNodes: ds0.t_order_$-> databaseStrategy: standard: shardingColumn: user_id shardingAlgorithmName: db_inline tableStrategy: standard: shardingColumn: order_id shardingAlgorithmName: order_inline shardingAlgorithms: db_inline: type: INLINE props: algorithm-expression: ds$-> order_inline: type: INLINE props: algorithm-expression: t_order_$->总结MySQL 优化有一个优先级:SQL 优化 > 索引优化 > 架构优化。大多数性能问题的根源在于糟糕的 SQL 和缺失的索引,而不是"数据库配置参数不够好"。Druid 监控是你发现这些问题的眼睛,而分库分表是最后的底牌——在此之前,请先确保 SQL 和索引已经做到最好。
2025年05月10日
10
0
1
2025-04-22
Go 1.24 泛型新特性与生产实战
Go 1.24 在 2025 年初发布,泛型特性迎来了第二次重大迭代。从 Go 1.18 的泛型初版到如今的 1.24,泛型已经从"实验性功能"进化为了"生产级基础设施"。本文将从实战角度解析 Go 1.24 泛型的最佳实践。Go 1.24 泛型新特性1. 类型推断增强:Go 1.24 显著改进了泛型函数的类型推断能力,大部分场景下不再需要显式指定类型参数。// Go 1.21 需要显式指定类型 result := Map[int, string](nums, strconv.Itoa) // Go 1.24 自动推断 result := Map(nums, strconv.Itoa)2. Range over func:迭代器模式正式进入标准库,使得泛型集合可以无缝使用 for-range 循环。3. 标准库泛型化:slices、maps、cmp 等包新增了大量泛型工具函数,大幅减少重复代码。实战:构建类型安全的泛型仓库层在典型的三层架构中,每个实体的 CRUD 操作通常高度相似。使用 Go 1.24 泛型可以消除这些重复:type Repository[T any, ID comparable] interface 通过泛型接口和实现,原本需要为每个实体(User、Order、Product 等)重复编写的 200+ 行仓储代码可以压缩为一个通用实现。性能考量Go 的泛型在编译时进行单态化(monomorphization),这意味着每个具体类型会生成独立的代码,不存在运行时开销。但这也意味着编译时间和二进制大小会有所增加。在我们的测试中,泛型化后的仓库层代码量减少了 60%,而二进制大小仅增加了 3.2%,编译时间增加 8%。
2025年04月22日
11
0
1
2025-04-15
Spring Boot 3 + Spring Cloud 微服务架构实战:从单体拆分到服务治理
微服务架构不是银弹,但它确实是解决大型项目复杂性的最有效手段之一。本文将带你从实践角度出发,使用 Spring Boot 3 和 Spring Cloud 2023+ 版本,完成一个微服务项目的拆分与治理。微服务拆分的核心原则DDD 限界上下文是微服务拆分的最佳指导:每个微服务对应一个限界上下文,有自己的领域模型。拆分的黄金法则是"高内聚、低耦合"——如果一个功能的修改总是同时改两个服务,说明它们不应该被拆分。避免微服务"死亡三角":拆分过细(300+ 个微服务但每个只有几百行代码)、拆分过粗(一个"核心服务"包含了 80% 的业务逻辑)、错误拆分(按技术层拆分:Controller 服务、Service 服务、DAO 服务)。Spring Cloud 微服务组件全景[网关层] Spring Cloud Gateway(路由、限流、鉴权) [注册中心] Nacos / Consul(服务发现与配置管理) [配置中心] Nacos Config(动态配置刷新) [熔断降级] Resilience4j / Sentinel(断路器、限流) [负载均衡] Spring Cloud LoadBalancer [远程调用] OpenFeign(声明式 HTTP 客户端) [链路追踪] Micrometer Tracing + Zipkin [消息驱动] Spring Cloud Stream + RocketMQ/Kafka服务注册与发现:Nacos 集成// bootstrap.yml spring: application: name: order-service cloud: nacos: discovery: server-addr: localhost:8848 namespace: prod group: ORDER_GROUP config: server-addr: localhost:8848 file-extension: yaml shared-configs: - data-id: common.yaml group: DEFAULT_GROUP refresh: trueOpenFeign 声明式远程调用// 服务消费方 - 声明式接口 @FeignClient(name = "user-service", path = "/api/users", fallbackFactory = UserClientFallbackFactory.class) public interface UserClient { @GetMapping("/") Result<User> getUser(@PathVariable("id") Long id); } // 使用:像调用本地方法一样调用远程服务 @RestController public class OrderController { @Autowired private UserClient userClient; @GetMapping("/api/orders/") public Result<OrderDetail> getOrder(@PathVariable Long id) { Order order = orderService.getById(id); Result<User> user = userClient.getUser(order.getUserId()); return Result.success(new OrderDetail(order, user.getData())); } }Gateway 网关:统一入口与过滤spring: cloud: gateway: routes: - id: user-service uri: lb://user-service predicates: - Path=/api/users/** filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 100 redis-rate-limiter.burstCapacity: 200 - id: order-service uri: lb://order-service predicates: - Path=/api/orders/** filters: - AuthFilterSentinel 熔断降级@SentinelResource(value = "getUser", blockHandler = "getUserBlockHandler") public User getUser(Long id) { return userMapper.selectById(id); } public User getUserBlockHandler(Long id, BlockException e) { return new User(id, "降级默认用户"); // 降级兜底 }分布式事务:Seata 集成@GlobalTransactional public void createOrder(OrderDTO dto) { orderService.create(dto); // 本地事务 inventoryClient.deduct(dto.getItems()); // Feign 远程调用扣减库存 accountClient.charge(dto.getUserId(), dto.getAmount()); // 远程扣款 } // Seata 通过 TC + TM + RM 实现 AT 模式下的自动补偿总结微服务架构的核心挑战不在技术,而在组织——分布式事务的最终一致性、服务间的数据一致性、跨服务的调试和追踪,这些问题的解决方案都在 "治理" 而不是 "代码" 层面。一个好的微服务架构应该是渐进式拆分的:先把单体写好,在业务增长需要的时候再逐步拆出服务。
2025年04月15日
11
0
1
1
...
3
4
5