@@ -92,4 +92,4 @@ T3 : Message Content | |||||
默认值:24*3600 秒(1天后) | 默认值:24*3600 秒(1天后) | ||||
成功消息的过期时间(秒)。 当消息发送或者消费成功时候,在时间达到 `SucceedMessageExpiredAfter` 秒时候将会从 Persistent 中删除,你可以通过指定此值来设置过期的时间。 | |||||
成功消息的过期时间(秒)。 当消息发送或者消费成功时候,在时间达到 `SucceedMessageExpiredAfter` 秒时候将会从 Persistent 中删除,你可以通过指定此值来设置过期的时间。 |
@@ -6,5 +6,16 @@ CAP 不直接提供开箱即用的基于 DTC 或者 2PC 的分布式事务,相 | |||||
在分布式环境中,由于涉及通讯的开销,使用基于2PC或DTC的分布式事务将非常昂贵,在性能方面也同样如此。另外由于基于2PC或DTC的分布式事务同样受**CAP定理**的约束,当发生网络分区时它将不得不放弃可用性(CAP中的A)。 | 在分布式环境中,由于涉及通讯的开销,使用基于2PC或DTC的分布式事务将非常昂贵,在性能方面也同样如此。另外由于基于2PC或DTC的分布式事务同样受**CAP定理**的约束,当发生网络分区时它将不得不放弃可用性(CAP中的A)。 | ||||
## 场景 | |||||
针对于分布式事务的处理,CAP 采用的是“异步确保”这种方案。 | |||||
### 异步确保 | |||||
异步确保这种方案又叫做本地消息表,这是一种经典的方案,方案最初来源于 eBay,参考资料见段末链接。这种方案目前也是企业中使用最多的方案之一。 | |||||
相对于 TCC 或者 2PC/3PC 来说,这个方案对于分布式事务来说是最简单的,而且它是去中心化的。在TCC 或者 2PC 的方案中,必须具有事务协调器来处理每个不同服务之间的状态,而此种方案不需要事务协调器。 | |||||
另外 2PC/TCC 这种方案如果服务依赖过多,会带来管理复杂性增加和稳定性风险增大的问题。试想如果我们强依赖 10 个服务,9 个都执行成功了,最后一个执行失败了,那么是不是前面 9 个都要回滚掉?这个成本还是非常高的。 | |||||
但是,并不是说 2PC 或者 TCC 这种方案不好,因为每一种方案都有其相对优势的使用场景和优缺点,这里就不做过多介绍了。 | |||||
> 中文:[http://www.cnblogs.com/savorboard/p/base-an-acid-alternative.html](http://www.cnblogs.com/savorboard/p/base-an-acid-alternative.html) | |||||
> 英文:[http://queue.acm.org/detail.cfm?id=1394128](http://queue.acm.org/detail.cfm?id=1394128) |
@@ -1,6 +1,14 @@ | |||||
# 基本 | # 基本 | ||||
CAP 需要使用具有持久化功能的存储介质来存储事件消息,例如通过数据库或者其他NoSql设施。 | |||||
CAP 需要使用具有持久化功能的存储介质来存储事件消息,例如通过数据库或者其他NoSql设施。CAP 使用这种方式来应对一切环境或者网络异常导致消息丢失的情况,消息的可靠性是分布式事务的基石,所以在任何情况下消息都不能丢失。 | |||||
对于消息的持久化分为两种: | |||||
**① 消息进入消息队列之前的持久化** | |||||
在消息进入到消息队列之前,CAP使用本地数据库表对消息进行持久化,这样可以保证当消息队列出现异常或者网络错误时候消息是没有丢失的。 | |||||
为了保证这种机制的可靠性,CAP使用和业务代码相同的数据库事务来保证业务操作和CAP的消息在持久化的过程中是强一致的。也就是说在进行消息持久化的过程中,任何一方发生异常情况数据库都会进行回滚操作。 | |||||
在 CAP 启动后,会向持久化介质中生成两个表,默认情况下名称为:`Cap.Published` `Cap.Received`。 | 在 CAP 启动后,会向持久化介质中生成两个表,默认情况下名称为:`Cap.Published` `Cap.Received`。 | ||||
@@ -42,4 +50,12 @@ Timestamp | 消息创建时间 | string | |||||
Content | 内容 | string | Content | 内容 | string | ||||
CallbackName | 回调的订阅者名称 | string | CallbackName | 回调的订阅者名称 | string | ||||
其中 Id 字段,CAP 采用的 MongoDB 中的 ObjectId 分布式Id生成算法生成。 | |||||
其中 Id 字段,CAP 采用的 MongoDB 中的 ObjectId 分布式Id生成算法生成。 | |||||
**② 消息进入到消息队列之后的持久化** | |||||
消息进入到消息队列之后,CAP会启动消息队列的持久化功能,我们需要说明一下在 RabbitMQ 和 Kafka 中CAP的消息是如何持久化的。 | |||||
针对于 RabbitMQ 中的消息持久化,CAP 使用的是具有消息持久化功能的消费者队列,但是这里面可能有例外情况,参加 2.2.1 章节。 | |||||
由于 Kafka 天生设计的就是使用文件进行的消息持久化,在所以在消息进入到Kafka之后,Kafka会保证消息能够正确被持久化而不丢失。 |
@@ -1 +1,22 @@ | |||||
# MySQL | |||||
# MySQL | |||||
### MySql Options | |||||
注意,如果你使用的是 EntityFramewrok,你用不到此配置项。 | |||||
CAP 采用的是针对 CapOptions 进行扩展来实现 MySql 的配置功能,所以针对 MySql 的配置用法如下: | |||||
```cs | |||||
services.AddCap(capOptions => { | |||||
capOptions.UseMySql(mysqlOptions => { | |||||
// mysqlOptions.ConnectionString | |||||
}); | |||||
}); | |||||
``` | |||||
NAME | DESCRIPTION | TYPE | DEFAULT | |||||
:---|:---|---|:--- | |||||
TableNamePrefix | Cap表名前缀 | string | cap | |||||
ConnectionString | 数据库连接字符串 | string | null |
@@ -1 +1,22 @@ | |||||
# Postgre SQL | |||||
# Postgre SQL | |||||
### PostgreSql Configs | |||||
Note that if you are using EntityFramewrok, you do not use this configuration item. | |||||
CAP uses PostgreSql configuration functions for CapOptions extensions, so the configuration usage for PostgreSql is as follows: | |||||
```c# | |||||
services.AddCap(capOptions => { | |||||
capOptions.UsePostgreSql(postgreOptions => { | |||||
// postgreOptions.ConnectionString | |||||
}); | |||||
}); | |||||
``` | |||||
NAME | DESCRIPTION | TYPE | DEFAULT | |||||
:---|:---|---|:------ | |||||
Schema | Cap table name prefix | string | cap | |||||
ConnectionString | Database connection string | string | null |
@@ -1 +1,22 @@ | |||||
# SQLServer | |||||
# SQLServer | |||||
### SqlServer Options | |||||
注意,如果你使用的是 EntityFramewrok,你用不到此配置项。 | |||||
CAP 采用的是针对 CapOptions 进行扩展来实现 SqlServer 的配置功能,所以针对 SqlServer 的配置用法如下: | |||||
```cs | |||||
services.AddCap(capOptions => { | |||||
capOptions.UseSqlServer(sqlserverOptions => { | |||||
// sqlserverOptions.ConnectionString | |||||
}); | |||||
}); | |||||
``` | |||||
NAME | DESCRIPTION | TYPE | DEFAULT | |||||
:---|:---|---|:--- | |||||
Schema | Cap表架构 | string | Cap | |||||
ConnectionString | 数据库连接字符串 | string | null |
@@ -1 +1,20 @@ | |||||
# Kafka | |||||
# Kafka | |||||
### Kafka Options | |||||
CAP 采用的是针对 CapOptions 进行扩展来实现 Kafka 的配置功能,所以针对 Kafka 的配置用法如下: | |||||
```cs | |||||
services.AddCap(capOptions => { | |||||
capOptions.UseKafka(kafkaOption=>{ | |||||
// kafka options. | |||||
// kafkaOptions.MainConfig.Add("", ""); | |||||
}); | |||||
}); | |||||
``` | |||||
`KafkaOptions` 提供了有关 Kafka 相关的配置,由于Kafka的配置比较多,所以此处使用的是提供的 MainConfig 字典来支持进行自定义配置,你可以查看这里来获取对配置项的支持信息。 | |||||
[https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md](https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md) | |||||
@@ -1 +1,28 @@ | |||||
# RabbitMQ | |||||
# RabbitMQ | |||||
## RabbitMQ Configs | |||||
The CAP uses the CapOptions extension to implement the RabbitMQ configuration function. Therefore, the configuration of the RabbitMQ is used as follows: | |||||
```cs | |||||
services.AddCap(capOptions => { | |||||
capOptions.UseRabbitMQ(rabbitMQOption=>{ | |||||
// rabbitmq options. | |||||
}); | |||||
}); | |||||
``` | |||||
`RabbitMQOptions` provides related RabbitMQ configuration: | |||||
NAME | DESCRIPTION | TYPE | DEFAULT | |||||
:---|:---|---|:------ | |||||
HostName | Host Address | string | localhost | |||||
UserName | username | string | guest | |||||
Password | Password | string | guest | |||||
VirtualHost | Virtual Host | string | / | |||||
Port | Port number | int | -1 | |||||
TopicExchangeName | CAP Default Exchange Name | string | cap.default.topic | |||||
RequestedConnectionTimeout | RabbitMQ Connection Timeout | int | 30,000 milliseconds | |||||
SocketReadTimeout | RabbitMQ message read timeout | int | 30,000 milliseconds | |||||
SocketWriteTimeout | RabbitMQ message write timeout | int | 30,000 milliseconds | |||||
QueueMessageExpires | Automatic deletion of messages in queue | int | (10 days) ms |