L4-7 网络代理平台的思考
目前部门网络组件bug 较多不稳定,准备自己改一改,所以现在想一想应该怎么处理!!
目前部门业务主要就是:
1、网络I/O----->读取文件,频繁读取网络套接字。
2、CPU在内存中的计算
so:瓶颈应该是在网络I/O中,毕竟不是CPU密集型,所有的数据都在内存中处理
多线程??多进程
多线程:要防止频繁的CPU切换,上下文的切换又涉及程序计数器、堆栈指针和程序状态字等一系列的寄存器置换、程序堆栈重置甚至是 CPU 高速缓存、TLB 的切换 所以多线程绑定到具体CPU 比较好
多进程:相比多线程,进程间通讯耗CPU,所以进程间 地址空间分离是有坏处但是也有好处!!好处就是稳定 进程间干扰少,不像单进程多线程一样,一个线程coredump 导致了进程退出;
当然多机分布式的时候,进程比线程好,还有一点 线程相比进程 切换调度 创建销毁都要快,CPU 利用率高、占用内存要少
所以如果遇到CPU密集型->计算量大-->cpu切换多,很可能需要多线程!!但是多线程调试有点坑。
考虑到一个http代理缓存的功能-----> CPU 瓶颈应该在网络io 不应该在计算,毕竟计算不多,也不会像web服务器,需要大量创建销毁process来处理,所以从这样看多进程比较好,
同时网络设备要求稳定,多线程一个线程挂掉了可能会导致整个进程退出!! 有可能涉及到http报文的pkt收发 pkt处理,两者相关性强,但是这两个都在一个进程中处理就行,所以单进程可以解决问题,不一定非要多线程;
而且http处理在业务上可以看做是水平扩展,适合多进程;一般多线程适合业务垂直扩展吧!!而且多进程开发效率比较高!!0
结论也就是:多进程
网络I/O
说到I/O就肯定涉及到epoll/poll/select 对于其分析请参考之前文章:epoll分析以及 epoll/select效率 等;
根据业务量:准备选择epoll了;
那么问题来了?
reactor模型 ?水平边沿触发的选择?
选择了多进程所以准备多reactor了!!
那么epoll是水平还是边沿??
业务主要是:http代理分析报文转发,一般都是网关,流量比较大;ET模式相比LT 被唤醒的次数要少,ET编程难度要高,
如果流量一直来,那是不是有可能ET一直都在rcv数据,导致其余的fd饿死等情况??这种情况只能在编程时慎重处理了!!!
所以EPOLL-ET了
PS:线程有共享数据,也就是内存中有全局数据, 如果没有还是用master+n-work-fork模型比较好!!
共享数据时可以修改的,不是静态常量,如果数据不能修改,只读--那么可以使用进程间的共享内存,那么多进程master+n-work-fork 比较好
记住利用异步操作,比如logging 无论是写磁盘还是send to logserver 都不应该被阻塞;
如果使用多线程:多线程应该有效的划分责任与功能!让每个线程功能单一,每个线程只处理事务的一个状态!不同类别的事务放在不同thread 里面处理
多线程 共享memory 线程切换时,其cpu的cache 可能miss 少一些!!
多线程一般分为:
- IO线程 使用epoll recv send数据 同时处理timer ;可以掺杂消息编码解码!
- 计算线程: 线程的主循环是queue 阻塞等待临界区!! 轮询一个队列可用的事务
- 第三方库的线程!!!
线程的标识:
- pthread_self 返回当前线程的标识!
线程销毁:
自然死亡:主函数退出
非正常退出: core触发
self kill: 自己调用pthread_exit 退出
killed:pthread_cancel 强制终止线程
线程退出只有自然死亡是正常的!!!
多线程处理signal:主线程统一处理!! ----> 子线程将异步信号转换为同步文件fd 事件 传递给主线程!! 参考libevent 中 sighandle 中 回调中通过写入pipe数据 master 读取event-fd 处理对应回调!!!、??