用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/microwind/ai-skills --skill cap命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | CAP定理应用 |
| description | 当应用CAP定理时,分析一致性模型,优化可用性保证,解决分区容错。验证系统架构,设计权衡策略,和最佳实践。 |
| license | MIT |
CAP定理是分布式系统设计的核心理论,指出分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)中的两个特性。理解CAP定理有助于在系统设计中做出正确的权衡决策。
核心原则: 在分布式系统中,网络分区是必然发生的,必须在一致性和可用性之间做出选择。没有完美的解决方案,只有适合特定场景的权衡。
始终:
触发短语:
问题: 数据不一致导致业务错误
原因: 分布式环境下数据同步延迟
解决: 选择合适的一致性模型,实现补偿机制
问题: 强一致性影响系统性能
原因: 过于严格的一致性要求
解决: 根据业务需求选择适当的一致性级别
问题: 系统故障导致服务不可用
原因: 缺乏高可用设计
解决: 实现冗余部署,故障自动转移
问题: 过度设计增加复杂性
原因: 不必要的可用性保证
解决: 根据业务重要性合理设计
// CP配置服务(一致性优先)
@Service
public class CPConfigurationService {
private final List<ConfigNode> configNodes;
private final ConsensusAlgorithm consensus;
private final ConfigStorage storage;
public CPConfigurationService(List<ConfigNode> configNodes,
ConsensusAlgorithm consensus,
ConfigStorage storage) {
this.configNodes = configNodes;
this.consensus = consensus;
this.storage = storage;
}
// 获取配置(强一致性)
public Config getConfig(String key) throws ConsensusException {
// 通过共识算法获取最新配置
ConfigValue value = consensus.get(key);
if (value == null) {
throw new ConfigNotFoundException("Config not found: " + key);
}
return new Config(key, value.getValue(), value.getVersion());
}
// 更新配置(需要共识)
@Transactional
public void updateConfig(String key, String value) throws ConsensusException {
// 1. 通过共识算法达成一致
ConfigValue (key, value, System.currentTimeMillis());
consensus.propose(newValue);
(!consensus.waitForQuorum(Duration.ofSeconds())) {
();
}
storage.store(key, newValue);
}
ConsensusException {
consensus.proposeDelete(key);
(!consensus.waitForQuorum(Duration.ofSeconds())) {
();
}
storage.delete(key);
}
ConsensusException {
();
configs.forEach((key, value) -> {
(key, value, System.currentTimeMillis());
batch.addUpdate(configValue);
});
consensus.proposeBatch(batch);
(!consensus.waitForQuorum(Duration.ofSeconds())) {
();
}
storage.batchStore(configs);
}
}
{
RaftNode raftNode;
Map<String, ConfigValue> configCache = <>();
{
.raftNode = raftNode;
}
ConfigValue {
configCache.get(key);
(cached != ) {
cached;
}
{
raftNode.getStateMachine().get(key);
(value != ) {
configCache.put(key, value);
}
value;
} (RaftException e) {
(, e);
}
}
ConsensusException {
{
CompletableFuture<Boolean> future = raftNode.propose(configValue);
future.get(, TimeUnit.SECONDS);
(!result) {
();
}
configCache.put(configValue.getKey(), configValue);
} (Exception e) {
(, e);
}
}
ConsensusException {
{
(key);
CompletableFuture<Boolean> future = raftNode.propose(deleteOp);
future.get(, TimeUnit.SECONDS);
(!result) {
();
}
configCache.remove(key);
} (Exception e) {
(, e);
}
}
ConsensusException {
{
CompletableFuture<Boolean> future = raftNode.propose(batch);
future.get(, TimeUnit.SECONDS);
(!result) {
();
}
(ConfigValue configValue : batch.getUpdates()) {
configCache.put(configValue.getKey(), configValue);
}
} (Exception e) {
(, e);
}
}
{
{
raftNode.waitForCommitIndex(timeout);
} (Exception e) {
;
}
}
}
// AP用户服务(可用性优先)
@Service
public class APUserService {
private final List<UserDataStore> dataStores;
private final ConflictResolver conflictResolver;
private final EventPublisher eventPublisher;
public APUserService(List<UserDataStore> dataStores,
ConflictResolver conflictResolver,
EventPublisher eventPublisher) {
this.dataStores = dataStores;
this.conflictResolver = conflictResolver;
this.eventPublisher = eventPublisher;
}
// 获取用户(最终一致性)
public User getUser(String userId) {
// 尝试从本地数据存储获取
for (UserDataStore store : dataStores) {
try {
User user = store.getUser(userId);
if (user != null) {
return user;
}
} catch (Exception e) {
// 忽略单个存储的故障,继续尝试其他存储
log.warn("Failed to get user from store: {}", store.getClass().getSimpleName(), e);
}
}
// 如果所有存储都失败,返回null而不是抛出异常
return null;
}
// 创建用户(写入多个存储)
public User createUser(User user) {
User user.withId(UUID.randomUUID().toString());
(createdUser, System.currentTimeMillis());
List<CompletableFuture<Boolean>> futures = dataStores.stream()
.map(store -> CompletableFuture.supplyAsync(() -> {
{
store.createUser(versionedUser);
} (Exception e) {
log.error(, store.getClass().getSimpleName(), e);
;
}
}))
.collect(Collectors.toList());
{
CompletableFuture.anyOf(futures.toArray( []))
.get(, TimeUnit.SECONDS);
} (Exception e) {
log.warn();
}
eventPublisher.publishEvent( (createdUser));
createdUser;
}
User {
getLatestUserVersion(userId);
(currentUser == ) {
( + userId);
}
currentUser.withUpdate(update);
List<CompletableFuture<Boolean>> futures = dataStores.stream()
.map(store -> CompletableFuture.supplyAsync(() -> {
{
store.updateUser(updatedUser);
} (Exception e) {
log.error(, store.getClass().getSimpleName(), e);
;
}
}))
.collect(Collectors.toList());
eventPublisher.publishEvent( (updatedUser.getUser()));
updatedUser.getUser();
}
{
getLatestUserVersion(userId);
(currentUser == ) {
;
}
List<CompletableFuture<Boolean>> futures = dataStores.stream()
.map(store -> CompletableFuture.supplyAsync(() -> {
{
store.deleteUser(userId);
} (Exception e) {
log.error(, store.getClass().getSimpleName(), e);
;
}
}))
.collect(Collectors.toList());
eventPublisher.publishEvent( (userId));
}
UserVersioned {
List<UserVersioned> versions = <>();
(UserDataStore store : dataStores) {
{
store.getUserVersion(userId);
(version != ) {
versions.add(version);
}
} (Exception e) {
log.warn(, store.getClass().getSimpleName(), e);
}
}
(versions.isEmpty()) {
;
}
conflictResolver.resolveConflict(versions);
}
}
{
UserVersioned {
(versions.size() == ) {
versions.get();
}
versions.stream()
.max(Comparator.comparing(UserVersioned::getTimestamp))
.orElse(versions.get());
}
UserVersioned {
(versions.size() == ) {
versions.get();
}
versions.get();
( ; i < versions.size(); i++) {
merged = mergeVersions(merged, versions.get(i));
}
merged;
}
UserVersioned {
v1.getUser();
v2.getUser();
User. User.builder()
.id(mergedUser.getId())
.name(getNewerValue(mergedUser.getName(), user2.getName(), v1.getTimestamp(), v2.getTimestamp()))
.email(getNewerValue(mergedUser.getEmail(), user2.getEmail(), v1.getTimestamp(), v2.getTimestamp()))
.age(getNewerValue(mergedUser.getAge(), user2.getAge(), v1.getTimestamp(), v2.getTimestamp()));
(builder.build(), Math.max(v1.getTimestamp(), v2.getTimestamp()));
}
<T> T {
timestamp1 > timestamp2 ? value1 : value2;
}
}
// 混合CAP配置管理器
@Service
public class HybridCAPConfigManager {
private final CPConfigurationService cpService; // 强一致性配置
private final APConfigurationService apService; // 高可用配置
private final ConfigClassifier classifier; // 配置分类器
public HybridCAPConfigManager(CPConfigurationService cpService,
APConfigurationService apService,
ConfigClassifier classifier) {
this.cpService = cpService;
this.apService = apService;
this.classifier = classifier;
}
// 获取配置(根据类型选择策略)
public Config getConfig(String key) {
ConfigType type = classifier.classify(key);
switch (type) {
case CRITICAL:
// 关键配置使用CP策略
try {
return cpService.getConfig(key);
} catch (ConsensusException e) {
log.error("Failed to get critical config from CP service, falling back to AP", e);
return apService.getConfig(key);
}
case NON_CRITICAL:
// 非关键配置使用AP策略
return apService.getConfig(key);
default:
throw ( + type);
}
}
{
classifier.classify(key);
(type) {
CRITICAL:
{
cpService.updateConfig(key, value);
} (ConsensusException e) {
log.error(, e);
retryUpdate(key, value, type);
}
;
NON_CRITICAL:
apService.updateConfig(key, value);
;
:
( + type);
}
}
{
Map<String, String> criticalConfigs = <>();
Map<String, String> nonCriticalConfigs = <>();
configs.forEach((key, value) -> {
classifier.classify(key);
(type == ConfigType.CRITICAL) {
criticalConfigs.put(key, value);
} {
nonCriticalConfigs.put(key, value);
}
});
CompletableFuture<Void> cpFuture = CompletableFuture.runAsync(() -> {
(!criticalConfigs.isEmpty()) {
{
cpService.batchUpdateConfigs(criticalConfigs);
} (ConsensusException e) {
log.error(, e);
}
}
});
CompletableFuture<Void> apFuture = CompletableFuture.runAsync(() -> {
(!nonCriticalConfigs.isEmpty()) {
apService.batchUpdateConfigs(nonCriticalConfigs);
}
});
CompletableFuture.allOf(cpFuture, apFuture).join();
}
{
;
;
( ; i < maxRetries; i++) {
{
Thread.sleep(retryDelay * (i + ));
(type == ConfigType.CRITICAL) {
cpService.updateConfig(key, value);
} {
apService.updateConfig(key, value);
}
log.info(, i + , key);
;
} (Exception e) {
log.warn(, i + , key, e);
}
}
log.error(, maxRetries, key);
}
}
{
Set<String> criticalConfigPatterns;
{
criticalConfigPatterns = Set.of(
,
,
,
,
);
}
ConfigType {
(String pattern : criticalConfigPatterns) {
(configKey.matches(pattern.replace(, ))) {
ConfigType.CRITICAL;
}
}
ConfigType.NON_CRITICAL;
}
{
CRITICAL,
NON_CRITICAL
}
}
// 分区检测器
@Component
public class PartitionDetector {
private final List<Node> clusterNodes;
private final PartitionHandler partitionHandler;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public PartitionDetector(List<Node> clusterNodes, PartitionHandler partitionHandler) {
this.clusterNodes = clusterNodes;
this.partitionHandler = partitionHandler;
}
@PostConstruct
public void startDetection() {
// 定期检测网络分区
scheduler.scheduleAtFixedRate(this::detectPartitions, 5, 5, TimeUnit.SECONDS);
}
// 检测网络分区
private void detectPartitions() {
Map<Node, NodeStatus> nodeStatuses = new HashMap<>();
// 检查所有节点状态
for (Node node : clusterNodes) {
try {
NodeStatus status = checkNodeStatus(node);
nodeStatuses.put(node, status);
} catch (Exception e) {
nodeStatuses.put(node, NodeStatus.UNREACHABLE);
}
}
// 分析分区情况
analyzePartitions(nodeStatuses);
(partitionInfo.hasPartition()) {
partitionHandler.handlePartition(partitionInfo);
}
}
NodeStatus {
{
node.sendHeartbeat();
(response.isHealthy()) {
NodeStatus.HEALTHY;
} {
NodeStatus.UNHEALTHY;
}
} (Exception e) {
NodeStatus.UNREACHABLE;
}
}
PartitionInfo {
List<Node> healthyNodes = nodeStatuses.entrySet().stream()
.filter(entry -> entry.getValue() == NodeStatus.HEALTHY)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
List<Node> unhealthyNodes = nodeStatuses.entrySet().stream()
.filter(entry -> entry.getValue() != NodeStatus.HEALTHY)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
healthyNodes.size() > && unhealthyNodes.size() > ;
(healthyNodes, unhealthyNodes, hasPartition);
}
{
scheduler.shutdown();
}
{
HEALTHY, UNHEALTHY, UNREACHABLE
}
}
{
Node currentNode;
CAPStrategy capStrategy;
{
.currentNode = currentNode;
.capStrategy = capStrategy;
}
{
List<Node> healthyNodes = partitionInfo.getHealthyNodes();
List<Node> unhealthyNodes = partitionInfo.getUnhealthyNodes();
healthyNodes.contains(currentNode);
(currentInHealthy) {
handleHealthyPartition(healthyNodes, unhealthyNodes);
} {
handleUnhealthyPartition(healthyNodes, unhealthyNodes);
}
}
{
log.info(,
currentNode.getId(), healthyNodes.size());
(capStrategy == CAPStrategy.CP) {
enableReadOnlyMode();
} (capStrategy == CAPStrategy.AP) {
enableNormalMode();
}
logPartitionEvent(, healthyNodes, unhealthyNodes);
}
{
log.warn(,
currentNode.getId(), unhealthyNodes.size());
(capStrategy == CAPStrategy.CP) {
enableMaintenanceMode();
} (capStrategy == CAPStrategy.AP) {
enableNormalMode();
}
logPartitionEvent(, healthyNodes, unhealthyNodes);
}
{
log.info();
}
{
log.info();
}
{
log.info();
}
{
(
eventType,
currentNode.getId(),
healthyNodes.stream().map(Node::getId).collect(Collectors.toList()),
unhealthyNodes.stream().map(Node::getId).collect(Collectors.toList()),
System.currentTimeMillis()
);
getEventPublisher();
(publisher != ) {
publisher.publishEvent(event);
}
}
ApplicationEventPublisher {
;
}
{
CP,
AP
}
}