详解一次请求

客户端打开浏览器输入url地址请求页面,分两种页面,一种是不用登陆只请求静态页面,一种是需要登陆请求动态页面

1,静态页面

客户端请求,首先在本地缓存里面查看请求的域名是否有对应的IP地址的信息,如果没有,去访问本地机器的DNS服务器,若还没有就通过迭代的方式去一级一级往上询问

客户端拿到IP地址后,首先由传输层通过五元套接字(TCP,SRC,PORT,DST,PORT)以SYN去访问服务器,seq=x,这是第一次握手

服务器内核在得到客户端发过来的握手连接后,响应SYN+ACK给客户端,ack=x+1,seq=y(TCP是双向通道),并把这个连接放进内核的未完成队列(net.ipv4.tcp_max_syn_backlog)

客户端收到服务器的响应后,回复ACK,ack=y+1,seq=x+1+n发往服务端

服务端收到客户端ACK后,三次握手 完成,把这个连接从未完成队列移动到已完成队列(net.core.somaxconn)(这个参数是内核定义的大小,应用程序也可以定义大小)

以上的队列参数排序规则是,已完成队列的大小取最小值(内核定义,应用程序定义)

服务器应用程序以Nginx为例,worker进程会通过互斥锁的方式去抢占监听套接字(TCP,IP,PORT),规则由epoll_time_out等待时间跟低于worker_connections的7/8的worker进程去抢占

同一时间只有一个worker进程监听套接字

当已完成队列有连接时,worker进程通过accept()函数去获取连接,获取连接后worker进程与客户端发生通信,解析请求,期待IO,响应数据给客户端

以上Nginx的处理过程均是非阻塞的

2,动态页面

客户端第一次请求过程与上面一致,发送登录名与密码,不过在后端服务器验证完登录名与密码后,会为这个客户端生成session会话,并保存在本地,会让客户端第二次请求时带上以session id

为值的cookie,那样第二次过来的时候,服务端就能识别用户,并跟踪用户

以上的session是保存在服务端的,当有多台服务端集群时,就需要把session会话存放在redis里面,这样所有服务端都能去redis里面取得会话,识别用户信息,这种不需要haproxy,nginx的cookie

还有一种就是,服务端各自保存会话,由haproxy,nginx为客户端连接生成cookie,让每次客户端过来的请求都能到同一台服务端去

还有一种是不用session,而是用token来识别用户,服务端根据客户端的head,userid生成token,并用加密算法跟密钥为这个token签名

客户端往后的请求中带上这个token,服务端用密钥跟算法去验证这个签名是否是服务端发出的,若是通过验证,不是返回错误

这样,token就不是在服务端上面,而是保存在客户端上,服务端不用保存token信息,而haproxy也不用为客户端生成cookie

posted on 2019-07-07 15:17  一直用这名字  阅读(270)  评论(0编辑  收藏  举报

导航