New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于skynet网络收发问题 #646

Closed
linxiaolong opened this Issue Jun 2, 2017 · 26 comments

Comments

Projects
None yet
3 participants
@linxiaolong

在网络收发量较大的时候(MMO大量场景广播消息),skynet socket线程那里表面看起来反应缓慢,accept和正常网络收发的反应都有较大延迟,下面描述下:

服务器负荷:
us 用户态占比 sy 系统态占比 id 空闲态占比 hi 硬中断 si 软中断 wa 等待IO
16核16G,每核心大致都是 (5-25us) + (5-30sy),且每核基本都能保持50id,偶尔会有一两个核有5-15si,没发现hi和wa
服务器出入口带宽使用:
出:30Mb/s 入:20Mb/s
内存使用:
较为平稳,关闭了swap

在出现卡点的时候,在socket线程epoll抛ACCEPT事件那里打log,发现在服务器本地nc上去,大概等了5秒才有反应并成功出log,如果是nc其他进程的端口则正常,证明有某些原因导致skynet epoll对事件的侦测出现了延缓,暂不确定是内核提交事件的延缓(系统抑或进程的部分缓冲区的限制?),还是skynet网络收发线程过于繁忙。但如上所述,如果是skynet线程问题,不应该出现16个核心有稳定的空闲态,这里比较费解。

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 2, 2017

Owner

可以 log 一下 epoll_wait 调用的节奏,看看是否是网络线程的其它部分占用时间过长(比如 read/write 的调用占用了过多时间)。

另外,有个 MAX_EVENT 默认是 64 ,指每次 wait 获取的消息最多数量,超过则需要等待下次的查询,适当调大看看是否有差别。

如果排除 bug 因素,是由于大量写操作导致的读操作延迟(从 MMO大量场景广播消息 推断),我可以考虑把写操作移到单独的线程去完成。

Owner

cloudwu commented Jun 2, 2017

可以 log 一下 epoll_wait 调用的节奏,看看是否是网络线程的其它部分占用时间过长(比如 read/write 的调用占用了过多时间)。

另外,有个 MAX_EVENT 默认是 64 ,指每次 wait 获取的消息最多数量,超过则需要等待下次的查询,适当调大看看是否有差别。

如果排除 bug 因素,是由于大量写操作导致的读操作延迟(从 MMO大量场景广播消息 推断),我可以考虑把写操作移到单独的线程去完成。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Jun 2, 2017

1、LOG那个我待会调试一下
2、这个早前我调成65536作用不大
3、这里我之前也怀疑是写卡住,但从系统负荷来看,16个核心基本都是稳定超过50%的空闲态,包括read和write这类如果耗时较多,至少体现在sy很高才对,但并没有,十分费解

1、LOG那个我待会调试一下
2、这个早前我调成65536作用不大
3、这里我之前也怀疑是写卡住,但从系统负荷来看,16个核心基本都是稳定超过50%的空闲态,包括read和write这类如果耗时较多,至少体现在sy很高才对,但并没有,十分费解

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 2, 2017

Owner

建议把 epoll wait 每次调用的发起和结束时刻以及返回 event 输出到一个专门的 log 文件中,这样方便分析问题。

Owner

cloudwu commented Jun 2, 2017

建议把 epoll wait 每次调用的发起和结束时刻以及返回 event 输出到一个专门的 log 文件中,这样方便分析问题。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Jun 2, 2017

好,晚点也试试独立输出log来分析。刚gdb socket线程看来,在没发生卡点bt基本在epoll_wait,如果感觉到卡点bt基本是在send_socket,也算可以佐证socket线程应该是繁忙,虽然对cpu的空闲还是有些怀疑,准备先做下流量优化。另外,关于skynet网络收发这里,有部分看法不知道skynet近期是否会考虑:

  1. 底层可否由使用者定制多少个socketserver,底层按socketid取模决定由哪个来管理,这样除了分配id涉及并发,其他应该跟目前的简洁设计相符合,也有利于使用者根据情况来定制数目来并发。当然先把写独立出来应该也可以极大分压,不过还是会遇到瓶颈,且设计上也会引入锁,有点破坏现在的结构
    2.现在上层发控制和send都走pipe,pipe按目前内核倒是可以设置大小,不过这里skynet按自己需求弄个无锁队列是否会更好,就算是采用定长循环,大小可以由使用者定制应该也会更友好

