zoukankan      html  css  js  c++  java
  • C10K problem

    什么是C10K问题
    1W个客户端连接上一个server,客户不定时的发送请求。

    I/O策略
    软件架构
    1.单线程解决多重I/O调用
        不要使用阻塞/同步的调用,如果非要这么做,那就采用多进程或者多线程来并发处理。
        使用非阻塞的调用和就绪通知策略,当下一个I/O可用时通知调用者。适用于套接字I/O,而不是磁盘I/O.
        使用异步的调用和通知策略,当下一个I/O可用时通知调用者,适用于磁盘I/O和套接字I/O。
    2.如何控制服务每个客户端的代码
        每一个client对应一个服务端进程,每一个进程保存client的一个状态机。
    I/O方案
    1.每个线程处理多个客户端请求,使用非阻塞I/O和水平触发通知策略(同步非阻塞轮询)
        水平触发通知策略
        当I/O触发可读写的时候,如果调用者没有及时处理,下一次检查I/O状态的时候仍然会通知调用者。
        垂直触发通知策略
        当I/O触发可读写的时候,如果调用者没有及时处理,下一次检查I/O状态的时候就不再通知调用者,和水平触发通知策略不同的是,只有在I/O状态由不可用变为可用的时候才会通知调用者。
        设置文件描述符为非阻塞,告诉epoll想要关注哪些事件,内核将会检测哪些fd可用并通知调用者,不管调用者做了什么,只要fd是可用的,就一直通知调用者。
        瓶颈:如果要读的页不在core中,那从磁盘中read和sendfile是一个重要的瓶颈。对内存映射文件和磁盘文件句柄设置非阻塞模式是没有什么意义的,当服务器第一次需要进行磁盘I/O时将会阻塞,所有的client请求都必须等待。
    2.每个线程处理多个客户端请求,使用非阻塞I/O和就绪改变通知
        就绪改变通知,你交给内核一个文件句柄,当文件描述符从不就绪改变成就绪时,内核会通知你。在文件描述符从就绪状态改变为非就绪状态之前不会再发送通知,也就是说,想要再次触发通知,除非你做了某些操作使文件描述符进入非就绪状态,比如在send、recv、accept收到了EWOULDBLOCK错误。
        当使用就绪改变通知的时候,必须准备好应对闲杂事件,因为一个通用的实现是当收到任何包的时候都会通知,而不是当文件描述符就绪的时候才通知。
        使用就绪改变通知会减少编程错误的容忍度,如果你漏处理了一个连接上的任意一个事件,连接上的所有消息都被阻塞。
    3.每个线程处理多个客户端请求,使用异步I/O
        目前还不是很流行,可能是比较少的操作系统支持异步I/O,也可能是使用异步I/O需要重构现有的代码。异步I/O把一个signal和value关联到每一个I/O操作上,signal和value被实时的入队和发送到用户进程。LINUX目前有aio的实现。
        使用异步I/O也无法避免打开磁盘文件的阻塞过程,一个好的建议是在另外的线程打开磁盘文件。
    4.每个server线程处理一个client
        缺点是每个线程要保持一定的线程堆栈开销,如果启动数百个线程,开销还是相当可观的。
    5.把server代码编译到内核中
    其他的一些手段
    zero-copy
        sendfile API实现了网络的zero-copy
    原文
  • 相关阅读:
    基于redis实现滑动窗口式的短信发送接口限流
    Linux 宝塔下的PHP如何与本地的nginx关联
    Linux 下php安装gd库
    Linux Mysql8重置密码
    PHP 无限分级类
    redis 缓存穿透,缓存雪崩,缓存击穿
    yii2 事务添加
    ConcurrentHashMap
    Volatile
    this引用的逸出
  • 原文地址:https://www.cnblogs.com/learn-my-life/p/5636368.html
Copyright © 2011-2022 走看看