<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>架构视界</title>
    <link>https://blog-architectview.pages.dev/categories/%E6%9E%B6%E6%9E%84%E8%A7%86%E7%95%8C/</link>
    <description>Recent content on 架构视界</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <copyright>© 2026 架构视界 Architect View</copyright>
    <lastBuildDate>Tue, 19 May 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://blog-architectview.pages.dev/categories/%E6%9E%B6%E6%9E%84%E8%A7%86%E7%95%8C/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>分布式系统演进：从 CAP 到 PACELC 的架构思考</title>
      <link>https://blog-architectview.pages.dev/posts/distributed-systems-cap-to-pacelc/</link>
      <pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/distributed-systems-cap-to-pacelc/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;CAP 定理是分布式系统的「牛顿第一定律」——它定义了这个领域的基本约束。但在真实的工程实践中，CAP 定理过于粗粒度，以至于它无法指导我们在实际系统中做出正确的设计决策。我们需要一个更精细的模型。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;cap-定理的再理解&#34;&gt;CAP 定理的再理解&lt;/h2&gt;&#xA;&lt;p&gt;2000 年，Eric Brewer 提出 CAP 猜想；2002 年，Gilbert 和 Lynch 给出了形式化证明。CAP 定理告诉我们：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;在一个分布式系统中，以下三个特性最多只能同时满足两个：&#xA;&#xA;C (Consistency)  - 一致性：所有节点在同一时刻看到相同的数据&#xA;A (Availability) - 可用性：每个请求都能在合理时间内收到非错误响应&#xA;P (Partition Tolerance) - 分区容错：网络分区发生时系统仍能运行&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;大多数架构师对 CAP 的理解停留在「三选二」的层面。但这个理解有几个问题：&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;问题 1：P 不是一个可选项&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;在真实的分布式系统中，网络分区是必然会发生的事情——交换机故障、光缆被挖断、数据中心之间的网络抖动。所以 P 不是你可以「选择放弃」的特性，它是一个既定事实。&lt;/p&gt;&#xA;&lt;p&gt;真正的选择是在 &lt;strong&gt;C 和 A 之间&lt;/strong&gt;，而且这个选择只在分区发生时才有意义。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;没有分区时：C 和 A 可以同时满足&#xA;发生分区时：必须在 C 和 A 之间选择&#xA;&#xA;CP 系统：分区时拒绝服务，保证一致性&#xA;  例：ZooKeeper、etcd、HBase&#xA;&#xA;AP 系统：分区时继续服务，可能返回过期数据&#xA;  例：Cassandra、DynamoDB、CouchDB&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;问题 2：CAP 是全局的，但需求是局部的&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;同一个系统中，不同的业务操作可能有不同的一致性需求：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;电商系统的一致性需求：&#xA;&#xA;操作 A：扣减库存&#xA;  → 需要强一致性（不能超卖）→ CP&#xA;&#xA;操作 B：展示商品评价&#xA;  → 可以接受最终一致性（延迟几秒看到新评价无所谓）→ AP&#xA;&#xA;操作 C：用户修改收货地址&#xA;  → 需要强一致性（改错了会寄错地方）→ CP&#xA;&#xA;操作 D：商品浏览量计数&#xA;  → 可以接受最终一致性（少计几次没关系）→ AP&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;一个成熟的分布式系统不会在全局层面选择 CP 或 AP，而是在每个操作级别做精细的选择。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Redis 高并发缓存架构：击穿、穿透、雪崩全解</title>
      <link>https://blog-architectview.pages.dev/posts/redis-cache-breakdown-penetration-avalanche/</link>
      <pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/redis-cache-breakdown-penetration-avalanche/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;缓存是提升系统吞吐量最简单的手段，但它引入的问题也比你想象的更多。击穿、穿透、雪崩——这三个听起来像地质灾害的名词，是每一个高并发系统设计者必须跨越的三道坎。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;缓存的基本模型&#34;&gt;缓存的基本模型&lt;/h2&gt;&#xA;&lt;p&gt;在深入三个核心问题之前，先建立一个标准的缓存读写模型：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;标准缓存读取流程：&#xA;&#xA;客户端 → 缓存层（Redis）→ [命中] → 直接返回&#xA;                         → [未命中] → 数据库层 → 写入缓存 → 返回&#xA;&#xA;标准缓存写入流程：&#xA;&#xA;方案 A（Cache Aside）：先更新数据库，再删除缓存&#xA;方案 B（Read/Write Through）：通过缓存层代理读写&#xA;方案 C（Write Behind）：只写缓存，异步刷入数据库&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在绝大多数互联网场景中，&lt;strong&gt;Cache Aside&lt;/strong&gt;（旁路缓存）是最常用的模式——代码直接操作 Redis 和数据库，简单透明。但正是这种简单性，隐藏着三大问题。&lt;/p&gt;&#xA;&lt;h2 id=&#34;问题一缓存穿透cache-penetration&#34;&gt;问题一：缓存穿透（Cache Penetration）&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;定义&lt;/strong&gt;：查询一个根本不存在的数据，缓存中没有，数据库中也没有。每次请求都会穿透缓存直接打到数据库。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;正常请求：&#xA;  查询 user_id=123 → 缓存命中 → 返回（快）&#xA;&#xA;穿透请求：&#xA;  查询 user_id=-1 → 缓存未命中 → 查数据库 → 数据库也没有 → 返回空&#xA;  查询 user_id=-1 → 缓存未命中 → 查数据库 → 数据库也没有 → 返回空&#xA;  查询 user_id=-1 → 缓存未命中 → 查数据库 → 数据库也没有 → 返回空&#xA;  &#xA;  如果每秒 10000 次这样的请求，数据库直接被压垮&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;穿透通常由恶意攻击或业务 Bug 引起——攻击者构造大量不存在的 ID，绕过缓存直接攻击数据库。&lt;/p&gt;</description>
    </item>
    <item>
      <title>微服务治理演进：从 Netflix OSS 到 Service Mesh</title>
      <link>https://blog-architectview.pages.dev/posts/microservices-netflix-to-service-mesh/</link>
      <pubDate>Sun, 17 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/microservices-netflix-to-service-mesh/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;微服务架构的流行带来了一个悖论：系统被拆分成更小的单元以降低复杂度，但服务之间的通信却创造了一个更复杂的分布式系统。如何治理这个「服务间的混沌」，是过去十年基础架构领域最重要的课题之一。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;第一阶段蛮荒时代2014-之前&#34;&gt;第一阶段：蛮荒时代（2014 之前）&lt;/h2&gt;&#xA;&lt;p&gt;在微服务概念刚刚兴起的时候，服务治理几乎等于「手写一切」：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;服务 A 调用服务 B：&#xA;&#xA;1. 自己实现服务发现（查 ZooKeeper / Nginx upstream）&#xA;2. 自己实现负载均衡（轮询 / 随机）&#xA;3. 自己实现重试（try-catch + 循环）&#xA;4. 自己实现超时（设置 HTTP timeout）&#xA;5. 自己实现熔断（状态机 + 计数器）&#xA;&#xA;每一个服务的开发者都要重复实现这些逻辑，而且不同团队的实现质量参差不齐&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个阶段的核心问题是：&lt;strong&gt;治理逻辑和业务逻辑耦合在应用代码中&lt;/strong&gt;。每一次修改治理策略（比如调整超时时间），都需要修改业务代码、重新编译、重新部署。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第二阶段sdk-时代2014-2017&#34;&gt;第二阶段：SDK 时代（2014-2017）&lt;/h2&gt;&#xA;&lt;p&gt;Netflix 开源了一整套微服务治理工具（Netflix OSS），标志着微服务治理进入 SDK 时代：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Netflix OSS 全家桶：&#xA;&#xA;Eureka    → 服务注册与发现&#xA;Ribbon    → 客户端负载均衡&#xA;Hystrix   → 熔断器&#xA;Feign     → 声明式 HTTP 客户端&#xA;Zuul      → API 网关&#xA;Archaius  → 动态配置&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Spring Cloud 在此基础上做了封装，让 Java 开发者可以用注解的方式快速接入：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@FeignClient&lt;/span&gt;(name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user-service&amp;#34;&lt;/span&gt;, fallback &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; UserServiceFallback.&lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;UserServiceClient&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@GetMapping&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/users/{id}&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    User &lt;span style=&#34;color:#a6e22e&#34;&gt;getUser&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;@PathVariable&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;) Long id);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@Component&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;UserServiceFallback&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;implements&lt;/span&gt; UserServiceClient {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@Override&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; User &lt;span style=&#34;color:#a6e22e&#34;&gt;getUser&lt;/span&gt;(Long id) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; User.&lt;span style=&#34;color:#a6e22e&#34;&gt;defaultUser&lt;/span&gt;();  &lt;span style=&#34;color:#75715e&#34;&gt;// 熔断降级&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;sdk-模式的问题&#34;&gt;SDK 模式的问题&lt;/h3&gt;&#xA;&lt;p&gt;Netflix OSS 解决了「重复造轮子」的问题，但它引入了新的痛点：&lt;/p&gt;</description>
    </item>
    <item>
      <title>云算力 vs 本地破解：2026 年加密文件恢复方案选型指南</title>
      <link>https://blog-architectview.pages.dev/posts/cloud-vs-local-password-recovery/</link>
      <pubDate>Sat, 09 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/cloud-vs-local-password-recovery/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;作为一名架构师，我习惯用系统思维来分析问题——即使这个「问题」是忘了自己加密文件的密码。加密文件密码恢复本质上是一个算力密集型任务，而算力的获取方式无非两种：本地和云端。这篇文章从架构角度对比两种方案的优劣，帮你做出理性的选择。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;密码恢复的算力需求模型&#34;&gt;密码恢复的算力需求模型&lt;/h2&gt;&#xA;&lt;p&gt;先建立一个定量的认知框架。不同的加密格式，每次密码尝试的计算成本差异巨大：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;各格式单次密码尝试的计算成本（从低到高）：&#xA;&#xA;WPA2 握手包:     PBKDF2-SHA1, 4096 迭代     → 约 1,600 FLOPs/次&#xA;ZIP (ZipCrypto): RC4-40                       → 约 500 FLOPs/次&#xA;RAR3:            AES-128 + SHA1               → 约 5,000 FLOPs/次&#xA;Office 2007:     AES-128 + SHA1, 50K 迭代     → 约 20,000 FLOPs/次&#xA;RAR5:            AES-256 + SHA256, 可配置迭代  → 约 50,000 FLOPs/次&#xA;Office 2013+:    AES-256 + SHA512, 100K 迭代  → 约 100,000 FLOPs/次&#xA;BitLocker:       AES-256 + SHA256, 高迭代     → 约 100,000 FLOPs/次&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这意味着同一个 GPU，恢复 WPA2 密码的速度是恢复 Office 2013+ 密码的 &lt;strong&gt;60 倍以上&lt;/strong&gt;。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
