Skip to content

Commit 763cae3

Browse files
committed
feat: knowledge summary
1 parent 1c92ccf commit 763cae3

3 files changed

Lines changed: 232 additions & 19 deletions

File tree

src/components/stateless/DeploymentFlow/index.tsx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Phase03 from './phases/Phase03_Env'
44
import Phase04 from './phases/Phase04_Strategy'
55
import Phase05 from './phases/Phase05_Ops'
66
import TimelineDot from './shared/TimelineDot'
7+
import KnowledgeSummary from './shared/KnowledgeSummary'
78
import styles from './index.module.less'
89

910
const phases = [
@@ -20,23 +21,26 @@ interface Props {
2021

2122
const DeploymentFlow: React.FC<Props> = ({ scrollContainerRef }) => {
2223
return (
23-
<div className={styles.container}>
24-
<div className={styles.timelineLine}></div>
24+
<>
25+
<div className={styles.container}>
26+
<div className={styles.timelineLine}></div>
2527

26-
{phases.map((phase, index) => {
27-
const isLeft = index % 2 === 0
28-
const PhaseComponent = phase.component
28+
{phases.map((phase, index) => {
29+
const isLeft = index % 2 === 0
30+
const PhaseComponent = phase.component
2931

30-
return (
31-
<div key={phase.id} className={`${styles.node} ${styles[phase.type]}`}>
32-
<TimelineDot type={phase.type} />
33-
<div className={`${styles.cardWrapper} ${isLeft ? styles.left : styles.right}`}>
34-
<PhaseComponent isLeft={isLeft} scrollContainerRef={scrollContainerRef} />
32+
return (
33+
<div key={phase.id} className={`${styles.node} ${styles[phase.type]}`}>
34+
<TimelineDot type={phase.type} />
35+
<div className={`${styles.cardWrapper} ${isLeft ? styles.left : styles.right}`}>
36+
<PhaseComponent isLeft={isLeft} scrollContainerRef={scrollContainerRef} />
37+
</div>
3538
</div>
36-
</div>
37-
)
38-
})}
39-
</div>
39+
)
40+
})}
41+
</div>
42+
<KnowledgeSummary />
43+
</>
4044
)
4145
}
4246

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
import React from 'react'
2+
3+
const SectionTitle: React.FC<{ children: React.ReactNode }> = ({ children }) => (
4+
<h3
5+
style={{
6+
fontSize: '18px',
7+
fontWeight: 700,
8+
color: '#263238',
9+
marginBottom: '20px',
10+
borderBottom: '2px solid #e0e0e0',
11+
paddingBottom: '10px',
12+
}}
13+
>
14+
{children}
15+
</h3>
16+
)
17+
18+
const SubTitle: React.FC<{ children: React.ReactNode }> = ({ children }) => (
19+
<h4 style={{ fontSize: '15px', fontWeight: 600, color: '#546e7a', marginTop: '20px', marginBottom: '10px' }}>
20+
{children}
21+
</h4>
22+
)
23+
24+
const TextBlock: React.FC<{ children: React.ReactNode }> = ({ children }) => (
25+
<p style={{ fontSize: '14px', color: '#455a64', lineHeight: '1.8', marginBottom: '12px' }}>{children}</p>
26+
)
27+
28+
const ListPoint: React.FC<{ highlight?: boolean; children: React.ReactNode }> = ({ highlight, children }) => (
29+
<li
30+
style={{
31+
fontSize: '14px',
32+
color: '#455a64',
33+
lineHeight: '1.8',
34+
marginBottom: '8px',
35+
marginLeft: '20px',
36+
background: highlight ? '#fff3e0' : 'transparent',
37+
padding: highlight ? '4px 8px' : '0',
38+
borderRadius: '4px',
39+
borderLeft: highlight ? '3px solid #ff9800' : 'none',
40+
}}
41+
>
42+
{children}
43+
</li>
44+
)
45+
46+
// const GridCard: React.FC<{ title: string; items: string[] }> = ({ title, items }) => (
47+
// <div style={{ background: 'white', padding: '15px', borderRadius: '8px', border: '1px solid #eee' }}>
48+
// <strong style={{ display: 'block', color: '#263238', marginBottom: '10px', fontSize: '15px' }}>{title}</strong>
49+
// <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>
50+
// {items.map((item, idx) => <ListPoint key={idx}>{item}</ListPoint>)}
51+
// </ul>
52+
// </div>
53+
// );
54+
55+
const KnowledgeSummary: React.FC = () => {
56+
return (
57+
<div style={{ maxWidth: '1100px', margin: '60px auto', padding: '0 20px' }}>
58+
<SectionTitle>💡 核心实施规则与原理解析</SectionTitle>
59+
60+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(400px, 1fr))', gap: '30px' }}>
61+
{/* 左侧:Phase 04 发布策略详解 */}
62+
<div>
63+
<SubTitle>📦 Phase 04: 发布策略实现原理</SubTitle>
64+
<div style={{ display: 'flex', flexDirection: 'column', gap: '15px' }}>
65+
<div>
66+
<strong style={{ color: '#2e7d32' }}>🔄 蓝绿部署</strong>
67+
<TextBlock>
68+
基于负载均衡器或 Service Mesh 的路由配置。准备两套环境,验证无误后修改路由指向新版本,实现瞬间切换。
69+
</TextBlock>
70+
<ul>
71+
<ListPoint>
72+
<strong>实现:</strong>Kubernetes Service Mesh (Istio) 或 Nginx upstream 切换。
73+
</ListPoint>
74+
<ListPoint>
75+
<strong>特点:</strong>秒级回滚,全量测试,但资源消耗大(需双倍机器)。
76+
</ListPoint>
77+
</ul>
78+
</div>
79+
80+
<div>
81+
<strong style={{ color: '#2e7d32' }}>🐤 金丝雀发布</strong>
82+
<TextBlock>
83+
在生产环境中,让小部分用户流量(如 5%)访问新版本,监控错误率和性能,逐步扩大流量占比。
84+
</TextBlock>
85+
<ul>
86+
<ListPoint>
87+
<strong>实现:</strong>Istio VirtualService 的 <code>weight</code> 权重控制。
88+
</ListPoint>
89+
<ListPoint>
90+
<strong>特点:</strong>渐进式引入流量,注重监控验证,风险低于蓝绿部署。
91+
</ListPoint>
92+
</ul>
93+
</div>
94+
95+
<div>
96+
<strong style={{ color: '#2e7d32' }}>⚡ 滚动发布</strong>
97+
<TextBlock>系统自动分批次替换旧实例。每次启动新 Pod,停止旧 Pod,保持服务始终可用。</TextBlock>
98+
<ul>
99+
<ListPoint>
100+
<strong>实现:</strong>Kubernetes Deployment 默认策略,设置 <code>maxSurge</code>{' '}
101+
<code>maxUnavailable</code>
102+
</ListPoint>
103+
<ListPoint>
104+
<strong>特点:</strong>无资源浪费,适合日常迭代,但回滚相对较慢。
105+
</ListPoint>
106+
</ul>
107+
</div>
108+
109+
<div>
110+
<strong style={{ color: '#2e7d32' }}>🧪 A/B Testing</strong>
111+
<TextBlock>为了验证业务假设(如 UI 改版能否提高转化率),将用户分流到不同版本。</TextBlock>
112+
<ul>
113+
<ListPoint>
114+
<strong>实现:</strong>前端 SDK 或网关注入 Header (X-Experiment-Group),需要保持用户流量粘性。
115+
</ListPoint>
116+
<ListPoint>
117+
<strong>特点:</strong>关注业务指标(转化率),而非单纯的技术稳定性。
118+
</ListPoint>
119+
</ul>
120+
</div>
121+
122+
<div>
123+
<strong style={{ color: '#2e7d32' }}>🎛️ Feature Flag</strong>
124+
<TextBlock>代码部署与功能发布解耦。代码已上线但功能开关关闭,通过配置中心动态开启。</TextBlock>
125+
<ul>
126+
<ListPoint>
127+
<strong>实现:</strong>配置中心 + 前端 SDK。
128+
</ListPoint>
129+
<ListPoint>
130+
<strong>特点:</strong>极致的安全感(秒关),支持白名单/灰度,但需定期清理废弃开关。
131+
</ListPoint>
132+
</ul>
133+
</div>
134+
</div>
135+
</div>
136+
137+
{/* 右侧:Phase 05 监控运维详解 */}
138+
<div>
139+
<SubTitle>🛡️ Phase 05: 监控与运维铁律</SubTitle>
140+
141+
<div style={{ marginBottom: '20px' }}>
142+
<strong>🛠 基础设施规则</strong>
143+
<ul>
144+
<ListPoint highlight>
145+
<strong>K8s:</strong>声明式部署,必须配置健康检查,实现秒级自愈。
146+
</ListPoint>
147+
<ListPoint highlight>
148+
<strong>Docker/Istio:</strong>环境一致性;利用 Mesh 实现无侵入熔断和流量治理。
149+
</ListPoint>
150+
<ListPoint highlight>
151+
<strong>Apollo:</strong>配置中心实现业务逻辑热更新(Feature Flag)。
152+
</ListPoint>
153+
<ListPoint highlight>
154+
<strong>Harbor:</strong>镜像仓库必须配置漏洞扫描,阻断高危镜像。
155+
</ListPoint>
156+
</ul>
157+
</div>
158+
159+
<div style={{ marginBottom: '20px' }}>
160+
<strong>📊 监控体系规则</strong>
161+
<ul>
162+
<ListPoint highlight>
163+
<strong>Sentry:</strong>必须上传 <strong>Source Maps</strong>,否则无法定位源码错误。关联 User ID 和
164+
Release 版本。
165+
</ListPoint>
166+
<ListPoint highlight>
167+
<strong>APM / RUM:</strong>关注 LCP/FID/CLS 等 Web Vitals 指标,量化真实用户体验。
168+
</ListPoint>
169+
<ListPoint highlight>
170+
<strong>ELK:</strong>日志必须 <strong>JSON 结构化</strong> 并注入 <strong>TraceID</strong>
171+
,实现端到端排查。
172+
</ListPoint>
173+
<ListPoint highlight>
174+
<strong>Jaeger:</strong>可视化全链路(前端-&gt;网关-&gt;后端-&gt;DB),定位单点耗时瓶颈。
175+
</ListPoint>
176+
<ListPoint highlight>
177+
<strong>Grafana:</strong>统一大盘,设置 SLO 告警(如错误率 &lt; 1%)。
178+
</ListPoint>
179+
</ul>
180+
</div>
181+
182+
<div>
183+
<strong>⚙️ 核心铁律 (Iron Rules)</strong>
184+
<ul>
185+
<ListPoint>
186+
<strong>不可变原则:</strong>严禁 SSH 进容器修改文件,变更必须重新构建镜像。
187+
</ListPoint>
188+
<ListPoint>
189+
<strong>数据驱动:</strong>扩容、回滚必须基于监控数据,而非直觉。
190+
</ListPoint>
191+
<ListPoint>
192+
<strong>快速止损:</strong>故障优先级:Config 关停 &gt; K8s Rollback &gt; 代码回滚。
193+
</ListPoint>
194+
<ListPoint>
195+
<strong>全链路贯通:</strong>通过 TraceID 将 前端报错、日志、后端 Trace 串联。
196+
</ListPoint>
197+
</ul>
198+
</div>
199+
</div>
200+
</div>
201+
</div>
202+
)
203+
}
204+
205+
export default KnowledgeSummary

src/config/menu.config.jsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ import {
3333
ThunderboltOutlined,
3434
ToolOutlined,
3535
CloudUploadOutlined,
36+
DatabaseOutlined,
37+
SafetyCertificateOutlined,
38+
NodeIndexOutlined,
39+
PlayCircleOutlined,
3640
} from '@ant-design/icons'
3741

3842
// 静态菜单配置
@@ -94,7 +98,7 @@ const rawMainLayoutMenu = [
9498
path: '/zustand',
9599
icon: (
96100
<AnimatedIcon variant="spin" mode="hover">
97-
<ThunderboltOutlined />
101+
<DatabaseOutlined />
98102
</AnimatedIcon>
99103
),
100104
},
@@ -104,7 +108,7 @@ const rawMainLayoutMenu = [
104108
path: '/deploy-flow',
105109
icon: (
106110
<AnimatedIcon variant="spin" mode="hover">
107-
<ThunderboltOutlined />
111+
<RocketOutlined />
108112
</AnimatedIcon>
109113
),
110114
},
@@ -114,7 +118,7 @@ const rawMainLayoutMenu = [
114118
path: '/motion',
115119
icon: (
116120
<AnimatedIcon variant="spin" mode="hover">
117-
<RocketOutlined />
121+
<PlayCircleOutlined />
118122
</AnimatedIcon>
119123
),
120124
},
@@ -194,7 +198,7 @@ const rawMainLayoutMenu = [
194198
path: '/crypto',
195199
icon: (
196200
<AnimatedIcon variant="spin" mode="hover">
197-
<LockOutlined />
201+
<SafetyCertificateOutlined />
198202
</AnimatedIcon>
199203
),
200204
},
@@ -314,7 +318,7 @@ const rawMainLayoutMenu = [
314318
path: '/tech/frontend',
315319
icon: (
316320
<AnimatedIcon variant="spin" mode="hover">
317-
<DeploymentUnitOutlined />
321+
<NodeIndexOutlined />
318322
</AnimatedIcon>
319323
),
320324
children: [

0 commit comments

Comments
 (0)