好,晚点也试试独立输出log来分析。刚gdb socket线程看来,在没发生卡点bt基本在epoll_wait,如果感觉到卡点bt基本是在send_socket,也算可以佐证socket线程应该是繁忙,虽然对cpu的空闲还是有些怀疑,准备先做下流量优化。另外,关于skynet网络收发这里,有部分看法不知道skynet近期是否会考虑:

  1. 底层可否由使用者定制多少个socketserver,底层按socketid取模决定由哪个来管理,这样除了分配id涉及并发,其他应该跟目前的简洁设计相符合,也有利于使用者根据情况来定制数目来并发。当然先把写独立出来应该也可以极大分压,不过还是会遇到瓶颈,且设计上也会引入锁,有点破坏现在的结构
    2.现在上层发控制和send都走pipe,pipe按目前内核倒是可以设置大小,不过这里skynet按自己需求弄个无锁队列是否会更好,就算是采用定长循环,大小可以由使用者定制应该也会更友好
@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 3, 2017

Owner
  1. epoll 不太适合在多线程环境使用,需要考虑的东西比较多,不是调用 epoll 的结构问题,是 epoll 本身的问题;可以考虑分拆到多个进程。
  2. pipe 的作用是为了唤醒 epoll 。

要解决 write 的阻塞问题是可以考虑将 write 移到独立线程的,但是还没有想好怎么改。

Owner

cloudwu commented Jun 3, 2017

  1. epoll 不太适合在多线程环境使用,需要考虑的东西比较多,不是调用 epoll 的结构问题,是 epoll 本身的问题;可以考虑分拆到多个进程。
  2. pipe 的作用是为了唤醒 epoll 。

要解决 write 的阻塞问题是可以考虑将 write 移到独立线程的,但是还没有想好怎么改。

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 3, 2017

Owner

我倾向于认为这个是某种 bug 引起的,因为 I/O 吞吐能力是有限的。你也列出了 30Mb/s 的下行带宽,也就是说,socket 线程的 write 一秒只会处理 30Mb 的数据,从用户态向内核 copy 30Mb 数据是占用不了多少 cpu 的;当内核的 buf 满后,就不会触发 epoll 的可写事件,所以 epoll 事件被堵塞 5s 以上是及其不正常的。

如果要出现这种情况,我认为比较大的疑点是 write 到了一个阻塞模式的 fd 上,导致 socket 线程被挂起。具体可以多加一些 log 记录时间来查。目前 sp_nonblocking 并没有返回值,可以查一下这里是否有调用失败。

Owner

cloudwu commented Jun 3, 2017

我倾向于认为这个是某种 bug 引起的,因为 I/O 吞吐能力是有限的。你也列出了 30Mb/s 的下行带宽,也就是说,socket 线程的 write 一秒只会处理 30Mb 的数据,从用户态向内核 copy 30Mb 数据是占用不了多少 cpu 的;当内核的 buf 满后,就不会触发 epoll 的可写事件,所以 epoll 事件被堵塞 5s 以上是及其不正常的。

如果要出现这种情况,我认为比较大的疑点是 write 到了一个阻塞模式的 fd 上,导致 socket 线程被挂起。具体可以多加一些 log 记录时间来查。目前 sp_nonblocking 并没有返回值,可以查一下这里是否有调用失败。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Jun 7, 2017

