手写一个民用Tomcat (03)

2024-04-10 10:52
文章标签 tomcat 03 手写 民用

本文主要是介绍手写一个民用Tomcat (03),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们完成了这个 小型Tomcat 基本功能,但是他处理请求还是 一个一个的执行,并不能做到并行处理。 我们仿照Tomcat的思路来进行 一比一精准优化。

 首先看一下我们的JxdHttpConnector 有什么改进,他可以理解成一个快递站领导,统一指挥JxdHttpProcessor 进行 工作。

JxdHttpConnector引入一个队列池,每接到一个请求,就冲队列池中取出来,执行这个请求,执行完之后再放回队列池中,继续等待下一个处理。

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayDeque;
import java.util.Deque;public class JxdHttpConnector implements Runnable {int minProcessors = 3;int maxProcessors = 10;int curProcessors = 0;//存放多个processor的池子Deque<JxdHttpProcessor> processorDeque = new ArrayDeque<>();@Overridepublic void run() {ServerSocket serverSocket = null;int port = 8080;try {serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));} catch (IOException e) {e.printStackTrace();System.exit(1);}//初始化池子 最开始三个initProcessorDeque();while (true) {Socket socket = null;try {//这是单线程 一个请求一个请求获取socketsocket = serverSocket.accept();//得到一个新的processor,这个processor从池中获取(池中有可能新建)JxdHttpProcessor processor = createProcessor();if (processor == null) {socket.close();continue;}processor.assign(socket);} catch (Exception e) {e.printStackTrace();}}}public void start() {Thread thread = new Thread(this);thread.start();}//从池子中获取一个processor,如果池子为空且小于最大限制,则新建一个private JxdHttpProcessor createProcessor() {synchronized (processorDeque) {if (processorDeque.size() > 0) {return processorDeque.pop();}if (curProcessors < maxProcessors) {return newProcessor();} else {return null;}}}private void initProcessorDeque(){for (int i = 0; i < minProcessors; i++) {JxdHttpProcessor processor = new JxdHttpProcessor(this);processor.start();processorDeque.push(processor);}curProcessors = minProcessors;}private JxdHttpProcessor newProcessor() {JxdHttpProcessor jxdHttpProcessor = new JxdHttpProcessor(this);jxdHttpProcessor.start();processorDeque.push(jxdHttpProcessor);curProcessors++;return processorDeque.pop();}public void recycle(JxdHttpProcessor processor) {processorDeque.push(processor);}
}
processorDeque这就是队列池,刚开始的时候 会创建三个,随着业务访问了增加 最多增加10个 ,

你们发现了吗  JxdHttpProcessor 为啥要.start()多线程进行处理,因为 你 虽然引入队列池但是还是不能 解决并行处理问题,所以要让每一个真正的执行者(员工)。进行并行处理。

JxdHttpProcessor 代码:

public class JxdHttpProcessor implements Runnable {boolean available = false;Socket socket;JxdHttpConnector connector;public JxdHttpProcessor(JxdHttpConnector connector) {this.connector = connector;}private void process(Socket socket) { //服务器循环等待请求并处理try {Thread.sleep(3000);} catch (InterruptedException e1) {e1.printStackTrace();}InputStream input = null;OutputStream output = null;try {input = socket.getInputStream();output = socket.getOutputStream();// create Request object and parseJxdRequest request = new JxdRequest(input);request.parse();// create Response objectJxdResponse response = new JxdResponse(output);if (request.getUri().startsWith("/servlet/")) {//加载动态资源JxdServletProcessor jxdServletProcessor = new JxdServletProcessor();jxdServletProcessor.process(request, response);} else {//加载静态资源StaticResourceProcessor staticResourceProcessor = new StaticResourceProcessor();staticResourceProcessor.process(request, response);}//因为是多线程所以只能交给httpProcessor 来关闭socket.close();} catch (Exception ea) {ea.printStackTrace();}}@Overridepublic void run() {while (true) {// 等待socket分配过来Socket socket = await();if (socket == null) continue;// 处理请求process(socket);// 回收processor,员工归队      connector.recycle(this);}}public void start() {Thread thread = new Thread(this);thread.start();}private synchronized Socket await() {// 等待connector提供一个新的socketwhile (!available) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}// 获得这个新的SocketSocket socket = this.socket;//设置标志为falseavailable = false;//通知另外的线程notifyAll();return (socket);}public synchronized void assign(Socket socket) {// 等待connector提供一个新的socketwhile (available) {try {wait();} catch (InterruptedException e) {}}// 获取到这个新的Socketthis.socket = socket;// 把标志设置回去available = true;//通知另外的线程notifyAll();}
}
JxdHttpProcessor 真正的执行者 实现了 Runnable 接口 同时引入了 await()和assign()方法和available 标识。先说await()方法 ,available 默认为false 也就是线程启动的时候进入 等待状态,一直等,等谁呢 他在等待一个指令,就类似于 员工快递站工作,等来了快递 才工作 没有快递 就休息。

在说一下 assign()方法,他的入参是Socket ,表示 快递来了 ,因为available 默认为false所以他会继续走 ,把标志available 默认为true 然后 通知await()中等待的 员工要开始工作了 。

这就是 形成了一套 运行 机制,我通知你干活,你干完活之后 告诉我 ,我们在02那篇文章的时候是这样的,JxdHttpConnector 领导一直紧跟着JxdHttpProcessor 员工,直到员工干完活,一个领导盯着一个员工很累的,现在是 这个领导 统一指挥一个 团队,员工自己干完活之后反馈给领导。

socket.close(); 还记得这个吗。之前是 有JxdHttpConnector 来关闭的,现在由 员工JxdHttpProcessor来关闭了,为啥 因为领导 一致盯着 员工直到 结束,但是现在 盯不住了 ,只能员工自己 才知道什么时候结束 。

备注:其他类不展示 基本每改动。

看一下运行结果吧。 

public class JxdHttpServer {public static final String WEB_ROOT = System.getProperty("user.dir");public static final String FILE_ROOT = "D:\\";public static void main(String[] args) {JxdHttpConnector connector = new JxdHttpConnector();connector.start();}
}

这篇关于手写一个民用Tomcat (03)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/890859

相关文章

Tomcat版本与Java版本的关系及说明

《Tomcat版本与Java版本的关系及说明》:本文主要介绍Tomcat版本与Java版本的关系及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat版本与Java版本的关系Tomcat历史版本对应的Java版本Tomcat支持哪些版本的pythonJ

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

如何将Tomcat容器替换为Jetty容器

《如何将Tomcat容器替换为Jetty容器》:本文主要介绍如何将Tomcat容器替换为Jetty容器问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat容器替换为Jetty容器修改Maven依赖配置文件调整(可选)重新构建和运行总结Tomcat容器替

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

Centos环境下Tomcat虚拟主机配置详细教程

《Centos环境下Tomcat虚拟主机配置详细教程》这篇文章主要讲的是在CentOS系统上,如何一步步配置Tomcat的虚拟主机,内容很简单,从目录准备到配置文件修改,再到重启和测试,手把手带你搞定... 目录1. 准备虚拟主机的目录和内容创建目录添加测试文件2. 修改 Tomcat 的 server.X

Tomcat的下载安装与使用教程

《Tomcat的下载安装与使用教程》本文介绍了Tomcat的下载、安装和使用方法,包括在本机和云服务器上部署Tomcat的过程,以及解决启动失败问题的方法... 目录Tomcat的下载安装与使用Tomcat的下载与安装Tomcat在本机运行使用Tomcat在php云服务器上的使用总结Tomcat的下载安装与

Tomcat高效部署与性能优化方式

《Tomcat高效部署与性能优化方式》本文介绍了如何高效部署Tomcat并进行性能优化,以确保Web应用的稳定运行和高效响应,高效部署包括环境准备、安装Tomcat、配置Tomcat、部署应用和启动T... 目录Tomcat高效部署与性能优化一、引言二、Tomcat高效部署三、Tomcat性能优化总结Tom

通过prometheus监控Tomcat运行状态的操作流程

《通过prometheus监控Tomcat运行状态的操作流程》文章介绍了如何安装和配置Tomcat,并使用Prometheus和TomcatExporter来监控Tomcat的运行状态,文章详细讲解了... 目录Tomcat安装配置以及prometheus监控Tomcat一. 安装并配置tomcat1、安装

使用TomCat,service输出台出现乱码的解决

《使用TomCat,service输出台出现乱码的解决》本文介绍了解决Tomcat服务输出台中文乱码问题的两种方法,第一种方法是修改`logging.properties`文件中的`prefix`和`... 目录使用TomCat,service输出台出现乱码问题1解决方案问题2解决方案总结使用TomCat,

最新版IDEA配置 Tomcat的详细过程

《最新版IDEA配置Tomcat的详细过程》本文介绍如何在IDEA中配置Tomcat服务器,并创建Web项目,首先检查Tomcat是否安装完成,然后在IDEA中创建Web项目并添加Web结构,接着,... 目录配置tomcat第一步,先给项目添加Web结构查看端口号配置tomcat    先检查自己的to