个人理解:
首先要理解并发的概念,字面意思就是并行发生。当有大量事务需要处理的时候,就产生的并发,当只有一个处理器的core的时候,事实上同一个时刻只有一件事务可以处理,即便是超线程技术,同时也只能处理一件事务,当然cpu的频率已经非常高了,比如一个核心的主频是1GHz,也就意味着每秒钟开关1,073,741,824(1*1024*1204*1024)次,合理利用时间间隔,也可以给人是并行的错觉。
遇到问题:
这次是遇到了一个任务,主要内容是:监控文件目录,将发生变化的文件,及时传输到指定远程服务器,经服务器计算该文件,返回该文件变动属性。而且不同的文件,需要发往不同的服务器。
考虑因素:
1.服务的承载能力。
2.文件变动的速率和个数。
3.本地处理器的计算能力,cpu最多可以让出多少计算能力。
4.选用什么技术进行传输
5.选用什么技术进行监控文件
6.选用什么框架进行并行
设计方法:
在linux下,以阻塞方式监控文件描述符的属性变化,将写完毕的文件,经过判断文件名筛选掉一部分不需要的文件,然后把加入执行队列。在另一头开启一个进程监控该队列是否消息(该队列是否需要阻塞?),如果有消息就立即转发,利用根据文件的属性发往不同的服务器,传输方式是长连接tcp上的http消息,但是http有一个弊端,需要等待响应的到来(具体不是很清楚是否一定要等待响应,但是我做的请求都是需要等待响应一个 200 ok,比较迷),这就大大降低的传输能力,但是没办法,因为这里的响应结果是有用的数据,一来可以判断是否成功发送,二来可以得到文件属性变动的数据。为了增加传输能力,只能在这一步上做出牺牲,其实我仔细想想,服务器端可以累计再响应,单个就响应返回比较费力不讨好。这里需要做的就是在响应完毕时立即进行下一次数据的发送。同时开启100线程直接可以让操作系统卡死,而且http的传输能力不足以这么做,这里采用5个线程,考虑资源问题,在不需要的可以将线程挂起,而不是销毁,这就有点线程池的感觉了,而且可以做到在下一次消息到来的时候,1号线程恰巧执行上次传输任务完毕,那么可以继续使用该线程,而不是在线程池里再拿2号线程,产生多余的消耗。当没有空余线程的时候,消息应该在消息队列中阻塞,这里设计一个可以承载100个消息的队列。
小结:
1.inotify+epoll+消息队列+线程池+http+mysql(主要任务,也是方便自己理解这些技术)
2.inotify+redis+http(备用)
3.inotify+redis+udp(服务器可以改的话)
结语:
个人总结,完成后贴各版本小结的设计代码,主程序均采用c,考虑服务器部分改写用python或lua
原文:https://www.cnblogs.com/still-smile/p/13311220.html