从调试来看:
1)从gdb和打log来看应该是没有异常的socket
2)sp_nonblocking问题,已经确定了是设置成功了,为了确保又同时加了ioctrl设置,效果没差别
3)从strace和gdb来分析,应该是目前skynet网络底层在写多的情况下,容易一直处理ctrl_cmd(因为写首先会经过pipe),且很容易在ctrl_cmd这里就已经发生直接write(在socket队列为空情况下),也即对于poll循环来说,处理写的优先级远高于读

假设没BUG的情况下,基于3)的分析,我目前修改了skynet底层源码:
1)将send_socket里面的处理,不管socket写队列是否为空,都直接挂在写队列,永远不会在这里进行write
2)将MAX_EVENT调整为1024

1)的影响巨大,修改后,网络收发的平衡性得以调整,假设之前是在X人的时候遇到卡点,目前到了X*2人才遇到卡点,从体验而言可以说是两倍的跃升。2)有略微的影响

对于这种情况,云风看下是否需要调整,或者说有哪些影响是我没考虑到的

从调试来看:
1)从gdb和打log来看应该是没有异常的socket
2)sp_nonblocking问题,已经确定了是设置成功了,为了确保又同时加了ioctrl设置,效果没差别
3)从strace和gdb来分析,应该是目前skynet网络底层在写多的情况下,容易一直处理ctrl_cmd(因为写首先会经过pipe),且很容易在ctrl_cmd这里就已经发生直接write(在socket队列为空情况下),也即对于poll循环来说,处理写的优先级远高于读

假设没BUG的情况下,基于3)的分析,我目前修改了skynet底层源码:
1)将send_socket里面的处理,不管socket写队列是否为空,都直接挂在写队列,永远不会在这里进行write
2)将MAX_EVENT调整为1024

1)的影响巨大,修改后,网络收发的平衡性得以调整,假设之前是在X人的时候遇到卡点,目前到了X*2人才遇到卡点,从体验而言可以说是两倍的跃升。2)有略微的影响

对于这种情况,云风看下是否需要调整,或者说有哪些影响是我没考虑到的

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 8, 2017

Owner

send_socket 里尝试直接发送是一个优化,目的是在 socket 未阻塞(内部 buffer 够)前,可以省略向 epoll 监听可写事件的过程。

如果想让 ctrl_cmd 处理频率没那么高,我想更简单的改法是去掉
https://github.com/cloudwu/skynet/blob/master/skynet-src/socket_server.c#L1235 这里的 continue ,让每处理一次 ctrl_cmd 就有机会处理一次其它网络事件。

但我觉得 accept 被延迟数秒的问题还是没有得到合理的解释:write 操作多到了一直占据 socket 线程让其它事件一直无法处理?如果的确是这样,调整 read 和 write 的优先级,似乎并没有缓解网络延迟的问题,区别只在于读延迟和写延迟的多少。网络游戏是一个交互过程,不考虑压力测试的情况的话,服务器和客户端的交互过程中,无论哪个方向的延迟增加,对流程的影响似乎没有什么区别。

这里 accept 是一个读操作,是否是 accept 读的这个 fd 优先级被下降的问题?

Owner

cloudwu commented Jun 8, 2017

send_socket 里尝试直接发送是一个优化,目的是在 socket 未阻塞(内部 buffer 够)前,可以省略向 epoll 监听可写事件的过程。

如果想让 ctrl_cmd 处理频率没那么高,我想更简单的改法是去掉
https://github.com/cloudwu/skynet/blob/master/skynet-src/socket_server.c#L1235 这里的 continue ,让每处理一次 ctrl_cmd 就有机会处理一次其它网络事件。

但我觉得 accept 被延迟数秒的问题还是没有得到合理的解释:write 操作多到了一直占据 socket 线程让其它事件一直无法处理?如果的确是这样,调整 read 和 write 的优先级,似乎并没有缓解网络延迟的问题,区别只在于读延迟和写延迟的多少。网络游戏是一个交互过程,不考虑压力测试的情况的话,服务器和客户端的交互过程中,无论哪个方向的延迟增加,对流程的影响似乎没有什么区别。

