@@ -44,18 +44,18 @@ func isGRPCTransportError(err error) bool {
4444func ServeRPC (port uint ) {
4545 // 配置 gRPC 服务器选项,防止 goroutine 泄漏和连接问题
4646 opts := []grpc.ServerOption {
47- // 优化 keepalive 参数,减少broken pipe错误
47+ // 优化 keepalive 参数:使用长连接策略,减少重连
4848 grpc .KeepaliveParams (keepalive.ServerParameters {
49- MaxConnectionIdle : 3 * time .Minute , // 减少到3分钟,更快检测断开连接
50- MaxConnectionAge : 15 * time .Minute , // 增加到15分钟,减少频繁重连
51- MaxConnectionAgeGrace : 60 * time .Second , // 增加优雅关闭时间到60秒
52- Time : 20 * time .Second , // 减少到20秒,更频繁的心跳检测
53- Timeout : 10 * time .Second , // 增加超时到10秒,避免网络抖动
49+ MaxConnectionIdle : 30 * time .Minute , // 空闲30分钟后断开(防止僵尸连接)
50+ MaxConnectionAge : 2 * time .Hour , // 连接最长2小时(定期刷新,防止资源泄漏)
51+ MaxConnectionAgeGrace : 30 * time .Second , // 优雅关闭时间30秒
52+ Time : 30 * time .Second , // 每30秒发送心跳
53+ Timeout : 10 * time .Second , // 心跳超时10秒
5454 }),
5555 // 优化 keepalive 强制策略
5656 grpc .KeepaliveEnforcementPolicy (keepalive.EnforcementPolicy {
57- MinTime : 5 * time .Second , // 减少到5秒,允许更频繁的keepalive
58- PermitWithoutStream : true , // 允许没有活跃流时发送keepalive
57+ MinTime : 10 * time .Second , // 最小心跳间隔10秒
58+ PermitWithoutStream : true , // 允许没有活跃流时发送keepalive
5959 }),
6060 // 设置最大接收消息大小
6161 grpc .MaxRecvMsgSize (4 * 1024 * 1024 ), // 4MB
@@ -129,8 +129,19 @@ func DispatchTask(serviceSentinelDispatchBus <-chan model.Monitor) {
129129 workedServerIndex ++
130130 continue
131131 }
132+
133+ // 安全发送任务的辅助函数,防止竞态条件下的nil pointer dereference
134+ sendTask := func () error {
135+ // 再次检查TaskStream是否为nil(防止竞态条件)
136+ stream := currentServer .TaskStream
137+ if stream == nil {
138+ return nil // 连接已断开,静默跳过
139+ }
140+ return stream .Send (task .PB ())
141+ }
142+
132143 if task .Cover == model .MonitorCoverIgnoreAll && skipServers [currentServer .ID ] {
133- if err := currentServer . TaskStream . Send ( task . PB () ); err != nil {
144+ if err := sendTask ( ); err != nil {
134145 // 清理失效的连接
135146 currentServer .TaskStream = nil
136147 // 只在非正常网络错误时记录日志
@@ -142,7 +153,7 @@ func DispatchTask(serviceSentinelDispatchBus <-chan model.Monitor) {
142153 continue
143154 }
144155 if task .Cover == model .MonitorCoverAll && ! skipServers [currentServer .ID ] {
145- if err := currentServer . TaskStream . Send ( task . PB () ); err != nil {
156+ if err := sendTask ( ); err != nil {
146157 // 清理失效的连接
147158 currentServer .TaskStream = nil
148159 // 只在非正常网络错误时记录日志
@@ -154,7 +165,7 @@ func DispatchTask(serviceSentinelDispatchBus <-chan model.Monitor) {
154165 continue
155166 }
156167 // 找到合适机器执行任务,跳出循环
157- if err := currentServer . TaskStream . Send ( task . PB () ); err != nil {
168+ if err := sendTask ( ); err != nil {
158169 // 清理失效的连接
159170 currentServer .TaskStream = nil
160171 // 只在非正常网络错误时记录日志
@@ -174,11 +185,16 @@ func DispatchKeepalive() {
174185 singleton .SortedServerLock .RLock ()
175186 defer singleton .SortedServerLock .RUnlock ()
176187 for i := 0 ; i < len (singleton .SortedServerList ); i ++ {
177- if singleton .SortedServerList [i ] == nil || singleton .SortedServerList [i ].TaskStream == nil {
188+ server := singleton .SortedServerList [i ]
189+ if server == nil {
178190 continue
179191 }
180-
181- singleton .SortedServerList [i ].TaskStream .Send (& pb.Task {Type : model .TaskTypeKeepalive })
192+ // 防止竞态条件下的nil pointer dereference
193+ stream := server .TaskStream
194+ if stream == nil {
195+ continue
196+ }
197+ stream .Send (& pb.Task {Type : model .TaskTypeKeepalive })
182198 }
183199 })
184200}
0 commit comments