图解IO模型——BIO,NIO,AIO
服务架构模式——TPC/PPC模式
服务架构模式——单Reactor模式
服务架构模式——多Reactor模式
服务架构模式——Proactor模式
服务端接收客户端请求,处理请求,然后发送响应给客户端。
接收请求,发送响应的过程就是网络IO的过程,而处理请求就是线程计算。
因此服务端软件架构的设计有两个关键: 一是IO模型——采用何种IO模型来感知IO事件(连接事件,读请求事件,写响应事件) ,二是线程模型——如何使用有限数量的线程处理多个客户端发来的请求 。
TPC/PPC模式是最简单的服务端架构模式,IO模式采用BIO,为每个连接创建一个线程进行请求处理。
TPC
TPC: Thread per-connection.
当收到客户端连接时,服务端为每个客户端创建一个新的线程,一个线程处理一个客户端的请求。
image.png
另外还有一种PPC(Process per-connection)模式, 为每个客户端创建一个新“进程”,架构模式和TPC类似,只是把线程换成进程。
代码实现
serverSocket.accept()监听客户端请求,当有客户端请求到达时,创建一个新线程处理客户端请求
public class BIOServer implements Runnable{
public static void main(String[] args) {
new Thread(new BIOServer(), "BIO server").start();
}
@Override
public void run() {
try(ServerSocket serverSocket = new ServerSocket(Constant.port)){
while(true){
//接收请求
Socket socket = serverSocket.accept();
//每个请求启动一个线程
RequestHanlder hanlder = new RequestHanlder(socket);
Thread t = new Thread(hanlder);
t.start();
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
这种模式的优点是开发简单,适合连接数比较少的场景。当连接数较多时,服务端需要创建大量的线程,而服务端线程数量不可能无限制增加,因此使用线程池进行改进。
TPC改进版——线程池
设定worker线程池,当收到客户端请求时,先放入请求队列,由worker线程从队列中取出请求进行处理,然后返回响应给客户端 。
代码实现
设立一个worker线程池,当有客户端请求到达时,创建一个新runnable对象,放到worker线程池中处理。
public class BIOServerThreadPool implements Runnable{
public static void main(String[] args) {
new Thread(new BIOServerThreadPool(), "BIO server pool").start();
}
@Override
public void run() {
try(ServerSocket serverSocket = new ServerSocket(Constant.port)){
ExecutorService workerPool = Executors.newFixedThreadPool(8);
while(true){
//接收请求
Socket socket = serverSocket.accept();
//把请求放入线程池
RequestHanlder hanlder = new RequestHanlder(socket);
workerPool.submit(hanlder);
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
这种架构模式可以固定worker线程池的大小,防止由于并发请求量大导致服务端线程数量超限。当然也有缺点,当请求数量过多时,大量请求会积压在请求队列中,导致请求延迟增加。
网友评论