04|各司其职的Server:拆分响应模块与处理模块
项目结构
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了如何在手写MiniTomcat的过程中,拆分响应模块与处理模块,使各个部分各司其职。作者首先讨论了符合Servlet规范的重要性,并介绍了在Java的规则下实现MiniTomcat的方法。文章还提到了项目结构的变化,引入了Maven结构对项目的包依赖进行管理,并尽可能使用最原生的JDK来实现功能。新增的HttpConnector.java和HttpProcessor.java用来拆分HttpServer两个类,同时引入了javax.servlet.Servlet类。通过这些改进,读者可以更深地理解原理,并且能够快速了解如何在Java的规则下实现MiniTomcat。文章还详细介绍了对Request和Response类的改造,以及对ServletProcessor和HelloServlet的调整,最终实现了正确输出中文。整体而言,本文通过实际代码示例和详细解释,帮助读者更好地理解了如何在Java环境下实现MiniTomcat。 文章通过拆分HttpServer的功能,将其分为Connector和Processor两部分,实现了各司其职的目标。HttpProcessor负责处理接收、响应客户端请求以及调用Servlet,而HttpConnector负责接收连接并支持并发处理,提高整个服务器的吞吐量。通过对HelloServlet的改造和测试,读者可以清晰地了解改进后的功能。最后,文章提出了一个思考题,引导读者思考如何提高服务器的并发度。 总的来说,本文通过实际代码示例和详细解释,帮助读者更好地理解了如何在Java环境下实现MiniTomcat,并且引发了读者对服务器并发度提升的思考。
《手把手带你写一个 MiniTomcat》,新⼈⾸单¥59
全部留言(4)
- 最新
- 精选
- ?新!老师我有个关于tomcat连接层的问题求教? 场景:外部nginx日志记录调用了A服务并且超时,但是A服务本地日志localhost_access_log,没有记录,了解后怀疑是连接层,会等待队列就超时了,所以没有到容器层,没有被localhost_access_log记录? 问题: 1 我的怀疑是否可能? 2 有办法验证吗?比如tomcat等待队列超时或者accept超时,能记录日志
作者回复: 有道理。你看一下catalina开头的日志文件。 再启用一下AccessLogValve看看。
2024-01-02归属地:四川21 - peter请教老师几个问题: Q1:streamHandler不需要赋值吗? ServletProcessor.java的process方法中: URLStreamHandler streamHandler = null; urls[0] = new URL(null, repository, streamHandler); 代码声明了变量“streamHandler”, 但是没有赋值,然后直接用来创建URL的对象。 请问:为什么没有给“streamHandler”赋值? Q2:HttpConnector的run方法为什么没有注解? 类定义:HttpConnector implements Runnable, 其run方法上面没有注解,Idea2019提示: Missing '@Override' annotation on 'run()' 。 但程序能运行。请问老师的代码中,run方法为什么没有注解? Q3:第03课代码,一次请求,socket = serverSocket.accept();为什么运行两次? HttpServer.java文件中,while(true)代码块,在serverSocket.accept();这里阻塞。浏览器中输入请求,创建Request,成功地走完了整个流程。走完整个流程后按道理应该还在serverSocket.accept();这里阻塞。但竟然再次创建Request,不过在Request类的parse函数中,在i = input.read(buffer);这个地方不再往下面执行。我在input.read前后都加了打印语句,前面的打印语句执行了,后面的没有执行,神奇啊,为什么啊? 简单地说,就是:浏览器发送一个请求,HttpServer收到了两个request,第一个正常处理,第二个不能正常执行。(我用的是Chrome浏览器,也许和浏览器有关?)
作者回复: Q1, 你自己看URL api帮助文档 Q2, @Override是一个编译时注解,加上是一个好习惯,没有也不会出运行时错误 Q3,这个问题好。有些浏览器将请求分成简单请求和非简单请求,对于非简单请求,浏览器会先发出一个OPTIONS预检请求,这是为了安全性的原因。MiniTomcat没有考虑这些实际工作中的复杂性,直接忽略了。
2023-12-16归属地:北京31 - stars只是在主线程启动了一个子线程,这样就提高吞吐率了吗?请教老师。
作者回复: 没有简单的答案。对Tomcat这种场景,前面的线程用于接收客户端网络连接,后面的线程用于业务处理(合理的假定会消耗数据库),这种场景就是会提高吞吐量的。
2023-12-25归属地:陕西 - HH🐷🐠😄池子+队列, 学艺不精具体细节答不上来, 请老师指点。
作者回复: 提高并发度有一系列技术。能第一反应出来的就是多线程,将processor设计成多个线程,放到一个池子里面,服务器接受前端多个请求后交给后面线程池子里面的多个processor线程来并发处理。这解决了一部分问题,但是对一个processor来说,它还是串行工作的,当它涉及到数据库访问网络访问文件操作的时候,可以进一步再分线程。不过程序模式需要调整成使用Future或者CompletableFuture,完全的响应式编程结构复杂。JDK21提出的virtual thread很好地解决了这个问题。实际工作中,要根据场景要求进行选择。
2023-12-15归属地:广东2