这里 accept 是一个读操作,是否是 accept 读的这个 fd 优先级被下降的问题?

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 8, 2017

Owner

在 epoll_wait 加一下带时间戳的 log 可以确定是否的确是因为循环执行 ctrl_cmd 剥夺了 epoll_wait 的时间。

另外可以试试调整发送缓冲区的大小(调大或调小),看看是否有影响。

我可以开个分支试试把读写分开。

Owner

cloudwu commented Jun 8, 2017

在 epoll_wait 加一下带时间戳的 log 可以确定是否的确是因为循环执行 ctrl_cmd 剥夺了 epoll_wait 的时间。

另外可以试试调整发送缓冲区的大小(调大或调小),看看是否有影响。

我可以开个分支试试把读写分开。

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 8, 2017

Owner

是否可以在 send_socket 那里记录一下试图发送的真实流量。

即,在 send_socket 处记录当时的时刻和待发送的数据量:取时间可以用 skynet_now() ,因为这里不需要精度特别高,skynet_now 可以减少系统调用。建议可以设置一个记录点时刻,如果某次 send_socket 的时刻和前一次记录点的时刻差超过 1 秒(如果是 skynet_now 就是相差 100 ),把这段时间累加的字节数除以时间差换算出每秒的字节数,写在 log 里。一秒一条 log 的频率应当是可以接受的。

用这个和系统测算得到的下行带宽比较,看是否存在过载。

Owner

cloudwu commented Jun 8, 2017

是否可以在 send_socket 那里记录一下试图发送的真实流量。

即,在 send_socket 处记录当时的时刻和待发送的数据量:取时间可以用 skynet_now() ,因为这里不需要精度特别高,skynet_now 可以减少系统调用。建议可以设置一个记录点时刻,如果某次 send_socket 的时刻和前一次记录点的时刻差超过 1 秒(如果是 skynet_now 就是相差 100 ),把这段时间累加的字节数除以时间差换算出每秒的字节数,写在 log 里。一秒一条 log 的频率应当是可以接受的。

用这个和系统测算得到的下行带宽比较,看是否存在过载。

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 8, 2017

Owner

@linxiaolong 我今天尝试实现了多线程写, 9618dd4

目前在 directwrite 这个特性分支上。你可以帮忙 review 并测试一下是否可以达到你的需求。

这个 patch 会尝试在调用 socket_server_send 或 socket_server_udp_send 时,先检查一下能不能直接发送,如果可以,就直接发送走,而不需再投递到 socket thread 。

如果这步 api 调用失败,会开启写事件监听,并把待发 buffer 放在 struct socket 结构里。当 socket thread 的写事件触发发送 buffer 时,会先检查有没有 direct write 发送失败的 buffer ,若有,会将其加在链表头部。

Owner

cloudwu commented Jun 8, 2017

@linxiaolong 我今天尝试实现了多线程写, 9618dd4

目前在 directwrite 这个特性分支上。你可以帮忙 review 并测试一下是否可以达到你的需求。

这个 patch 会尝试在调用 socket_server_send 或 socket_server_udp_send 时,先检查一下能不能直接发送,如果可以,就直接发送走,而不需再投递到 socket thread 。

如果这步 api 调用失败,会开启写事件监听,并把待发 buffer 放在 struct socket 结构里。当 socket thread 的写事件触发发送 buffer 时,会先检查有没有 direct write 发送失败的 buffer ,若有,会将其加在链表头部。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Jun 9, 2017

好,近期我试试以上的建议,也合并特性分支测试对比一下

好,近期我试试以上的建议,也合并特性分支测试对比一下

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 19, 2017

Owner

cc138ad 今天修了两个 bug ,一是直接发送可以发送 udp ,需要处理一下;二是解锁的位置有点问题。

Owner

cloudwu commented Jun 19, 2017

