feat(transport): 完成安全架构拆分并收口 stream/bulk 传输优化

- 新增 managed/external/nested 三种传输保护模式
  - 新增 peer attach 显式认证、抗重放、channel binding 和可选前向保密协商
  - 明确单连接注入与可重拨连接源的语义边界
  - 禁止 ConnectByConn 场景下 dedicated bulk 走 sidecar,auto 模式自动回退 shared
  - 修正 dedicated attach 在 bootstrap/steady profile 切换下的处理逻辑
  - 优化 shared bulk super-batch 与批量 framed write 路径
  - 降低 stream/bulk fast path 的复制和分发损耗
  - 补齐 benchmark、回归测试、运行时快照和 README 文档
This commit is contained in:
2026-04-20 16:35:44 +08:00
parent f038a89771
commit 98ef9e7fcc
52 changed files with 4069 additions and 445 deletions
+114 -10
View File
@@ -83,7 +83,7 @@ func (r *bulkDedicatedLaneBatchRequest) reset() {
}
}
func (r *bulkDedicatedLaneBatchRequest) prepare(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest, wait bool) {
func (r *bulkDedicatedLaneBatchRequest) prepare(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest, wait bool, borrowItems bool) {
if r == nil {
return
}
@@ -94,6 +94,10 @@ func (r *bulkDedicatedLaneBatchRequest) prepare(ctx context.Context, dataID uint
if deadline, ok := ctx.Deadline(); ok {
r.Deadline = deadline
}
if borrowItems {
r.Items = items
return
}
if cap(r.Items) < len(items) {
r.Items = make([]bulkDedicatedSendRequest, len(items))
} else {
@@ -119,10 +123,10 @@ func (s *bulkDedicatedLaneSender) submitData(ctx context.Context, dataID uint64,
Seq: seq,
Payload: append([]byte(nil), payload...),
}}
return s.submitBatch(ctx, dataID, items, false)
return s.submitBatch(ctx, dataID, items, false, false)
}
func (s *bulkDedicatedLaneSender) submitWrite(ctx context.Context, dataID uint64, startSeq uint64, payload []byte, chunkSize int) (int, error) {
func (s *bulkDedicatedLaneSender) submitWrite(ctx context.Context, dataID uint64, startSeq uint64, payload []byte, chunkSize int, payloadOwned bool) (int, error) {
if s == nil {
return 0, errTransportDetached
}
@@ -132,6 +136,9 @@ func (s *bulkDedicatedLaneSender) submitWrite(ctx context.Context, dataID uint64
if chunkSize <= 0 {
chunkSize = defaultBulkChunkSize
}
if submitted, written, err := s.tryDirectSubmitWrite(ctx, dataID, startSeq, payload, chunkSize); submitted {
return written, err
}
written := 0
seq := startSeq
for written < len(payload) {
@@ -170,7 +177,7 @@ func (s *bulkDedicatedLaneSender) submitWrite(ctx context.Context, dataID uint64
seq++
written = end
}
if err := s.submitWriteBatch(ctx, dataID, items); err != nil {
if err := s.submitWriteBatch(ctx, dataID, items, payloadOwned); err != nil {
return start, err
}
start = written
@@ -178,7 +185,7 @@ func (s *bulkDedicatedLaneSender) submitWrite(ctx context.Context, dataID uint64
return written, nil
}
func (s *bulkDedicatedLaneSender) submitWriteBatch(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest) error {
func (s *bulkDedicatedLaneSender) submitWriteBatch(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest, _ bool) error {
if s == nil {
return errTransportDetached
}
@@ -188,8 +195,7 @@ func (s *bulkDedicatedLaneSender) submitWriteBatch(ctx context.Context, dataID u
if submitted, err := s.tryDirectSubmitBatch(ctx, dataID, items); submitted {
return err
}
queuedItems := copyBulkDedicatedSendRequests(items)
return s.submitBatch(ctx, dataID, queuedItems, true)
return s.submitBatch(ctx, dataID, items, true, true)
}
func (s *bulkDedicatedLaneSender) submitControl(ctx context.Context, dataID uint64, frameType uint8, flags uint8, seq uint64, payload []byte) error {
@@ -204,10 +210,10 @@ func (s *bulkDedicatedLaneSender) submitControl(ctx context.Context, dataID uint
if len(payload) > 0 {
items[0].Payload = append([]byte(nil), payload...)
}
return s.submitBatch(ctx, dataID, items, true)
return s.submitBatch(ctx, dataID, items, true, false)
}
func (s *bulkDedicatedLaneSender) submitBatch(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest, wait bool) error {
func (s *bulkDedicatedLaneSender) submitBatch(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest, wait bool, borrowItems bool) error {
if s == nil {
return errTransportDetached
}
@@ -218,7 +224,7 @@ func (s *bulkDedicatedLaneSender) submitBatch(ctx context.Context, dataID uint64
return err
}
req := getBulkDedicatedLaneBatchRequest()
req.prepare(ctx, dataID, items, wait)
req.prepare(ctx, dataID, items, wait, borrowItems)
s.queued.Add(1)
select {
case <-ctx.Done():
@@ -237,6 +243,104 @@ func (s *bulkDedicatedLaneSender) submitBatch(ctx context.Context, dataID uint64
}
}
func (s *bulkDedicatedLaneSender) tryDirectSubmitWrite(ctx context.Context, dataID uint64, startSeq uint64, payload []byte, chunkSize int) (bool, int, error) {
if s == nil {
return true, 0, errTransportDetached
}
if ctx == nil {
ctx = context.Background()
}
if len(payload) == 0 {
return true, 0, nil
}
if chunkSize <= 0 {
chunkSize = defaultBulkChunkSize
}
if err := s.errSnapshot(); err != nil {
return true, 0, err
}
select {
case <-ctx.Done():
return true, 0, normalizeStreamDeadlineError(ctx.Err())
case <-s.stopCh:
return true, 0, s.stoppedErr()
default:
}
if s.queued.Load() != 0 {
return false, 0, nil
}
if !s.flushMu.TryLock() {
return false, 0, nil
}
defer s.flushMu.Unlock()
if s.queued.Load() != 0 {
return false, 0, nil
}
if err := s.errSnapshot(); err != nil {
return true, 0, err
}
written := 0
seq := startSeq
deadline, _ := ctx.Deadline()
for written < len(payload) {
select {
case <-ctx.Done():
return true, written, normalizeStreamDeadlineError(ctx.Err())
case <-s.stopCh:
return true, written, s.stoppedErr()
default:
}
var itemBuf [bulkDedicatedBatchMaxItems]bulkDedicatedSendRequest
items := itemBuf[:0]
batchBytes := bulkDedicatedBatchHeaderLen
start := written
for written < len(payload) && len(items) < bulkDedicatedBatchMaxItems {
end := written + chunkSize
if end > len(payload) {
end = len(payload)
}
itemLen := bulkDedicatedSendRequestLenFromPayloadLen(end - written)
if len(items) > 0 && batchBytes+itemLen > bulkDedicatedBatchMaxPlainBytes {
break
}
items = append(items, bulkDedicatedSendRequest{
Type: bulkFastPayloadTypeData,
Seq: seq,
Payload: payload[written:end],
})
batchBytes += itemLen
seq++
written = end
}
if len(items) == 0 {
end := written + chunkSize
if end > len(payload) {
end = len(payload)
}
items = append(items, bulkDedicatedSendRequest{
Type: bulkFastPayloadTypeData,
Seq: seq,
Payload: payload[written:end],
})
seq++
written = end
}
if err := s.flush([]bulkDedicatedOutboundBatch{{
DataID: dataID,
Items: items,
}}, deadline); err != nil {
err = normalizeDedicatedBulkSendError(err)
s.setErr(err)
s.failPending(err)
if s.fail != nil {
go s.fail(err)
}
return true, start, err
}
}
return true, written, nil
}
func (s *bulkDedicatedLaneSender) tryDirectSubmitBatch(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest) (bool, error) {
if s == nil {
return true, errTransportDetached