服务器是如何处理多个用户的请求
‘壹’ 服务器同时接收到多条请求会怎么处理
理论上有多少块CPU就可以同时处理多少请求,如果同时有多个请求过来一般会根据时间和优先级排序,先处理优先级高+先到达的。
另外,什么叫同时收到?一弹指含二十瞬,一瞬含二十念,一念含九十刹那,一刹那含九百万生灭,到CPU那儿再怎么快也能给你分出先来后到。
‘贰’ java程序完成服务器和客户端的SOCKET通讯,要求服务器使用多线程接收和处理多个客户端访问请求
1. 客户端程序
import java.io.*;
import java.net.*;
public class TalkClient {
public static void main(String args[]) {
try{
Socket socket=new Socket("127.0.0.1",4700);
//向本机的4700端口发出客户请求
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
PrintWriter os=new PrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并构造PrintWriter对象
BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入流,并构造相应的BufferedReader对象
String readline;
readline=sin.readLine(); //从系统标准输入读入一字符串
while(!readline.equals("bye")){
//若从标准输入读入的字符串为 "bye"则停止循环
os.println(readline);
//将从系统标准输入读入的字符串输出到Server
os.flush();
//刷新输出流,使Server马上收到该字符串
System.out.println("Client:"+readline);
//在系统标准输出上打印读入的字符串
System.out.println("Server:"+is.readLine());
//从Server读入一字符串,并打印到标准输出上
readline=sin.readLine(); //从系统标准输入读入一字符串
} //继续循环
os.close(); //关闭Socket输出流
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
}catch(Exception e) {
System.out.println("Error"+e); //出错,则打印出错信息
}
}
}
2. 服务器端程序
import java.io.*;
import java.net.*;
import java.applet.Applet;
public class TalkServer{
public static void main(String args[]) {
try{
ServerSocket server=null;
try{
server=new ServerSocket(4700);
//创建一个ServerSocket在端口4700监听客户请求
}catch(Exception e) {
System.out.println("can not listen to:"+e);
//出错,打印出错信息
}
Socket socket=null;
try{
socket=server.accept();
//使用accept()阻塞等待客户请求,有客户
//请求到来则产生一个Socket对象,并继续执行
}catch(Exception e) {
System.out.println("Error."+e);
//出错,打印出错信息
}
String line;
BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入流,并构造相应的BufferedReader对象
PrintWriter os=newPrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并构造PrintWriter对象
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
System.out.println("Client:"+is.readLine());
//在标准输出上打印从客户端读入的字符串
line=sin.readLine();
//从标准输入读入一字符串
while(!line.equals("bye")){
//如果该字符串为 "bye",则停止循环
os.println(line);
//向客户端输出该字符串
os.flush();
//刷新输出流,使Client马上收到该字符串
System.out.println("Server:"+line);
//在系统标准输出上打印读入的字符串
System.out.println("Client:"+is.readLine());
//从Client读入一字符串,并打印到标准输出上
line=sin.readLine();
//从系统标准输入读入一字符串
} //继续循环
os.close(); //关闭Socket输出流
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
server.close(); //关闭ServerSocket
}catch(Exception e){
System.out.println("Error:"+e);
//出错,打印出错信息
}
}}
‘叁’ 服务器如何实现承受如此大量的用户请求
首先以网站和游戏服务器为例。是否每一位用户都将自己的请求发送到同一IP地址,实际应用中他们只将请求发送到同一域名,不一定是同一IP地址。在此,服务器对待这些请求,是否只有两种处理方式: 一种独立完成 另一种先用一台服务器接收下来,然后通过某种方式将请求分发给其他服务器. 如果都指向同一IP地址的话,是。但如何实现“另一种”有很多种方法。可否就"服务器分发请求"这种方式简述一下实现。此类技术统称Load Balancing,根据你的服务需要可以在TCP/IP栈的上四层的任何一层实现。每一层又有不同的实现方法。具体的大概读一读相关文档更容易。是否不论是以上哪两种,这其中必然会有一个集中处理的过程。你既然已经要求到达同一IP了,自然这个IP上就要集中处理。当然对于大多数业务后台也会集中处理,不过不在此题目之限。若存在一个集中处理的过程,像网络这样的网站,又是如何做到让集中接收请求的那台机器不被大量的用户请求淹没,首先你的硬件要足够强大。
‘肆’ 服务器如何实现承受如此大量的用户请求
首先我想说楼主的提问列表很程序员,从0开始的。
这个当然是不一定的,楼主已经知道问题是负载均衡了,现在大型服务器一般都会做成分布式的。
其实你说的意思应该是直接处理这个请求还是我找另外一个机器处理你的请求。
服务器分发请求有很多种策略,举个简单的例子。某个服务器在登录的时候根据用户的ID取模,然后选择对应的一台机器进行转发,这是一种比较简单的分发请求策略了。再比如很多游戏服务器会分网通、电信等大区,然后大区下有分1,2,3...多个房间,这些其实都是分发请求的例子。
根据你的业务类型,可能会存在一个必须有集中处理的过程。比如登录校验这个过程,所有的请求最终都要去查询db,那么如果db只有一台的话就会存在你说的集中处理情况。现在的开发很聪明的,无论是高并发还是容灾都不会只搞一台db的,他们可以分库分表,可会主从备份,甚至是读写分离。
在设计服务器的时候,肯定会相对会有4中的情况,我们当然不希望因为4中的情况而影响整个服务器的性能。
我们可以把分发策略放在客户端,比如登录的时候在客户端进行选择,直接登录到负载较低的服务器上。你会说客户端查询各个服务器的负载情况这个功能接口会压力很大,其实不做IO操作的话,仅仅是获取内存中的数据性能会很高的。
如果楼主需要进行服务器压力测试的话可以试试腾讯公司的一款工具WeTest服务器性能,用来测试服务器各个接口的性能情况很有效,附个链接:http://wetest.qq.com/gaps/。