refactor: 重构trustlog-sdk目录结构到trustlog/go-trustlog
- 将所有trustlog-sdk文件移动到trustlog/go-trustlog/目录 - 更新README中所有import路径从trustlog-sdk改为go-trustlog - 更新cookiecutter配置文件中的项目名称 - 更新根目录.lefthook.yml以引用新位置的配置 - 添加go.sum文件到版本控制 - 删除过时的示例文件 这次重构与trustlog-server保持一致的目录结构, 为未来支持多语言SDK(Python、Java等)预留空间。
This commit is contained in:
205
api/adapter/TCP_QUICK_START.md
Normal file
205
api/adapter/TCP_QUICK_START.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# TCP 适配器快速开始指南
|
||||
|
||||
## 简介
|
||||
|
||||
TCP 适配器提供了一个无需 Pulsar 的 Watermill 消息发布/订阅实现,适用于内网直连场景。
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 启动消费端(Subscriber)
|
||||
|
||||
消费端作为 TCP 服务器,监听指定端口。
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"go.yandata.net/iod/iod/trustlog-sdk/api/adapter"
|
||||
"go.yandata.net/iod/iod/trustlog-sdk/api/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 使用 NopLogger 或自定义 logger
|
||||
log := logger.NewNopLogger()
|
||||
|
||||
// 创建 Subscriber
|
||||
config := adapter.TCPSubscriberConfig{
|
||||
ListenAddr: "127.0.0.1:9090",
|
||||
}
|
||||
|
||||
subscriber, err := adapter.NewTCPSubscriber(config, log)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer subscriber.Close()
|
||||
|
||||
// 订阅 topic
|
||||
messages, err := subscriber.Subscribe(context.Background(), "my-topic")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 处理消息
|
||||
for msg := range messages {
|
||||
log.Println("收到消息:", string(msg.Payload))
|
||||
msg.Ack() // 确认消息
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 启动生产端(Publisher)
|
||||
|
||||
生产端作为 TCP 客户端,连接到消费端。
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ThreeDotsLabs/watermill/message"
|
||||
"go.yandata.net/iod/iod/trustlog-sdk/api/adapter"
|
||||
"go.yandata.net/iod/iod/trustlog-sdk/api/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logger.NewNopLogger()
|
||||
|
||||
// 创建 Publisher
|
||||
config := adapter.TCPPublisherConfig{
|
||||
ServerAddr: "127.0.0.1:9090",
|
||||
ConnectTimeout: 5 * time.Second,
|
||||
AckTimeout: 10 * time.Second,
|
||||
}
|
||||
|
||||
publisher, err := adapter.NewTCPPublisher(config, log)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer publisher.Close()
|
||||
|
||||
// 发送消息
|
||||
msg := message.NewMessage("msg-001", []byte("Hello, World!"))
|
||||
|
||||
err = publisher.Publish("my-topic", msg)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("消息发送成功")
|
||||
}
|
||||
```
|
||||
|
||||
## 特性演示
|
||||
|
||||
### 并发发送多条消息
|
||||
|
||||
```go
|
||||
// 准备 10 条消息
|
||||
messages := make([]*message.Message, 10)
|
||||
for i := 0; i < 10; i++ {
|
||||
payload := []byte(fmt.Sprintf("Message #%d", i))
|
||||
messages[i] = message.NewMessage(fmt.Sprintf("msg-%d", i), payload)
|
||||
}
|
||||
|
||||
// 并发发送,Publisher 会等待所有 ACK
|
||||
err := publisher.Publish("my-topic", messages...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("所有消息发送成功")
|
||||
```
|
||||
|
||||
### 错误处理和 NACK
|
||||
|
||||
```go
|
||||
// 在消费端
|
||||
for msg := range messages {
|
||||
// 处理消息
|
||||
if err := processMessage(msg); err != nil {
|
||||
log.Println("处理失败:", err)
|
||||
msg.Nack() // 拒绝消息
|
||||
continue
|
||||
}
|
||||
msg.Ack() // 确认消息
|
||||
}
|
||||
```
|
||||
|
||||
## 配置参数
|
||||
|
||||
### TCPPublisherConfig
|
||||
|
||||
```go
|
||||
type TCPPublisherConfig struct {
|
||||
ServerAddr string // 必填: TCP 服务器地址,如 "127.0.0.1:9090"
|
||||
ConnectTimeout time.Duration // 连接超时,默认 10s
|
||||
AckTimeout time.Duration // ACK 超时,默认 30s
|
||||
MaxRetries int // 最大重试次数,默认 3
|
||||
}
|
||||
```
|
||||
|
||||
### TCPSubscriberConfig
|
||||
|
||||
```go
|
||||
type TCPSubscriberConfig struct {
|
||||
ListenAddr string // 必填: 监听地址,如 "127.0.0.1:9090"
|
||||
}
|
||||
```
|
||||
|
||||
## 运行示例
|
||||
|
||||
```bash
|
||||
# 运行完整示例
|
||||
cd trustlog-sdk/examples
|
||||
go run tcp_example.go
|
||||
```
|
||||
|
||||
## 性能特点
|
||||
|
||||
- ✅ **低延迟**: 直接 TCP 连接,无中间件开销
|
||||
- ✅ **高并发**: 支持并发发送多条消息
|
||||
- ✅ **可靠性**: 每条消息都需要 ACK 确认
|
||||
- ⚠️ **无持久化**: 消息仅在内存中传递
|
||||
|
||||
## 适用场景
|
||||
|
||||
✅ **适合:**
|
||||
- 内网服务间直接通信
|
||||
- 开发和测试环境
|
||||
- 无需消息持久化的场景
|
||||
- 低延迟要求的场景
|
||||
|
||||
❌ **不适合:**
|
||||
- 需要消息持久化
|
||||
- 需要高可用和故障恢复
|
||||
- 公网通信(需要加密)
|
||||
- 需要复杂的路由和负载均衡
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 如何处理连接断开?
|
||||
|
||||
A: 当前版本连接断开后需要重新创建 Publisher。未来版本将支持自动重连。
|
||||
|
||||
### Q: 消息会丢失吗?
|
||||
|
||||
A: TCP 适配器不提供持久化,连接断开或服务重启会导致未确认的消息丢失。
|
||||
|
||||
### Q: 如何实现多个消费者?
|
||||
|
||||
A: 当前版本将消息发送到第一个订阅者。如需负载均衡,需要在应用层实现。
|
||||
|
||||
### Q: 支持 TLS 加密吗?
|
||||
|
||||
A: 当前版本不支持 TLS。未来版本将添加 TLS/mTLS 支持。
|
||||
|
||||
## 下一步
|
||||
|
||||
- 查看 [完整文档](TCP_ADAPTER_README.md)
|
||||
- 运行 [测试用例](tcp_integration_test.go)
|
||||
- 查看 [示例代码](../../examples/tcp_example.go)
|
||||
|
||||
Reference in New Issue
Block a user