Alanxtl commented on issue #3093:
URL: https://github.com/apache/dubbo-go/issues/3093#issuecomment-4680938036

   https://github.com/apache/dubbo-go/issues/3204#issuecomment-4680890484
   
   Rpc 这边 old_triple 有问题,启动服务端会 panic,以下是 Claude Fable 5 的总结分析
   
   ### 问题描述:
   
   老 triple(compat)服务处理 unary 调用时,server 端 goroutine panic,HTTP/2 流被重置。客户端只能看到:
   
   internal: stream error: stream ID 7; INTERNAL_ERROR; received from peer
   
   Server 端堆栈:
   ```
   panic: unsupported attachment value type bool
   
   
dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol.(*tripleCompatInterceptor).compatUnaryServerInterceptor.func1(...)
           protocol/triple/triple_protocol/handler_compat.go:91
   github.com/.../proto._GreetService_Greet_Handler(...)
           greet_triple.pb.go:152
   ...NewCompatUnaryHandler.generateCompatUnaryHandlerFunc.func1(...)
           protocol/triple/triple_protocol/handler_compat.go:157
   ...(*Handler).ServeHTTP(...)
   ```
   ### 根因
   
   compatUnaryServerInterceptor 把 RPCResult.Attachments() 复制到 HTTP trailer 
时,遇到非 string / []string 类型的值直接 panic:
   ```
   go// protocol/triple/triple_protocol/handler_compat.go
   for key, valRaw := range dubbo3Resp.Attachments() {
       switch valRaw := valRaw.(type) {
       case string:
           trailer[key] = []string{valRaw}
       case []string:
           trailer[key] = valRaw
       default:
           panic(fmt.Sprintf("unsupported attachment value type %T", valRaw))
       }
   }
   ```
   而优雅停机 provider filter(filter/graceful_shutdown)会在 invocation attachments 
里写入一个 bool 类型的内部计数标记:
   
   key:   dubbo-go-graceful-shutdown-provider-counted
   value: true (bool)
   
   该 attachment 会进入 result attachments,导致走 compat 路径的每一次 unary 调用都 panic。由于该 
filter 默认注册,老 triple compat 路径实际上完全不可用。
   
   注意:这个 panic 目前被另一个 bug 掩盖 —— 使用旧 config.Load() API 时 compat handler 
根本不会被注册(#3229 之后 URL 上缺少 ProviderConfigKey/RpcServiceKey,客户端报 unimplemented: 
HTTP status 404)。一旦修复注册问题,本 panic 立即暴露。可用 
dubbo-go-samples/rpc/triple/old_triple 复现。
   
   ### 修复方案
   
   服务端不应因为无法序列化某个 attachment 就崩溃。把 panic 改为告警并跳过:
   ```
   godefault:
       // Attachments 可能包含非 string 类型的内部记账值
       //(例如优雅停机 filter 写入的 bool 计数标记),
       // 无法作为 HTTP trailer 传输,跳过而不是 panic。
       logger.Warnf("triple compat: skip attachment %q with unsupported value 
type %T", key, valRaw)
   
   (同时移除不再使用的 "fmt" import。)
   ```
   可选的补充方案:
   
   
   写 trailer 前过滤掉内部 attachment key(如优雅停机计数标记),让内部标记不泄漏到响应中。
   让优雅停机 filter 在 OnResponse 里清理自己的记账 attachment,使其不会到达协议层。
   
   
   把 panic 改成 warn + skip 是最小安全改动,同时也能防御用户自己设置的非 string attachment;方案 1/2 
可在此基础上叠加。
   
   ### 复现步骤
   运行 dubbo-go-samples/rpc/triple/old_triple/go-server(旧 config.Load() 
API),需先应用 handler 注册修复,使服务真正被导出。
   运行对应 client,调用 Greet。
   Server 在 handler_compat.go:91 panic,client 收到 INTERNAL_ERROR 流重置。
   预期行为:调用成功;不可序列化的内部 attachment 不写入 trailer。


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to