怎么检测包体的结束(在头部有一个content-length,然后你收内容为这个长度即可)
进一步提升服务器性能的方向
高并发
单个服务性能
实现原理
将源文件按长度为分为N块文件,然后开辟N个线程,每个线程传输一块,最后合并所有线线程文件.比如
一个文件500M我们按长度可以分5个线程传输.第一线程从0-100M,第二线程从100M-200M......最后合并5个线程文件.
实现流程
1.客户端向服务端请求文件信息(名称,长度)
2.客户端跟据文件长度开辟N个线程连接服务端
3.服务端开辟新的线程与客户端通信并传输文件
4.客户端将每线程数据保存到一个文件
5.合并所有线程文件
各种模型的优化方案
这里可能需要有一定理解和基础才能看懂,看不懂就跳过就好了,未来就能看懂的嘿嘿。
同步写非阻塞模型怎么优化
异步写非阻塞(aio_read)
proactor模式
静态页面动态页面分离
增加集群服务器(多进程)
同步多线程和异步多线程区别
同步多线程的瓶颈
线程数
reactor模型是同步读
异步多线程的缺点
异步导致逻辑复杂
需要考虑线程间同步互斥问题。
各种模式的总结
1、同步单线程模式
优点:a)实现简单。b)不用考虑线程间同步互斥问题。
缺点:a)对CPU的使用率不高(容易在进行IO操作或自身等待操作时阻塞),在多CPU时劣势更明显。b)并发性不好,在有的事件需要长时间占用CPU处理的情况下,其他事件会长时间等待得不到处理。
2、同步多线程模式
优点:a)对CPU的使用率较高,在多CPU时优势更明显。b)并发性好,各线程都能根据优先级得到执行。
缺点:a)需要考虑线程间同步互斥问题。b)实现较复杂,不同线程的业务步骤有相互依赖时,需要分解实现成状态机及事件通知驱动模式(或者轮询模式)。
3、异步多线程模式
优点:a)对CPU的使用率高,在多CPU时优势更明显。b)并发性好,各线程都能根据优先级得到执行。
缺点:a)需要考虑线程间同步互斥问题。b)实现复杂,要把所有会导致阻塞的操作转化为异步操作,另外不同线程的业务步骤有相互依赖时,需要分解实现成状态机及事件通知驱动模式(或者轮询模式)。
4、异步单线程模式
优点:a)对CPU的使用率高。b)不用考虑线程间同步互斥问题。
缺点:a)实现较复杂,要把所有会导致阻塞的操作转化为异步操作。b)并发性不好,在有的事件需要长时间占用CPU处理的情况下,其他事件会长时间等待得不到处理。c)在多CPU时不如多线程高效。
简单的说:同步实现简单但是CPU利用率低,异步实现复杂但是CPU利用率高。
单线程不用考虑互斥但是并发性、多CPU利用率低,多线程需要考虑互斥但是并发性、多CPU利用率高。
综合参考
当下流行的技术架构
使用多线程多进程的服务器/常见服务器 端口与连接相关问题 可以多个线程监听同一个端口吗 tcp/udp可以绑定同一个端口吗(镜像问题)
tcp/udp均不可以两个同类的监听socket绑定在同一个端口上。
但是可以一个tcp一个udp同时绑定一个端口。
由上述结果可知:TCP、UDP可以同时绑定一个端口8888,但是一个端口在同一时刻不可以被TCP或者UDP绑定2次。
原因如下:
tcp的端口不是物理概念,仅仅是协议栈中的两个字节; TCP和UDP的端口完全没有任何关系,完全有可能又有一种XXP基于IP,也有端口的概念,这是完全可能的; TCP和UDP传输协议监听同一个端口后,接收数据互不影响,不冲突。因为数据接收时时根据五元组{传输协议,源IP,目的IP,源端口,目的端口}判断接受者的。 端口复用的应该仅在这些环境下使用
1、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启动的程序的socket2要占用该地址和端口,你的程序就要用到该选项。
2、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可以测试这种情况。
3、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个socket绑定的ip地址不同。这和2很相似,区别请看UNPv1。
4、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的多播,不用于TCP。
需要注意的是,设置端口复用函数要在绑定之前调用,而且只要绑定到同一个端口的所有套接字都得设置复用:
socket连接的理解
如果一个程序创建了一个socket,并让其监听80端口,其实是向TCP/IP协议栈声明了其对80端口的占有。以后,所有目标是80端口的TCP数据包都会 转发给该程序(这里的程序,因为使用的是Socket编程接口,所以首先由Socket层来处理)。所谓accept函数,其实抽象的是TCP的连接建立过程。accept函数返回的新socket其实指代的是本次创建的连接,而一个连接是包括两部分信息的,一个是源IP和源端口,另一个是宿IP和宿端口。所以,accept可以产生多个不同的socket,而这些socket里包含的宿IP和宿端口是不变的,变化的只是源IP和源端口。这样的话,这些socket宿端口就可以都是80,而Socket层还是能根据源/宿对来准确地分辨出IP包和socket的归属关系,从而完成对TCP/IP协议的操作封装!而同时,放火墙的对IP包的处理规则也是清晰明了,不存在前面设想的种种复杂的情形。
多个服务器监听socket强行绑定到一个端口上,每次只能有一个accept得到正确的响应。
明白socket只是对TCP/IP协议栈操作的抽象,而不是简单的映射关系,这很重要!
主机上最多能保持多少个连接
这个问题在某乎上有一篇非常好的回答,不放链接了感兴趣的同学自己去搜把。作者闪客sum。根据该回答个人归纳总结如下:
连接通过5元组唯一识别(源IP,源端口,目标IP,目标端口,协议)。协议比如tcp,udp。只要五元组不同就是不同的socket连接。
瓶颈1 端口号限制
[root]# cat /proc/sys/net/ipv4/ip_local_port_range 1024 65000 //修改范围 vim /etc/sysctl.conf net.ipv4.ip_local_port_range = 60000 60009
理论端口号是16位,范围1~65535,但实际上是有限制的,并不是所有端口号都可用。如果始终向同一目标IP和同一目标端口发出连接请求,首先会遇到的是端口号限制。
此时如果不断更换目标IP和目标端口号,可以继续发出连接请求
瓶颈2 文件描述符限制
linux对于文件描述符的限制有3个级别
瓶颈3 线程并发过多
C10K问题,当服务器连接数达到1万且每个连接都需要消耗线程资源的时候,操作系统会忙于线程上下文切换,可能会导致系统崩溃,同时建立新连接会越来越慢。需要使用IO多路复用技术解决这一问题。简而言之,使得一个线程可以管理多个TCP连接的资源。
瓶颈4 内存 瓶颈5 CPU 资源 一台Linux服务器的资源 一个TCP连接占用的资源 占满了会发生什么
CPU
看你花多少钱买的
看你用它干嘛
电脑卡死
内存
看你花多少钱买的
取决于缓冲区大小
OOM
临时端口号
ip_local_port_range
cannot assign requested address
文件描述符
fs.file-max
too many open files
进程\线程数
ulimit -n
看IO模型
系统崩溃
一些其他问题 跨域问题
跨域问题()
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。
所谓同源是指,域名,协议,端口均相同,只要有一个不同,就是跨域。不明白没关系,举个栗子:
调用 (非跨域)
调用 (主域名不同:123/456,跨域)
调用 (子域名不同:abc/def,跨域)
:8080/index.html 调用 :8081/server.php (端口不同:8080/8081,跨域)