cc138ad 今天修了两个 bug ,一是直接发送可以发送 udp ,需要处理一下;二是解锁的位置有点问题。

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 21, 2017

Owner

@linxiaolong 不知道有没有新信息。

今天又做了一些优化调整,把 socket thread 里的 lock 改成了 trylock ,可以在某些特殊情况下,减少不必要的等待。

Owner

cloudwu commented Jun 21, 2017

@linxiaolong 不知道有没有新信息。

今天又做了一些优化调整,把 socket thread 里的 lock 改成了 trylock ,可以在某些特殊情况下,减少不必要的等待。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Jun 24, 2017

因为之前修改达到预期,没把读写分离特性部署到大并发环境。review和本地测试暂未发现问题,下周会把该分支部署测试,具体比较形成数据后再反馈

因为之前修改达到预期,没把读写分离特性部署到大并发环境。review和本地测试暂未发现问题,下周会把该分支部署测试,具体比较形成数据后再反馈

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Jun 27, 2017

合并读写分离特性之后的情况:

具体对比:
1.0版本完全不改:30Mb/s,人数大概X人会卡顿(收发不平衡)
1.0版本小改(ctrl_cmd的send_socket改为永不直接write,都是挂buffer):50mb/s,人数大概2X人会卡顿
1.0版本合并读写分离特性:80Mb/s,人数大概3.5X人会卡顿

从目前看来的话,该修改还是很有意义,排除bug可能性来说,希望该特性也纳入2.0版本考虑

问题反馈:
1、死锁。譬如:
send_buffer_函数:
//此处分支必然发生死锁,因为force_close内也会上锁
666 if (s->type == SOCKET_TYPE_HALFCLOSE) {
667 force_close(ss, s, result);
668 return SOCKET_CLOSE;
669 }

2、sp_write问题:
1446 s->dw_buffer = buffer;
1447 s->dw_size = sz;
1448 s->dw_offset = n;
1449 spinlock_unlock(&s->dw_lock);
1450
//没在锁范围,可能发生socket被关,然后sp_write把fd打进event_fd,造成永久不清
1451 sp_write(ss->event_fd, s->fd, s, true);

关于多线程并发这里,上面列了下已经发现的情况,其他的暂时review也没发现,云风看下有什么比较好的方式规避这种风险,目前的自旋锁不支持嵌套,这估计会是一个不小的隐患

合并读写分离特性之后的情况:

具体对比:
1.0版本完全不改:30Mb/s,人数大概X人会卡顿(收发不平衡)
1.0版本小改(ctrl_cmd的send_socket改为永不直接write,都是挂buffer):50mb/s,人数大概2X人会卡顿
1.0版本合并读写分离特性:80Mb/s,人数大概3.5X人会卡顿

从目前看来的话,该修改还是很有意义,排除bug可能性来说,希望该特性也纳入2.0版本考虑

问题反馈:
1、死锁。譬如:
send_buffer_函数:
//此处分支必然发生死锁,因为force_close内也会上锁
666 if (s->type == SOCKET_TYPE_HALFCLOSE) {
667 force_close(ss, s, result);
668 return SOCKET_CLOSE;
669 }

2、sp_write问题:
1446 s->dw_buffer = buffer;
1447 s->dw_size = sz;
1448 s->dw_offset = n;
1449 spinlock_unlock(&s->dw_lock);
1450
//没在锁范围,可能发生socket被关,然后sp_write把fd打进event_fd,造成永久不清
1451 sp_write(ss->event_fd, s->fd, s, true);

关于多线程并发这里,上面列了下已经发现的情况,其他的暂时review也没发现,云风看下有什么比较好的方式规避这种风险,目前的自旋锁不支持嵌套,这估计会是一个不小的隐患

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 27, 2017

Owner

谢谢,1 我等下改一下;2 原来是对的,后来改错了 aa42534 ,我改回来。

加锁了肯定会有麻烦,目前只能靠 review 了。

Owner

