Open yuexiaocai opened 1 month ago
作为参考:
redis中的backlog
默认值是511:https://github.com/redis/redis/blob/unstable/redis.conf#L148
PostgreSQL中通过 postgresql.conf
配置文件中的 max_connections
参数间接影响 backlog
,默认值是100:https://github.com/postgres/postgres/blob/master/src/backend/utils/misc/postgresql.conf.sample#L65
puma中的backlog
默认值是1024:https://github.com/puma/puma/issues/1449
另外,是否可以在retry时使用指数退避的策略,而不是无间隔地进行retry?
由于 d.DialContext()
直接返回了错误,所以Dialer
的Timeout参数(10秒)其实是不生效的,所有的retry会再次并发执行,导致最终全部失败。
再次补充:dpvs数据面用的是accept,所以无法同时和多个client通信,不知此处为什么要模仿go-pg的连接池。是否考虑把数据面改成epoll呢?
dpvs-agent底层通信的连接池设计上有缺陷,现在只是通过简单重试缓解该问题,后面我们会详细看看,非常感谢提供的问题线索和解决思路。
问题描述
在使用dpvs-agent批量下发配置(例如并发设置几十条转发路由,并发量并不大)时经常出现
Get conn from pool failed: Error="dial unix /var/run/dpvs.ipc: connect: resource temporarily unavailable"
的报错。dpvs-agent的解决方法(未奏效)
注意到dpvs-agent的代码中也有提到相关问题,解决方法是进行10次重试(但在我的测试中并未奏效,重试10次后仍有很多路由下发失败):
疑点
连接池参数
此时我尝试输出中有多少连接可以复用,结果调试发现代码中的ConnPool似乎并未起到作用:我在
route.go
执行conn, err := cp.Get(ctx)
之后打印了cp.Stats()
,发现在每次查找连接时都是Miss
,从未Hit
连接,TotalConns
的数量也是0。我发现dpvs-agent代码中,初始化时未设置
MinIdleConns
字段,因而缺省为0,进而连接池中并无idle连接可以复用,每次与数据面交互似乎都需要重新创建连接。然而设置了
MinIdleConns
字段后,所有访问dpvs-agent的curl
请求都block住了,无法正常运行。socket监听参数
同时,数据面的
ctrl.c
中 Server socket 监听的backlog
设置成了1
,这样的做法似乎并不常见:当我把
backlog
调大后,connect: resource temporarily unavailable
的问题解决了,所有路由都可以批量下发成功。问题
想请教一下 DPVS 的开发者们:
listen(srv_fd, 1)
的backlog
设置为1
有什么其他方面的特殊考虑吗?这会不会是导致下发配置并发问题的根因?