cap
发布于
concurrent

CAP 三选二公式误导性

理解 CAP

处理策略

CAP 和延迟的联系

异步、并发、协程原理
发布于
io

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

支持协程的语言

适合使用协程的场景

协程与异步和并发的联系

惊群
发布于
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 的惊群,内核则不予处理

Actor VS Thread VS Coroutine
发布于
concurrent

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

  • 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()性能问题)

aio
发布于
io

宏观与微观角度看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

python aop
发布于
python aop

动态语言提供了在运行时改变程序结构的能力,有时候会提供巨大的方便

函数调用拦截是aop的基础

class Target:
    def targetFunc(self):
        print ("targetFunction")

temp=Target.targetFunc

def foo(self):
    print ("before call")
    temp(self)
    print ("after call")

Target.targetFunc=foo

t=Target()
t.targetFunc()

对调用者来说根本就不知道函数已经给动了手脚

用Java, C++来实现就麻烦些了

tcp_tw_reuse、tcp_tw_recycle
发布于
network

tcp 使用场景,一般区分为“长连接”和“短连接”

如何解决tcp短连接的TIME_WAIT问题

短连接最大缺点:占用资源(如:本地端口、socket句柄)


正常的TCP client关闭后,进入TIME_WAIT,持续的时间一般在1~4分钟

每秒建1000个短连接(Web请求访问memcached)

假TIME_WAIT时间是1分钟,1分钟内需要建立6W个短连接,这些短连接1分钟内都处于TIME_WAIT状态,都不会释放

Linux默认本地端口范围:net.ipv4.ip_local_port_range = 32768 61000

不到3W,由于没有本地端口就不能建立了