cloudwu commented Jun 27, 2017

谢谢,1 我等下改一下;2 原来是对的,后来改错了 aa42534 ,我改回来。

加锁了肯定会有麻烦,目前只能靠 review 了。

cloudwu added a commit that referenced this issue Jun 27, 2017

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 27, 2017

Owner

调用 force_close 死锁的位置不仅仅在 667,send_list_tcp 里也有。我加了个 nested spinlock 解决这个问题,帮忙看一下。

Owner

cloudwu commented Jun 27, 2017

调用 force_close 死锁的位置不仅仅在 667,send_list_tcp 里也有。我加了个 nested spinlock 解决这个问题,帮忙看一下。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Jun 27, 2017

netsted spinlock那里,目前所有的worker thread传入的thread都是同一个,这样需要上层保证对于同一个socket id的操作不能有并发service的可能性。我们目前确实保证了同一个socket id只由对应的gate去处理,但底层这里还是采取传入thread id会合理一些?

netsted spinlock那里,目前所有的worker thread传入的thread都是同一个,这样需要上层保证对于同一个socket id的操作不能有并发service的可能性。我们目前确实保证了同一个socket id只由对应的gate去处理,但底层这里还是采取传入thread id会合理一些?

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 27, 2017

Owner

是的,这里还有问题。我再想想怎么改。

Owner

cloudwu commented Jun 27, 2017

是的,这里还有问题。我再想想怎么改。

cloudwu added a commit that referenced this issue Jun 27, 2017

cloudwu added a commit that referenced this issue Jun 27, 2017

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 27, 2017

Owner

先把那个 nested lock 回退了,不确定 api 设计的好不好。如果增加 thread id 又搞复杂了。

所以换了种方法解决这里的现实问题,在 socket_server.c 内部增加了一个 socket_lock 的结构来处理锁嵌套问题。见上面最后一个相关提交。虽然实现麻烦一点,但是不依赖系统 api (比如获取 thread id, 使用 tls 变量等) 。

Owner

cloudwu commented Jun 27, 2017

先把那个 nested lock 回退了,不确定 api 设计的好不好。如果增加 thread id 又搞复杂了。

所以换了种方法解决这里的现实问题,在 socket_server.c 内部增加了一个 socket_lock 的结构来处理锁嵌套问题。见上面最后一个相关提交。虽然实现麻烦一点,但是不依赖系统 api (比如获取 thread id, 使用 tls 变量等) 。

@chenzuo

This comment has been minimized.

Show comment
Hide comment
@chenzuo

chenzuo Jun 28, 2017

chenzuo commented Jun 28, 2017

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jun 28, 2017

Owner

skynet 采用的 MIT 许可,只有这一个版本,没有其它分支。

skynet 本身有免费的网上社区支持。如果觉得有必要,也可以提供正式的付费技术支持,可以单独和我联系。

Owner

cloudwu commented Jun 28, 2017

skynet 采用的 MIT 许可,只有这一个版本,没有其它分支。

skynet 本身有免费的网上社区支持。如果觉得有必要,也可以提供正式的付费技术支持,可以单独和我联系。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Jun 28, 2017

把最新修改合并review暂无发现其他问题,也发布到大并发环境测试ing,会让其持续运行几天,暂无发现其他问题。表现上和之前贴的对比差不多。

把最新修改合并review暂无发现其他问题,也发布到大并发环境测试ing,会让其持续运行几天,暂无发现其他问题。表现上和之前贴的对比差不多。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Jul 1, 2017

已经在大并发环境跑了3天,暂时没发现其他问题

已经在大并发环境跑了3天,暂时没发现其他问题

@linxiaolong linxiaolong closed this Jul 1, 2017

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Jul 1, 2017

Owner

我会在最近发布 1.1 版本时把这个分支合并到主干。

Owner

cloudwu commented Jul 1, 2017

我会在最近发布 1.1 版本时把这个分支合并到主干。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment