<!DOCTYPE html><html lang="zh-CN"><head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Redisson:超越简单客户端的分布式系统利器</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
<style>
:root {
--primary: #1e293b;
--secondary: #475569;
--accent: #3b82f6;
--muted: #64748b;
--background: #f8fafc;
--surface: #ffffff;
--border: #e2e8f0;
}
body {
font-family: 'Inter', sans-serif;
background: var(--background);
color: var(--primary);
line-height: 1.7;
overflow-x: hidden;
}
img {
max-width: 100%;
height: auto;
}
.serif {
font-family: 'Playfair Display', serif;
}
.toc-fixed {
position: fixed;
top: 0;
left: 0;
width: 280px;
height: 100vh;
background: var(--surface);
border-right: 1px solid var(--border);
overflow-y: auto;
z-index: 50;
padding: 2rem 1.5rem;
box-shadow: 2px 0 10px rgba(0,0,0,0.05);
}
.main-content {
margin-left: 280px;
min-height: 100vh;
}
.hero-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
align-items: center;
min-height: 60vh;
}
.bento-card {
background: var(--surface);
border-radius: 16px;
padding: 2rem;
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
border: 1px solid var(--border);
}
.chart-container {
background: var(--surface);
border-radius: 12px;
padding: 2rem;
margin: 2rem 0;
box-shadow: 0 2px 15px rgba(0,0,0,0.05);
border: 1px solid var(--border);
}
.citation {
color: var(--accent);
text-decoration: none;
font-weight: 500;
border-bottom: 1px dotted var(--accent);
}
.citation:hover {
background: rgba(59, 130, 246, 0.1);
padding: 2px 4px;
border-radius: 4px;
}
.section-header {
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
color: white;
padding: 4rem 0;
margin-bottom: 3rem;
}
.code-block {
background: #1e293b;
color: #e2e8f0;
border-radius: 8px;
padding: 1.5rem;
overflow-x: auto;
font-family: 'Monaco', 'Menlo', monospace;
font-size: 0.9rem;
line-height: 1.6;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.feature-card {
background: var(--surface);
border-radius: 12px;
padding: 1.5rem;
border: 1px solid var(--border);
transition: all 0.3s ease;
}
.feature-card:hover {
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
transform: translateY(-2px);
}
.comparison-table {
width: 100%;
border-collapse: collapse;
margin: 2rem 0;
background: var(--surface);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 15px rgba(0,0,0,0.05);
}
.comparison-table th,
.comparison-table td {
padding: 1rem;
text-align: left;
border-bottom: 1px solid var(--border);
}
.comparison-table th {
background: var(--primary);
color: white;
font-weight: 600;
}
.comparison-table tr:hover {
background: rgba(59, 130, 246, 0.05);
}
.toc-link {
display: block;
padding: 0.5rem 0;
color: var(--secondary);
text-decoration: none;
border-left: 3px solid transparent;
padding-left: 1rem;
transition: all 0.3s ease;
}
.toc-link:hover,
.toc-link.active {
color: var(--accent);
border-left-color: var(--accent);
background: rgba(59, 130, 246, 0.05);
margin-left: -1rem;
padding-left: 2rem;
}
.toc-link.sub {
font-size: 0.9rem;
color: var(--muted);
padding-left: 2rem;
}
.toc-link.sub:hover {
padding-left: 3rem;
}
/* Mermaid Chart Styles */
.mermaid-container {
display: flex;
justify-content: center;
min-height: 300px;
max-height: 800px;
background: #ffffff;
border: 2px solid #e5e7eb;
border-radius: 12px;
padding: 30px;
margin: 30px 0;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.08);
position: relative;
overflow: hidden;
}
.mermaid-container .mermaid {
width: 100%;
max-width: 100%;
height: 100%;
cursor: grab;
transition: transform 0.3s ease;
transform-origin: center center;
display: flex;
justify-content: center;
align-items: center;
touch-action: none; /* 防止触摸设备上的默认行为 */
-webkit-user-select: none; /* 防止文本选择 */
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.mermaid-container .mermaid svg {
max-width: 100%;
height: 100%;
display: block;
margin: 0 auto;
}
.mermaid-container .mermaid:active {
cursor: grabbing;
}
.mermaid-container.zoomed .mermaid {
height: 100%;
width: 100%;
cursor: grab;
}
.mermaid-controls {
position: absolute;
top: 15px;
right: 15px;
display: flex;
gap: 10px;
z-index: 20;
background: rgba(255, 255, 255, 0.95);
padding: 8px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.mermaid-control-btn {
background: #ffffff;
border: 1px solid #d1d5db;
border-radius: 6px;
padding: 10px;
cursor: pointer;
transition: all 0.2s ease;
color: #374151;
font-size: 14px;
min-width: 36px;
height: 36px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-control-btn:hover {
background: #f8fafc;
border-color: #3b82f6;
color: #3b82f6;
transform: translateY(-1px);
}
.mermaid-control-btn:active {
transform: scale(0.95);
}
/* Enhanced mermaid node styling for better contrast */
.mermaid .node rect,
.mermaid .node circle,
.mermaid .node ellipse,
.mermaid .node polygon {
stroke: var(--primary) !important;
stroke-width: 2px !important;
}
.mermaid .node .label {
color: var(--primary) !important;
font-weight: 600 !important;
font-size: 14px !important;
}
.mermaid .edgePath .path {
stroke: var(--secondary) !important;
stroke-width: 2px !important;
}
.mermaid .edgeLabel {
background-color: var(--surface) !important;
color: var(--primary) !important;
font-weight: 500 !important;
border: 1px solid var(--border) !important;
border-radius: 4px !important;
padding: 2px 6px !important;
}
/* Improve text contrast for different node colors */
.mermaid .node[class*="fill-red"] .label,
.mermaid .node[class*="fill-yellow"] .label,
.mermaid .node[class*="fill-orange"] .label {
color: #ffffff !important;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5) !important;
}
<span class="mention-invalid">@media</span> (max-width: 1024px) {
.toc-fixed {
transform: translateX(-100%);
transition: transform 0.3s ease;
}
.toc-fixed.open {
transform: translateX(0);
}
.main-content {
margin-left: 0;
}
.mermaid-control-btn:not(.reset-zoom) {
display: none;
}
.mermaid-controls {
top: auto;
bottom: 15px;
right: 15px;
}
}
</style>
<base target="_blank">
</head>
<body>
<!-- Table of Contents -->
<nav class="toc-fixed">
<div class="mb-8">
<h3 class="serif text-xl font-bold text-gray-900 mb-4">目录导航</h3>
<div class="space-y-1">
<a href="#hero" class="toc-link">概述</a>
<a href="#architecture" class="toc-link">核心原理剖析</a>
<a href="#lock-mechanism" class="toc-link sub">分布式锁机制</a>
<a href="#watchdog" class="toc-link sub">看门狗机制</a>
<a href="#fair-lock" class="toc-link sub">公平锁实现</a>
<a href="#redis-objects" class="toc-link sub">分布式对象</a>
<a href="#comparison" class="toc-link">客户端对比分析</a>
<a href="#functional-comparison" class="toc-link sub">功能定位差异</a>
<a href="#performance" class="toc-link sub">性能考量</a>
<a href="#industry-cases" class="toc-link">行业应用案例</a>
<a href="#finance" class="toc-link sub">金融行业应用</a>
<a href="#ecommerce" class="toc-link sub">电商行业应用</a>
<a href="#iot" class="toc-link sub">物联网应用</a>
<a href="#best-practices" class="toc-link">最佳实践指南</a>
<a href="#configuration" class="toc-link sub">配置优化</a>
<a href="#lock-practices" class="toc-link sub">锁使用最佳实践</a>
<a href="#monitoring" class="toc-link sub">监控与排查</a>
</div>
</div>
<div class="border-t pt-4">
<p class="text-sm text-gray-500 mb-2">快速导航</p>
<div class="flex flex-wrap gap-2">
<span class="px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded">分布式锁</span>
<span class="px-2 py-1 bg-green-100 text-green-800 text-xs rounded">高可用</span>
<span class="px-2 py-1 bg-purple-100 text-purple-800 text-xs rounded">性能优化</span>
</div>
</div>
</nav>
<!-- Main Content -->
<main class="main-content">
<!-- Hero Section -->
<section id="hero" class="section-header">
<div class="container mx-auto px-8">
<div class="hero-grid">
<div>
<h1 class="serif text-5xl font-bold mb-6 leading-tight">
<em>Redisson</em>:超越简单客户端的
<br/>
<span class="text-blue-300">分布式系统利器</span>
</h1>
<p class="text-xl text-gray-200 mb-8 leading-relaxed">
基于Redis的Java分布式协调框架,为微服务架构提供企业级解决方案
</p>
<div class="flex items-center space-x-6">
<div class="flex items-center space-x-2">
<i class="fas fa-lock text-blue-300"></i>
<span class="text-sm">分布式锁</span>
</div>
<div class="flex items-center space-x-2">
<i class="fas fa-network-wired text-blue-300"></i>
<span class="text-sm">高可用</span>
</div>
<div class="flex items-center space-x-2">
<i class="fas fa-tachometer-alt text-blue-300"></i>
<span class="text-sm">高性能</span>
</div>
</div>
</div>
<div class="bento-card">
<img src="https://kimi-web-img.moonshot.cn/img/www.biaodianfu.com/675d080d550047752360616c411ae7238f1229aa.png" alt="抽象分布式网络节点连接图" class="w-full h-64 object-cover rounded-lg mb-4" size="medium" aspect="wide" query="抽象分布式网络节点" referrerpolicy="no-referrer" data-modified="1" data-score="0.00"/>
<div class="grid grid-cols-2 gap-4 text-sm">
<div class="text-center">
<div class="text-2xl font-bold text-blue-600">15+</div>
<div class="text-gray-600">分布式服务</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-green-600">100%</div>
<div class="text-gray-600">Java兼容</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Core Architecture -->
<section id="architecture" class="container mx-auto px-8 py-12">
<h2 class="serif text-4xl font-bold mb-8 text-center">核心实现原理深度剖析</h2>
<div class="prose max-w-none mb-12">
<p class="text-lg text-gray-600 leading-relaxed">
Redisson的强大之处不仅在于其丰富的API,更在于其对分布式系统核心问题的深刻理解和高超的工程实现。它并非简单地将Redis命令进行封装,而是通过一系列精妙的机制,解决了分布式环境下的并发、数据一致性和高可用性等难题。
</p>
</div>
<!-- Architecture Diagram -->
<div class="chart-container">
<h3 class="text-2xl font-bold mb-6">Redisson核心架构</h3>
<div class="mermaid-container">
<div class="mermaid-controls">
<button class="mermaid-control-btn zoom-in" title="放大">
<i class="fas fa-search-plus"></i>
</button>
<button class="mermaid-control-btn zoom-out" title="缩小">
<i class="fas fa-search-minus"></i>
</button>
<button class="mermaid-control-btn reset-zoom" title="重置">
<i class="fas fa-expand-arrows-alt"></i>
</button>
<button class="mermaid-control-btn fullscreen" title="全屏查看">
<i class="fas fa-expand"></i>
</button>
</div>
<div class="mermaid" id="architecture-diagram">
graph TB
A["Redisson Client"] --> B["Netty Framework"]
B --> C["Redis Connection Pool"]
B --> D["Command Executor"]
D --> E["Lua Script Engine"]
D --> F["Async Processor"]
A --> G["Distributed Objects"]
G --> H["RLock"]
G --> I["RMap"]
G --> J["RQueue"]
G --> K["RAtomicLong"]
H --> L["Watchdog Mechanism"]
E --> M["Redis Server"]
style A fill:#3b82f6,stroke:#1e40af,stroke-width:2px,color:#fff
style G fill:#10b981,stroke:#059669,stroke-width:2px,color:#fff
style H fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#fff
style L fill:#ef4444,stroke:#dc2626,stroke-width:2px,color:#fff
style M fill:#8b5cf6,stroke:#7c3aed,stroke-width:2px,color:#fff
</div>
</div>
</div>
<!-- Distributed Lock Mechanism -->
<div id="lock-mechanism" class="mb-16">
<h3 class="serif text-3xl font-bold mb-6">分布式锁的实现机制</h3>
<div class="grid lg:grid-cols-2 gap-8 mb-8">
<div class="bento-card">
<h4 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-key text-blue-600 mr-3"></i>
可重入锁(RLock)与Lua脚本
</h4>
<p class="text-gray-600 mb-4">
Redisson的可重入锁(RLock)通过Lua脚本实现原子操作,确保"检查-设置"这一系列操作的不可分割性。
<a href="https://www.cnblogs.com/Howinfun/p/15755551.html" class="citation" target="_blank">[147]</a>
</p>
<div class="code-block">
-- 加锁Lua脚本示例
if redis.call('exists', KEYS[1]) == 0 then
redis.call('hset', KEYS[1], ARGV[2], 1)
redis.call('pexpire', KEYS[1], ARGV[1])
return nil
end
if redis.call('hexists', KEYS[1], ARGV[2]) == 1 then
redis.call('hincrby', KEYS[1], ARGV[2], 1)
redis.call('pexpire', KEYS[1], ARGV[1])
return nil
end
return redis.call('pttl', KEYS[1])
</div>
</div>
<div class="bento-card">
<h4 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-shield-alt text-red-600 mr-3"></i>
原子性保障
</h4>
<p class="text-gray-600 mb-4">
Lua脚本在Redis服务器端原子执行,避免了因网络延迟或客户端故障导致的竞态条件,是实现可靠分布式锁的基石。
</p>
<div class="bg-blue-50 p-4 rounded-lg border-l-4 border-blue-500">
<p class="text-sm text-blue-800">
<strong>关键优势:</strong>通过EVAL命令保证操作的原子性,无需担心中间状态不一致问题。
</p>
</div>
</div>
</div>
</div>
<!-- Watchdog Mechanism -->
<div id="watchdog" class="mb-16">
<h3 class="serif text-3xl font-bold mb-6">看门狗(Watchdog)机制</h3>
<div class="feature-grid">
<div class="feature-card">
<h4 class="text-lg font-bold mb-3 flex items-center">
<i class="fas fa-clock text-orange-600 mr-2"></i>
自动续期机制
</h4>
<p class="text-gray-600 text-sm mb-3">
看门狗是一个后台定时任务,默认每10秒检查一次锁状态,通过Lua脚本重置锁的过期时间。
<a href="https://segmentfault.com/a/1190000041172633/en" class="citation" target="_blank">[336]</a>
</p>
<div class="bg-orange-50 p-3 rounded text-xs text-orange-800">
默认续期时间:30秒
</div>
</div>
<div class="feature-card">
<h4 class="text-lg font-bold mb-3 flex items-center">
<i class="fas fa-exclamation-triangle text-red-600 mr-2"></i>
防死锁设计
</h4>
<p class="text-gray-600 text-sm mb-3">
防止因业务执行时间过长或客户端故障导致的锁失效问题,提高分布式锁的健壮性。
</p>
<div class="bg-red-50 p-3 rounded text-xs text-red-800">
业务完成自动取消看门狗任务
</div>
</div>
<div class="feature-card">
<h4 class="text-lg font-bold mb-3 flex items-center">
<i class="fas fa-cogs text-blue-600 mr-2"></i>
可配置性
</h4>
<p class="text-gray-600 text-sm mb-3">
通过Config.lockWatchdogTimeout配置检查间隔,适应不同业务场景需求。
</p>
<div class="bg-blue-50 p-3 rounded text-xs text-blue-800">
建议配置:业务执行时间的2-3倍
</div>
</div>
</div>
</div>
<!-- Fair Lock -->
<div id="fair-lock" class="mb-16">
<h3 class="serif text-3xl font-bold mb-6">公平锁(Fair Lock)的实现</h3>
<div class="bento-card mb-8">
<img src="https://kimi-web-img.moonshot.cn/img/developer.qcloudimg.com/94e61f602fc4e566f0cf79ef9939cca37bf44886.png" alt="排队系统中的公平队列机制示意图" class="w-full h-48 object-cover rounded-lg mb-6" size="medium" aspect="wide" query="公平队列系统示意图" referrerpolicy="no-referrer" data-modified="1" data-score="0.00"/>
<h4 class="text-xl font-bold mb-4">队列机制与公平性保障</h4>
<p class="text-gray-600 mb-4">
Redisson的公平锁实现巧妙地结合了Redis的列表(List)和发布/订阅(Pub/Sub)机制,确保按照线程请求锁的顺序来分配锁。
<a href="https://www.yisu.com/jc/579250.html" class="citation" target="_blank">[335]</a>
</p>
<div class="grid md:grid-cols-2 gap-6">
<div>
<h5 class="font-bold mb-2">FIFO等待队列</h5>
<p class="text-sm text-gray-600 mb-3">
使用Redis列表实现先进先出队列,LPUSH命令将线程标识符放入队列尾部。
</p>
</div>
<div>
<h5 class="font-bold mb-2">消息通知机制</h5>
<p class="text-sm text-gray-600 mb-3">
通过PUBLISH命令向等待线程发送通知,RPOP命令从队列头部取出线程标识符。
</p>
</div>
</div>
</div>
</div>
<!-- Redis Objects -->
<div id="redis-objects" class="mb-16">
<h3 class="serif text-3xl font-bold mb-6">分布式对象与集合的映射原理</h3>
<div class="grid lg:grid-cols-3 gap-6">
<div class="bento-card">
<h4 class="text-lg font-bold mb-3 flex items-center">
<i class="fas fa-map text-green-600 mr-2"></i>
RMap实现
</h4>
<p class="text-sm text-gray-600 mb-3">
基于Redis Hash数据结构,实现Java ConcurrentMap接口,支持本地缓存和数据分片。
<a href="https://blog.csdn.net/weixin_41715077/article/details/102403763" class="citation" target="_blank">[310]</a>
</p>
<div class="text-xs text-gray-500">
<div>• HSET → put()</div>
<div>• HGET → get()</div>
<div>• HDEL → remove()</div>
</div>
</div>
<div class="bento-card">
<h4 class="text-lg font-bold mb-3 flex items-center">
<i class="fas fa-list text-purple-600 mr-2"></i>
队列系统
</h4>
<p class="text-sm text-gray-600 mb-3">
RQueue基于Redis List,RDelayedQueue结合Sorted Set和BlockingQueue实现延迟队列。
</p>
<div class="text-xs text-gray-500">
<div>• RPUSH → offer()</div>
<div>• LPOP → poll()</div>
<div>• BLPOP → take()</div>
</div>
</div>
<div class="bento-card">
<h4 class="text-lg font-bold mb-3 flex items-center">
<i class="fas fa-calculator text-blue-600 mr-2"></i>
原子对象
</h4>
<p class="text-sm text-gray-600 mb-3">
RAtomicLong利用Redis单线程模型和INCR/DECR命令实现高效并发计数。
</p>
<div class="text-xs text-gray-500">
<div>• INCR → incrementAndGet()</div>
<div>• DECR → decrementAndGet()</div>
<div>• Lua脚本 → compareAndSet()</div>
</div>
</div>
</div>
</div>
</section>
<!-- Comparison Section -->
<section id="comparison" class="bg-gray-50 py-16">
<div class="container mx-auto px-8">
<h2 class="serif text-4xl font-bold mb-8 text-center">与主流Redis客户端的全面对比</h2>
<div id="functional-comparison" class="mb-16">
<h3 class="text-2xl font-bold mb-8">功能定位差异</h3>
<div class="comparison-table">
<table>
<thead>
<tr>
<th>特性</th>
<th>Jedis</th>
<th>Lettuce</th>
<th>Redisson</th>
</tr>
</thead>
<tbody>
<tr>
<td class="font-semibold">核心定位</td>
<td>轻量级、命令式客户端</td>
<td>高性能、响应式客户端</td>
<td>分布式对象与服务框架</td>
</tr>
<tr>
<td class="font-semibold">编程模型</td>
<td>同步、阻塞</td>
<td>同步、异步、响应式</td>
<td>同步、异步、响应式</td>
</tr>
<tr>
<td class="font-semibold">线程安全</td>
<td>实例非线程安全,需连接池</td>
<td>连接线程安全</td>
<td>对象线程安全</td>
</tr>
<tr>
<td class="font-semibold">高级抽象</td>
<td>无,直接映射Redis命令</td>
<td>无,直接映射Redis命令</td>
<td>丰富(分布式锁、队列、Map等)</td>
</tr>
<tr>
<td class="font-semibold">学习曲线</td>
<td>低,与Redis命令一致</td>
<td>中等,需理解响应式编程</td>
<td>较高,需理解其对象模型</td>
</tr>
</tbody>
</table>
</div>
<div class="grid lg:grid-cols-3 gap-6 mt-8">
<div class="bento-card">
<h4 class="font-bold text-lg mb-3 text-blue-600">Jedis</h4>
<p class="text-sm text-gray-600 mb-3">
最老牌的Redis客户端,简单直接,轻量级命令封装。适用于简单的命令执行场景。
<a href="https://www.instaclustr.com/blog/redis-java-clients-and-client-side-caching/" class="citation" target="_blank">[309]</a>
</p>
<div class="text-xs text-gray-500">
<strong>适用:</strong>传统应用、简单操作
</div>
</div>
<div class="bento-card">
<h4 class="font-bold text-lg mb-3 text-green-600">Lettuce</h4>
<p class="text-sm text-gray-600 mb-3">
基于Netty的响应式客户端,完全非阻塞,适合高并发响应式系统。
<a href="https://github.com/rodrigobrito/redis-benchmark-java" class="citation" target="_blank">[341]</a>
</p>
<div class="text-xs text-gray-500">
<strong>适用:</strong>高并发、响应式应用
</div>
</div>
<div class="bento-card">
<h4 class="font-bold text-lg mb-3 text-purple-600">Redisson</h4>
<p class="text-sm text-gray-600 mb-3">
分布式Java对象和服务框架,提供高级抽象,简化分布式系统开发。
</p>
<div class="text-xs text-gray-500">
<strong>适用:</strong>复杂分布式系统
</div>
</div>
</div>
</div>
<!-- Performance Analysis -->
<div id="performance" class="mb-16">
<h3 class="text-2xl font-bold mb-8">性能考量与适用场景分析</h3>
<div class="bento-card">
<h4 class="text-xl font-bold mb-6 flex items-center">
<i class="fas fa-chart-line text-blue-600 mr-3"></i>
基准测试数据解读
</h4>
<div class="grid md:grid-cols-2 gap-8">
<div>
<h5 class="font-bold mb-3">性能对比发现</h5>
<ul class="space-y-2 text-sm text-gray-600">
<li class="flex items-start">
<i class="fas fa-circle text-blue-500 text-xs mt-2 mr-2"></i>
单线程环境:Jedis延迟略低于Redisson
<a href="https://www.instaclustr.com/blog/redis-java-clients-and-client-side-caching/" class="citation" target="_blank">[309]</a>
</li>
<li class="flex items-start">
<i class="fas fa-circle text-green-500 text-xs mt-2 mr-2"></i>
高并发环境:Redisson PRO吞吐量优于Jedis
<a href="https://blog.csdn.net/weixin_41715077/article/details/102403763" class="citation" target="_blank">[310]</a>
</li>
<li class="flex items-start">
<i class="fas fa-circle text-purple-500 text-xs mt-2 mr-2"></i>
响应式API:Lettuce在高并发下表现最佳
<a href="https://github.com/rodrigobrito/redis-benchmark-java" class="citation" target="_blank">[341]</a>
</li>
</ul>
</div>
<div>
<h5 class="font-bold mb-3">选择建议</h5>
<div class="space-y-3">
<div class="bg-blue-50 p-3 rounded border-l-4 border-blue-500">
<p class="text-sm text-blue-800">
<strong>选择Jedis:</strong>简单命令执行,对性能要求不高的传统应用
</p>
</div>
<div class="bg-green-50 p-3 rounded border-l-4 border-green-500">
<p class="text-sm text-green-800">
<strong>选择Lettuce:</strong>极高并发、响应式编程模型应用
</p>
</div>
<div class="bg-purple-50 p-3 rounded border-l-4 border-purple-500">
<p class="text-sm text-purple-800">
<strong>选择Redisson:</strong>复杂分布式系统,需要高级协调服务
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Industry Cases -->
<section id="industry-cases" class="container mx-auto px-8 py-16">
<h2 class="serif text-4xl font-bold mb-8 text-center">行业应用案例深度解析</h2>
<!-- Finance Industry -->
<div id="finance" class="mb-16">
<h3 class="text-2xl font-bold mb-8 flex items-center">
<i class="fas fa-university text-blue-600 mr-3"></i>
金融行业:高可用性与数据一致性保障
</h3>
<div class="grid lg:grid-cols-2 gap-8 mb-8">
<div class="bento-card">
<img src="https://kimi-web-img.moonshot.cn/img/i-blog.csdnimg.cn/44982d78438fcd8a030ea390c9c4b85122e74bb9.png" alt="金融交易系统架构图" class="w-full h-48 object-cover rounded-lg mb-4" size="medium" aspect="wide" style="photo" query="金融交易系统架构" referrerpolicy="no-referrer" data-modified="1" data-score="0.00"/>
<h4 class="text-xl font-bold mb-4">交易系统分布式锁应用</h4>
<p class="text-gray-600 mb-4">
在证券、期货、外汇等交易系统中,Redisson的RLock确保对同一账户余额或持仓的修改互斥,防止超买、超卖或资金透支。
</p>
<div class="bg-blue-50 p-4 rounded-lg">
<h5 class="font-bold text-blue-800 mb-2">核心优势</h5>
<ul class="text-sm text-blue-700 space-y-1">
<li>• 看门狗机制保证锁不会意外失效</li>
<li>• 原子操作确保交易数据一致性</li>
<li>• 高性能支持高频并发交易</li>
</ul>
</div>
</div>
<div class="bento-card">
<h4 class="text-xl font-bold mb-4">风险控制与状态同步</h4>
<p class="text-gray-600 mb-4">
金融风控系统使用RLocalCachedMap构建分布式用户状态缓存,近缓存特性降低访问延迟,提升风控决策实时性。
<a href="https://medium.com/<span class="mention-invalid">@shiju</span>.johnsocs/implementing-redis-near-cache-with-redisson-a27599d67d6f" class="citation" target="_blank">[264]</a>
</p>
<div class="space-y-3">
<div class="flex items-center space-x-3">
<i class="fas fa-shield-alt text-green-600"></i>
<span class="text-sm">实时风险评分缓存</span>
</div>
<div class="flex items-center space-x-3">
<i class="fas fa-users text-blue-600"></i>
<span class="text-sm">用户行为标签存储</span>
</div>
<div class="flex items-center space-x-3">
<i class="fas fa-broadcast-tower text-purple-600"></i>
<span class="text-sm">风险事件广播(RTopic)</span>
</div>
</div>
</div>
</div>
<div class="bento-card mb-8">
<h4 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-building text-blue-600 mr-2"></i>
企业级用户案例
</h4>
<p class="text-gray-600 mb-6">
Redisson的可靠性已经得到了全球众多顶级企业的验证,包括IBM、AIG、波音等世界级企业。
<a href="https://www.alibabacloud.com/blog/interview-with-the-creator-of-redisson-building-an-open-source-enterprise-redis-client_593854" class="citation" target="_blank">[94]</a>
</p>
<div class="grid md:grid-cols-3 gap-6">
<div class="text-center">
<div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-3">
<i class="fas fa-building text-blue-600 text-xl"></i>
</div>
<h5 class="font-bold text-blue-600">AIG集团</h5>
<p class="text-xs text-gray-600">全球保险业务支撑</p>
</div>
<div class="text-center">
<div class="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-3">
<i class="fas fa-laptop text-green-600 text-xl"></i>
</div>
<h5 class="font-bold text-green-600">IBM</h5>
<p class="text-xs text-gray-600">企业级应用支持</p>
</div>
<div class="text-center">
<div class="w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center mx-auto mb-3">
<i class="fas fa-plane text-purple-600 text-xl"></i>
</div>
<h5 class="font-bold text-purple-600">波音公司</h5>
<p class="text-xs text-gray-600">在线飞行导航服务</p>
</div>
</div>
</div>
</div>
<!-- E-commerce Industry -->
<div id="ecommerce" class="mb-16">
<h3 class="text-2xl font-bold mb-8 flex items-center">
<i class="fas fa-shopping-cart text-green-600 mr-3"></i>
电商行业:高并发场景下的解决方案
</h3>
<div class="grid lg:grid-cols-2 gap-8">
<div class="bento-card">
<h4 class="text-xl font-bold mb-4">库存扣减与订单处理</h4>
<p class="text-gray-600 mb-4">
在高并发下,多个用户同时下单同一商品,Redisson的分布式锁确保库存不会被超卖,将操作从数据库层面转移到缓存层面,极大提升性能。
<a href="https://www.alibabacloud.com/blog/600811" class="citation" target="_blank">[252]</a>
</p>
<div class="code-block">
RAtomicLong stockCounter = redisson.getAtomicLong("stock:sku123");
long remainingStock = stockCounter.decrementAndGet();
if (remainingStock >= 0) {
// 库存扣减成功,处理订单
} else {
// 库存不足,回滚操作
stockCounter.incrementAndGet();
}
</div>
</div>
<div class="bento-card">
<img src="https://kimi-web-img.moonshot.cn/img/i-blog.csdnimg.cn/303aa230de88fccaf14e90a2cd77252c5f80bb4e.jpeg" alt="电商订单处理系统架构图" class="w-full h-48 object-cover rounded-lg mb-4" size="medium" aspect="wide" style="photo" query="电商订单处理系统架构" referrerpolicy="no-referrer" data-modified="1" data-score="0.00"/>
<h4 class="text-xl font-bold mb-4">分布式任务调度</h4>
<p class="text-gray-600 mb-4">
RDelayedQueue实现订单支付超时关闭、用户积分发放等延迟任务,确保消息在指定时间后被投递和处理。
</p>
<div class="bg-green-50 p-4 rounded-lg">
<h5 class="font-bold text-green-800 mb-2">双十一大促应用</h5>
<p class="text-sm text-green-700">
在海量订单场景下,Redisson的分布式队列方案具备高可用和高并发特性,轻松应对流量洪峰。
</p>
</div>
</div>
</div>
</div>
<!-- IoT Industry -->
<div id="iot" class="mb-16">
<h3 class="text-2xl font-bold mb-8 flex items-center">
<i class="fas fa-wifi text-purple-600 mr-3"></i>
物联网(IoT)行业:实时状态管理
</h3>
<div class="bento-card">
<div class="grid lg:grid-cols-2 gap-8">
<div>
<h4 class="text-xl font-bold mb-4">设备状态实时同步</h4>
<p class="text-gray-600 mb-4">
使用RMap为每个设备创建独立的状态存储,实现在线/离线状态、电量、信号强度等信息的实时共享和同步。
</p>
<div class="space-y-2 mb-4">
<div class="flex items-center space-x-2 text-sm">
<i class="fas fa-circle text-green-500 text-xs"></i>
<span>在线状态监控</span>
</div>
<div class="flex items-center space-x-2 text-sm">
<i class="fas fa-circle text-yellow-500 text-xs"></i>
<span>电量和信号强度</span>
</div>
<div class="flex items-center space-x-2 text-sm">
<i class="fas fa-circle text-blue-500 text-xs"></i>
<span>传感器数据</span>
</div>
</div>
</div>
<div>
<h4 class="text-xl font-bold mb-4">高并发数据采集</h4>
<p class="text-gray-600 mb-4">
RQueue作为数据采集缓冲队列,实现生产者-消费者模型,支持水平扩展处理能力。
</p>
<div class="bg-purple-50 p-4 rounded-lg">
<h5 class="font-bold text-purple-800 mb-2">架构优势</h5>
<ul class="text-sm text-purple-700 space-y-1">
<li>• 数据采集与处理解耦</li>
<li>• 支持动态扩容</li>
<li>• 实时状态一致性保证</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Best Practices -->
<section id="best-practices" class="bg-gray-50 py-16">
<div class="container mx-auto px-8">
<h2 class="serif text-4xl font-bold mb-8 text-center">性能调优指南与最佳实践</h2>
<!-- Configuration Optimization -->
<div id="configuration" class="mb-16">
<h3 class="text-2xl font-bold mb-8">配置优化</h3>
<div class="grid lg:grid-cols-3 gap-6 mb-8">
<div class="bento-card">
<h4 class="text-lg font-bold mb-4 flex items-center">
<i class="fas fa-network-wired text-blue-600 mr-2"></i>
连接池配置
</h4>
<div class="space-y-3 text-sm">
<div>
<strong>connectionPoolSize</strong>
<p class="text-gray-600">最大连接数,建议从50开始调优</p>
</div>
<div>
<strong>connectionMinimumIdleSize</strong>
<p class="text-gray-600">最小空闲连接,避免高峰时频繁创建</p>
</div>
<div>
<strong>idleConnectionTimeout</strong>
<p class="text-gray-600">空闲连接超时时间,及时释放资源</p>
</div>
</div>
</div>
<div class="bento-card">
<h4 class="text-lg font-bold mb-4 flex items-center">
<i class="fas fa-cogs text-green-600 mr-2"></i>
线程池设置
</h4>
<div class="space-y-3 text-sm">
<div>
<strong>Executor</strong>
<p class="text-gray-600">异步回调和后台任务执行器</p>
</div>
<div>
<strong>EventLoopGroup</strong>
<p class="text-gray-600">Netty事件循环组,默认CPU核心数*2</p>
</div>
<div class="bg-green-50 p-2 rounded text-xs">
建议:I/O密集型应用可适当增加线程数
</div>
</div>
</div>
<div class="bento-card">
<h4 class="text-lg font-bold mb-4 flex items-center">
<i class="fas fa-file-code text-purple-600 mr-2"></i>
序列化选择
</h4>
<div class="space-y-2 text-sm">
<div class="flex justify-between">
<span>JsonJacksonCodec</span>
<span class="text-gray-500">通用性好</span>
</div>
<div class="flex justify-between">
<span>KryoCodec</span>
<span class="text-gray-500">性能最高</span>
</div>
<div class="flex justify-between">
<span>FstCodec</span>
<span class="text-gray-500">体积小</span>
</div>
<div class="flex justify-between">
<span>StringCodec</span>
<span class="text-gray-500">仅字符串</span>
</div>
</div>
</div>
</div>
</div>
<!-- Lock Best Practices -->
<div id="lock-practices" class="mb-16">
<h3 class="text-2xl font-bold mb-8">分布式锁使用最佳实践</h3>
<div class="grid lg:grid-cols-2 gap-8">
<div class="bento-card">
<h4 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-key text-red-600 mr-2"></i>
锁的粒度与超时设置
</h4>
<div class="space-y-4">
<div>
<h5 class="font-bold text-sm mb-2">锁粒度原则</h5>
<p class="text-sm text-gray-600">尽可能小,只锁定必要资源。例如为每个订单ID创建独立锁,而非全局锁。</p>
</div>
<div>
<h5 class="font-bold text-sm mb-2">超时时间设置</h5>
<p class="text-sm text-gray-600">如业务执行时间可预估,建议显式指定leaseTime;否则依赖看门狗机制。</p>
</div>
</div>
</div>
<div class="bento-card">
<h4 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-exclamation-triangle text-orange-600 mr-2"></i>
避免死锁与失效
</h4>
<div class="space-y-4">
<div>
<h5 class="font-bold text-sm mb-2">死锁预防</h5>
<p class="text-sm text-gray-600">确保所有线程以相同顺序获取多把锁,避免循环等待。</p>
</div>
<div>
<h5 class="font-bold text-sm mb-2">锁失效处理</h5>
<p class="text-sm text-gray-600">tryLock返回false时进行重试或降级,finally块中确保unlock()。</p>
</div>
</div>
</div>
</div>
<div class="bento-card mt-8">
<h4 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-shield-alt text-blue-600 mr-2"></i>
红锁(RedLock)的正确使用
</h4>
<div class="grid md:grid-cols-2 gap-6">
<div>
<p class="text-gray-600 mb-4">
红锁提供高可用性,但实现复杂,性能开销更大。仅在特定场景下使用。
</p>
<div class="bg-blue-50 p-4 rounded-lg">
<h5 class="font-bold text-blue-800 mb-2">适用场景</h5>
<ul class="text-sm text-blue-700 space-y-1">
<li>• 金融交易核心环节</li>
<li>• 分布式任务调度</li>
<li>• 极高可用性要求</li>
</ul>
</div>
</div>
<div>
<div class="bg-yellow-50 p-4 rounded-lg border-l-4 border-yellow-500">
<h5 class="font-bold text-yellow-800 mb-2">注意事项</h5>
<ul class="text-sm text-yellow-700 space-y-1">
<li>• 依赖系统时钟同步</li>
<li>• 性能开销较大</li>
<li>• 大多数场景单实例锁足够</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Monitoring and Troubleshooting -->
<div id="monitoring" class="mb-16">
<h3 class="text-2xl font-bold mb-8">监控与故障排查</h3>
<div class="grid lg:grid-cols-2 gap-8">
<div class="bento-card">
<h4 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-chart-bar text-green-600 mr-2"></i>
关键性能指标监控
</h4>
<div class="space-y-4">
<div>
<h5 class="font-bold text-sm mb-2">Redis服务器指标</h5>
<div class="grid grid-cols-2 gap-2 text-xs text-gray-600">
<div>• QPS</div>
<div>• 连接数</div>
<div>• 内存使用率</div>
<div>• CPU使用率</div>
</div>
</div>
<div>
<h5 class="font-bold text-sm mb-2">Redisson客户端指标</h5>
<div class="grid grid-cols-2 gap-2 text-xs text-gray-600">
<div>• 连接池使用情况</div>
<div>• 请求延迟</div>
<div>• 锁等待时间</div>
<div>• 看门狗续期次数</div>
</div>
</div>
</div>
</div>
<div class="bento-card">
<h4 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-tools text-orange-600 mr-2"></i>
常见问题诊断
</h4>
<div class="space-y-4">
<div class="border-l-4 border-red-500 pl-4">
<h5 class="font-bold text-sm text-red-800">连接超时</h5>
<p class="text-xs text-gray-600">检查网络连通性,确认Redis地址配置,检查服务器timeout设置</p>
</div>
<div class="border-l-4 border-yellow-500 pl-4">
<h5 class="font-bold text-sm text-yellow-800">命令执行超时</h5>
<p class="text-xs text-gray-600">检查慢查询,优化Redis命令,监控服务器负载</p>
</div>
<div class="border-l-4 border-blue-500 pl-4">
<h5 class="font-bold text-sm text-blue-800">锁竞争严重</h5>
<p class="text-xs text-gray-600">减小锁粒度,考虑使用读写锁替代独占锁</p>
</div>
<div class="border-l-4 border-purple-500 pl-4">
<h5 class="font-bold text-sm text-purple-800">内存溢出</h5>
<p class="text-xs text-gray-600">检查大key或数据堆积,优化淘汰策略,调整本地缓存配置</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer class="bg-gray-900 text-white py-12">
<div class="container mx-auto px-8">
<div class="grid lg:grid-cols-3 gap-8">
<div>
<h3 class="serif text-2xl font-bold mb-4">Redisson</h3>
<p class="text-gray-300 text-sm leading-relaxed">
基于Redis的Java分布式协调框架,为微服务架构提供企业级解决方案。
</p>
</div>
<div>
<h4 class="font-bold mb-4">快速链接</h4>
<div class="space-y-2 text-sm">
<a href="#architecture" class="text-gray-300 hover:text-white transition-colors">核心原理</a>
<br/>
<a href="#comparison" class="text-gray-300 hover:text-white transition-colors">客户端对比</a>
<br/>
<a href="#industry-cases" class="text-gray-300 hover:text-white transition-colors">行业案例</a>
<br/>
<a href="#best-practices" class="text-gray-300 hover:text-white transition-colors">最佳实践</a>
</div>
</div>
<div>
<h4 class="font-bold mb-4">参考资料</h4>
<div class="text-xs text-gray-300 space-y-1">
<p>官方文档:<a href="https://redisson.org" class="text-blue-400 hover:underline">redisson.org</a>
</p>
<p>GitHub:<a href="https://github.com/redisson/redisson" class="text-blue-400 hover:underline">GitHub仓库</a>
</p>
<p>社区支持:<a href="https://stackoverflow.com/questions/tagged/redisson" class="text-blue-400 hover:underline">Stack Overflow</a>
</p>
</div>
</div>
</div>
<div class="border-t border-gray-700 mt-8 pt-8 text-center text-sm text-gray-400">
<p>本报告基于公开资料和技术文档整理,旨在为技术决策者提供参考。</p>
</div>
</div>
</footer>
</main>
<script>
// Initialize Mermaid
mermaid.initialize({
startOnLoad: true,
theme: 'base',
themeVariables: {
primaryColor: '#ffffff',
primaryTextColor: '#1e293b',
primaryBorderColor: '#1e293b',
lineColor: '#475569',
secondaryColor: '#f8fafc',
tertiaryColor: '#e2e8f0',
background: '#ffffff',
mainBkg: '#ffffff',
secondBkg: '#f1f5f9',
tertiaryBkg: '#e2e8f0',
nodeBorder: '#1e293b',
clusterBkg: '#f8fafc',
clusterBorder: '#cbd5e1',
defaultLinkColor: '#475569',
titleColor: '#1e293b',
edgeLabelBackground: '#ffffff',
nodeTextColor: '#1e293b'
},
flowchart: {
useMaxWidth: true,
htmlLabels: true,
curve: 'basis'
},
fontFamily: 'Inter, sans-serif'
});
// Initialize Mermaid Controls for zoom and pan
function initializeMermaidControls() {
const containers = document.querySelectorAll('.mermaid-container');
containers.forEach(container => {
const mermaidElement = container.querySelector('.mermaid');
let scale = 1;
let isDragging = false;
let startX, startY, translateX = 0, translateY = 0;
// 触摸相关状态
let isTouch = false;
let touchStartTime = 0;
let initialDistance = 0;
let initialScale = 1;
let isPinching = false;
// Zoom controls
const zoomInBtn = container.querySelector('.zoom-in');
const zoomOutBtn = container.querySelector('.zoom-out');
const resetBtn = container.querySelector('.reset-zoom');
const fullscreenBtn = container.querySelector('.fullscreen');
function updateTransform() {
mermaidElement.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;
if (scale > 1) {
container.classList.add('zoomed');
} else {
container.classList.remove('zoomed');
}
mermaidElement.style.cursor = isDragging ? 'grabbing' : 'grab';
}
if (zoomInBtn) {
zoomInBtn.addEventListener('click', () => {
scale = Math.min(scale * 1.25, 4);
updateTransform();
});
}
if (zoomOutBtn) {
zoomOutBtn.addEventListener('click', () => {
scale = Math.max(scale / 1.25, 0.3);
if (scale <= 1) {
translateX = 0;
translateY = 0;
}
updateTransform();
});
}
if (resetBtn) {
resetBtn.addEventListener('click', () => {
scale = 1;
translateX = 0;
translateY = 0;
updateTransform();
});
}
if (fullscreenBtn) {
fullscreenBtn.addEventListener('click', () => {
if (container.requestFullscreen) {
container.requestFullscreen();
} else if (container.webkitRequestFullscreen) {
container.webkitRequestFullscreen();
} else if (container.msRequestFullscreen) {
container.msRequestFullscreen();
}
});
}
// Mouse Events
mermaidElement.addEventListener('mousedown', (e) => {
if (isTouch) return; // 如果是触摸设备,忽略鼠标事件
isDragging = true;
startX = e.clientX - translateX;
startY = e.clientY - translateY;
mermaidElement.style.cursor = 'grabbing';
updateTransform();
e.preventDefault();
});
document.addEventListener('mousemove', (e) => {
if (isDragging && !isTouch) {
translateX = e.clientX - startX;
translateY = e.clientY - startY;
updateTransform();
}
});
document.addEventListener('mouseup', () => {
if (isDragging && !isTouch) {
isDragging = false;
mermaidElement.style.cursor = 'grab';
updateTransform();
}
});
document.addEventListener('mouseleave', () => {
if (isDragging && !isTouch) {
isDragging = false;
mermaidElement.style.cursor = 'grab';
updateTransform();
}
});
// 获取两点之间的距离
function getTouchDistance(touch1, touch2) {
return Math.hypot(
touch2.clientX - touch1.clientX,
touch2.clientY - touch1.clientY
);
}
// Touch Events - 触摸事件处理
mermaidElement.addEventListener('touchstart', (e) => {
isTouch = true;
touchStartTime = Date.now();
if (e.touches.length === 1) {
// 单指拖动
isPinching = false;
isDragging = true;
const touch = e.touches[0];
startX = touch.clientX - translateX;
startY = touch.clientY - translateY;
} else if (e.touches.length === 2) {
// 双指缩放
isPinching = true;
isDragging = false;
const touch1 = e.touches[0];
const touch2 = e.touches[1];
initialDistance = getTouchDistance(touch1, touch2);
initialScale = scale;
}
e.preventDefault();
}, { passive: false });
mermaidElement.addEventListener('touchmove', (e) => {
if (e.touches.length === 1 && isDragging && !isPinching) {
// 单指拖动
const touch = e.touches[0];
translateX = touch.clientX - startX;
translateY = touch.clientY - startY;
updateTransform();
} else if (e.touches.length === 2 && isPinching) {
// 双指缩放
const touch1 = e.touches[0];
const touch2 = e.touches[1];
const currentDistance = getTouchDistance(touch1, touch2);
if (initialDistance > 0) {
const newScale = Math.min(Math.max(
initialScale * (currentDistance / initialDistance),
0.3
), 4);
scale = newScale;
updateTransform();
}
}
e.preventDefault();
}, { passive: false });
mermaidElement.addEventListener('touchend', (e) => {
// 重置状态
if (e.touches.length === 0) {
isDragging = false;
isPinching = false;
initialDistance = 0;
// 延迟重置isTouch,避免鼠标事件立即触发
setTimeout(() => {
isTouch = false;
}, 100);
} else if (e.touches.length === 1 && isPinching) {
// 从双指变为单指,切换为拖动模式
isPinching = false;
isDragging = true;
const touch = e.touches[0];
startX = touch.clientX - translateX;
startY = touch.clientY - translateY;
}
updateTransform();
});
mermaidElement.addEventListener('touchcancel', (e) => {
isDragging = false;
isPinching = false;
initialDistance = 0;
setTimeout(() => {
isTouch = false;
}, 100);
updateTransform();
});
// Enhanced wheel zoom with better center point handling
container.addEventListener('wheel', (e) => {
e.preventDefault();
const rect = container.getBoundingClientRect();
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const delta = e.deltaY > 0 ? 0.9 : 1.1;
const newScale = Math.min(Math.max(scale * delta, 0.3), 4);
// Adjust translation to zoom towards center
if (newScale !== scale) {
const scaleDiff = newScale / scale;
translateX = translateX * scaleDiff;
translateY = translateY * scaleDiff;
scale = newScale;
if (scale <= 1) {
translateX = 0;
translateY = 0;
}
updateTransform();
}
});
// Initialize display
updateTransform();
});
}
// Smooth scrolling for TOC links
document.querySelectorAll('.toc-link').forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href').substring(1);
const targetElement = document.getElementById(targetId);
if (targetElement) {
targetElement.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Active TOC link highlighting
window.addEventListener('scroll', function() {
const sections = document.querySelectorAll('section[id], div[id]');
const tocLinks = document.querySelectorAll('.toc-link');
let currentSection = '';
sections.forEach(section => {
const rect = section.getBoundingClientRect();
if (rect.top <= 100 && rect.bottom >= 100) {
currentSection = section.getAttribute('id');
}
});
tocLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === '#' + currentSection) {
link.classList.add('active');
}
});
});
// Mobile TOC toggle
function toggleTOC() {
const toc = document.querySelector('.toc-fixed');
toc.classList.toggle('open');
}
// Close TOC when clicking outside on mobile
document.addEventListener('click', function(event) {
const toc = document.querySelector('.toc-fixed');
const hamburger = document.querySelector('.mobile-menu-button');
const isTocClick = toc.contains(event.target);
const isHamburgerClick = hamburger && hamburger.contains(event.target);
if (!isTocClick && !isHamburgerClick && toc.classList.contains('open')) {
toc.classList.remove('open');
}
});
// Add mobile menu button for smaller screens
if (window.innerWidth <= 1024) {
const mobileMenuButton = document.createElement('button');
mobileMenuButton.innerHTML = '<i class="fas fa-bars text-xl"></i>';
mobileMenuButton.className = 'mobile-menu-button fixed top-4 left-4 z-50 bg-white p-3 rounded-lg shadow-lg lg:hidden';
mobileMenuButton.onclick = toggleTOC;
document.body.appendChild(mobileMenuButton);
}
// Remove open class on large screens
window.addEventListener('resize', function() {
const toc = document.querySelector('.toc-fixed');
if (window.innerWidth > 1024 && toc.classList.contains('open')) {
toc.classList.remove('open');
}
});
// Initialize Mermaid controls after DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
setTimeout(initializeMermaidControls, 1000); // Wait for mermaid to render
});
</script>
</body></html>
登录后可参与表态
讨论回复
1 条回复
QianXun (QianXun)
#1
10-15 01:37
登录后可参与表态