为什么讨厌java

开发难度低,无需智商测试

copy&paste

会传染烂设计

设计模式大补丸

重构 大杀器

工业化大生产

发布于 | Tags java lang

cap

CAP 三选二公式误导性

理解 CAP

处理策略

CAP 和延迟的联系

发布于 | Tags concurrent

异步、并发、协程原理

进程、线程、协程的特点及区别

支持协程的语言

适合使用协程的场景

协程与异步和并发的联系

发布于 | Tags io

惊群

多个进程/线程同时阻塞等同一个事件时,事件发生后,唤醒所有的进程

但最终只可能有一个进程/线程对该事件进行处理,其他在失败后重新休眠,这种性能浪费就是惊群

accept 惊群

主进程创建socket, bind, listen后,fork出多个子进程都循环处理(accept)这个socket

每个进程都阻塞在accpet上,当一个新的连接到来时,所有的进程都会被唤醒,但其中只有一个进程会accept成功,其余皆失败,重新休眠。这就是accept惊群

fork出多个进程是为了利用多核CPU

内核早解决这问题了

多个进程/线程都阻塞在对同一个 socket 的 accept 调用上时,新连接到来,内核只唤醒一个进程,其他进程保持休眠,压根就不会被唤醒

epoll惊群

accept 已无惊群问题,但 epoll 还有

即,如果多个进程/线程阻塞在监听同一个 listening socket fd 的 epoll_wait 上,当有一个新的连接到来时,多个子进程被唤醒

为什么内核不处理 epoll 惊群

accept 应该只能被一个进程调用成功,内核很清楚这一点

但 epoll 监听的fd,除可能被 accept 调用外,还有可能是其他网络 IO 事件的

其他 IO 事件是否只能由一个进程处理(如一个文件会由多个进程来读写),得用户决定,内核不能强制

所以,对 epoll 的惊群,内核则不予处理

发布于 | Tags io

Actor VS Thread VS Coroutine

大规模并发服务的技术,归纳起来就是两种方式:

  • thread per client,用blocking I/O

  • 多个clients一个thread,用nonblocking I/O或asynchronous I/O

Linux asynchronous I/O还不好,一般都是用nonblocking I/O

多数都是用epoll()的edge triggering(select()性能问题)

发布于 | Tags concurrent

aio

宏观与微观角度看epoll+nonblock

宏观角度可以叫做全异步

微观角度还是同步 IO(数据到达后得到系统通知,然后同步执行 recv 取回数据,没有 iowait)

真正的异步 IO(AIO)应像 Windows IOCP 一样,传入文件句柄,缓存区,尺寸等参数和一个函数指针,当os真正完成了 IO 操作,再执行对应的函数

  1. 实际上 socket ,epoll 已经是最高效的模型了,虽然比 AIO 多一次 recv 系统调用,但总体来看没有任何 IO 等待,效率很高

  2. epoll 天然 reactor 模型,程序实现更容易。AIO 如 windows 的 IOCP,异步回调的方式,开发难度很高

为什么还是需要 AIO

文件句柄跟 socket 完全不同,它总是处于可读状态,不能 epoll+nonblock 实现异步化

在 epoll 的全异步 Server 中,读写文件必须得用 AIO

发布于 | Tags io