最通俗易懂的 - Tomcat 核心源码仿写 第二版代码

news2024/11/24 20:09:39

– 更新信息 –

第一版代码实现了基本的交互功能,但只实现了单线程,此次迭代修改多线程,并升级为Maven项目,同时优化代码排版,提高代码可读性

第一版代码介绍博客地址:最通俗易懂的 - Tomcat 核心源码仿写

– 源码地址 –
朱元杰的开源仓库 – Tomcat核心源码仿写

– 正文内容 –

直接上main方法代码:

public static void main(String[] args) throws IOException {

        //创建JUL日志执行器
        Logger myTomcatLogger = Logger.getLogger("MyTomcat");

        //创建线程池
        ThreadPoolExecutor threadPoolExecutor = createThreadPoolExecutor();

        //启动阶段
        startupPhase(myTomcatLogger);

        //注册端口
        InetAddress localHost = InetAddress.getLocalHost();
        myTomcatLogger.info("当前服务器信息:" + localHost);
        ServerSocket serverSocket = new ServerSocket(8080, 10, localHost);

        while (true) {

            myTomcatLogger.info("等待建立连接 - " + connectSerialNumber);
            Socket socket = serverSocket.accept();
            myTomcatLogger.info("连接已建立 - " + connectSerialNumber);
            connectSerialNumber++;

            threadPoolExecutor.execute(() -> {

                //接收Http请求报文
                ArrayList<String> httpMessage = receiveHttp(socket, myTomcatLogger);

                //处理请求
                //获取请求方式
                String httpHead = httpMessage.get(0);
                String requestStyle = httpHead.split(" ")[0];

                if (requestStyle.equals("GET")) {

                    String requestPathAndParameter = httpHead.split(" ")[1];

                    //创建HttpRequest对象
                    MyHttpRequest myHttpRequest = new MyHttpRequest();

                    //获取请求路径,并将参数置入HttpRequest对象
                    String requestPath = getRequestPathAndSetMyHttpRequest(requestPathAndParameter, myHttpRequest, myTomcatLogger);

                    //还没处理 favicon.ico 请求,先屏蔽
                    if (requestPath.equals("favicon.ico")) {
                        myTomcatLogger.info("暂时无法响应 favicon.ico");
                        return;
                    }

                    //创建HttpResponse对象
                    MyHttpResponse myHttpResponse = getMyHttpResponse(socket);

                    //反射调用Servlet方法
                    servletActuator(requestPath, "doGet", myHttpRequest, myHttpResponse);

                } else {
                    myTomcatLogger.info("还未开通其他请求方式.....");
                }
            });
        }

本次引入线程池,将交互的内容交给线程池完成,main方法负责建立socket连接

可以看到有个while(true)循环,不断建立socket连接,建立起连接后就将连接丢给threadPoolExecutor.execute 去处理

在 threadPoolExecutor.execute 中完成的还是那几步:

  1. 接收Http请求报文
  2. 获取请求路径和请求参数
  3. 创建出 HttpRequest 和 HttpResponse 对象
  4. 通过反射调用请求路径对应的 servlet 方法

我将每一步的具体实现方法都封装成了一个方法,需要的就去我的Gitee上拿源码吧

另外,通过配置文件配置线程池的方法如下:

  1. 引入 org.yaml 依赖,因为我是通过 yml 文件进行配置的
		<dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.29</version>
        </dependency>
  1. 在resources 文件下编写配置文件 config.yml 内容如下:
thread:
  pool:
    coreSize: 5
    maxSize: 10
    keepAliveTime: 60
    workQueueSize: 1000
  1. 接着就可以创建线程池了
    private static ThreadPoolExecutor createThreadPoolExecutor() throws FileNotFoundException {
        //读取yml配置文件
        Yaml yaml = new Yaml();
        InputStream inputStream = new FileInputStream("src\\main\\resources\\config.yml");
        Map<String, Object> threadPoolMap = new HashMap<>();
        threadPoolMap = yaml.load(inputStream);
        Map<String, Map<String, Object>> poolMap = (Map<String, Map<String, Object>>) threadPoolMap.get("thread");
        //创建线程池
        return new ThreadPoolExecutor(
                (Integer) poolMap.get("pool").get("coreSize"),
                (Integer) poolMap.get("pool").get("maxSize"),
                (Integer) poolMap.get("pool").get("keepAliveTime"),
                TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>((Integer) poolMap.get("pool").get("workQueueSize")),
                new ThreadPoolExecutor.AbortPolicy()
        );
    }

现在已经可以进行多台主机的连续请求,效果如下:

第一次请求:
在这里插入图片描述
第二次请求 - 修改请求地址为 address2(出现了乱码问题,不过问题不大嘿嘿):
在这里插入图片描述

查看控制台输出:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实际上这边总共有四次请求,这是因为每次我们发送请求时,浏览器都会自动发出一个请求来获取网站的 favicon.ico 文件。favicon.ico 是网站的小图标,通常位于网站的根目录下。这个请求是浏览器自动发出的,不需要用户手动触发。

另外一个可以看到,当前都是基于 Http 1.1 的请求, Http 1.1 是短链接,因此每一次请求都要建立一次socket连接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/891827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

odoo-035 Pycharm git commit 提交提示 No changes detected

文章目录 问题查找解决其他&#xff1f; 问题 在 gitee 上面新建的 git 项目&#xff0c;dowanload 下来&#xff0c;在 Pycharm 中修改后发现改完就变成白色到了&#xff0c;不是绿色或蓝色的&#xff0c;然后 git commit 的时候提示 No changes detected。 查找 上面是在 …

spring bean创建总览 1

1 开始 这是一个总图 下边慢慢看 我们最基础的写的方式就是xml的方式去写 像这样&#xff0c; 而我们会通过applicationContext的方式去获得我们的bean &#xff0c;我其中一篇博客就写到了applicationContext他的父类就是beanFactory 但是中间的是怎么样处理的呢&#xff1f…

springboot、java实现调用企业微信接口向指定用户发送消息

因为项目的业务逻辑需要向指定用户发送企业微信消息&#xff0c;所以在这里记录一下 目录 引入相关依赖创建配置工具类创建发送消息类测试类最终效果 引入相关依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-…

从 Ansible Galaxy 使用角色

从 Ansible Galaxy 使用角色 根据下列要求&#xff0c;创建一个名为 /home/curtis/ansible/roles.yml 的 playbook &#xff1a; playbook 中包含一个 play&#xff0c; 该 play 在 balancers 主机组中的主机上运行并将使用 balancer 角色。 此角色配置一项服务&#xff0c;以…

代码随想录算法训练营第63天|单调栈part02|503.下一个更大元素II、 42. 接雨水

代码随想录算法训练营第63天&#xff5c;单调栈part02&#xff5c;503.下一个更大元素II、 42. 接雨水 503.下一个更大元素II 503.下一个更大元素II 思路&#xff1a; 如何处理循环数组 相信不少同学看到这道题&#xff0c;就想那我直接把两个数组拼接在一起&#xff0c;然…

银河麒麟服务器v10 sp1 .Net6.0 上传文件错误

上一篇&#xff1a;银河麒麟服务器v10 sp1 部署.Net6.0 http https_csdn_aspnet的博客-CSDN博客 .NET 6之前&#xff0c;在Linux服务器上安装 libgdiplus 即可解决&#xff0c;libgdiplus是System.Drawing.Common原生端跨平台实现的主要提供者&#xff0c;是开源mono项目。地址…

小红书美妆护肤种草推广:深度剖析与实战策略

在这个平台上&#xff0c;用户可以分享自己的购物心得和产品评价&#xff0c;为其他消费者提供购买参考。这种基于用户真实体验的分享&#xff0c;更容易赢得消费者的信任&#xff0c;从而提高产品的购买转化率。 小红书俨然成为了美妆护肤品牌种草推广的主要战场&#xff0c;…

如何实现客户自助服务?打造产品知识库

良好的客户服务始于自助服务。根据哈佛商业评论&#xff0c;81% 的客户在联系工作人员之前尝试自己解决问题。92% 的客户表示他们更喜欢使用产品知识库/帮助中心。 所以本文主要探讨了产品知识库是什么&#xff0c;有哪些优势以及如何创建。 产品知识库是什么 产品知识库是将…

“展会建筑小背心”被百万网友吐槽火遍网络!到底为什么?

奇葩的建筑在国内绝对是一个又一个经典的存在&#xff01;前有央视大楼被网友吐槽像大裤衩&#xff0c;后就有金主爸爸富而喜悦耗资50多万设计的展会建筑&#xff0c;被数万网友温柔吐槽像极了“展会建筑小背心”&#xff01;更是在不到短短的24小时里&#xff0c;就被微博网友…

Scratch 之 如何制作鼠标框(2)—— 鼠标框框定角色

hello&#xff0c;大家好&#xff0c;欢迎来到鼠标框系列的第二课时&#xff01; 咱们废话不多说&#xff0c;直接开始 首先&#xff0c;温故知新一下&#xff0c;上个教程我们讨论了如何绘制鼠标框&#xff0c;网址&#xff1a;绘制鼠标框 你说&#xff0c;一个鼠标框&…

excel条件格式:不同组对应位置对比标记

问题描述 下图中有两组数据&#xff0c;想要对比两个对应位置的数据并标记 条件格式 选中其中一个单元格&#xff0c;条件格式->新建规则 使用公式确定要设置格式的单元格&#xff0c;自定义需求 格式化剩余同样标准的单元格

自定义WEB框架结合Jenkins实现全自动测试

自定义WEB框架结合Jenkins实现全自动测试 allure生成 allure生成 1.allure–纯命令运行 -固定的–稍微记住对应的单词即可。2 安装&#xff0c;2个步骤: 1.下载allure包&#xff0c;然后配置环境变量。 https://github.com/allure-framework/allure2/releases/tag/2.22.4 2.在…

卫星定位接收机的现场安装步骤

卫星定位接收机的现场安装步骤如下&#xff1a; 1.选址和规划&#xff1a;选择一个位于开阔空地或无遮挡的位置&#xff0c;以便卫星信号可以顺利接收。确保安装位置可靠稳定&#xff0c;没有物体遮挡。 2.安装支架&#xff1a;根据选定的位置&#xff0c;安装接收机的支架&a…

哪款运动耳机好、好的运动蓝牙耳机推荐

根据美国运动杂志《Runners World》的报道&#xff0c;有实验证据表明&#xff0c;在健身前听一段自己喜欢的音乐可以显著提高肌肉力量和耐力&#xff0c;改善运动表现。快节奏的音乐也可帮助减轻疲劳感&#xff0c;提升锻炼效果。因此&#xff0c;我们可以说音乐可能是运动中最…

基于YOLOv5n/s/m不同参数量级模型开发构建茶叶嫩芽检测识别模型,使用pruning剪枝技术来对模型进行轻量化处理,探索不同剪枝水平下模型性能影响【续】

这里主要是前一篇博文的后续内容&#xff0c;简单回顾一下&#xff1a;本文选取了n/s/m三款不同量级的模型来依次构建训练模型&#xff0c;所有的参数保持同样的设置&#xff0c;之后探索在不同剪枝处理操作下的性能影响。 在上一篇博文中保持30的剪枝程度得到的效果还是比较理…

【解决方法】浏览器连不上网了?扛狼扛狼扛,进来看~

哈喽&#xff0c;木易巷上线啦&#xff01; 今天一大早来到单位&#xff0c;打开笔记本电脑&#xff0c;发现浏览器连不上网&#xff0c;尝试了好多次都是这样的界面。 木易巷点击了下方的【运行Windows网络诊断】 哦豁&#xff0c;显示【远程计算机或设备将不接受连接】 小伙…

第四章,登录注册

目录 4.1 添加注册页面 4.2 注册表单验证 4.3提交注册信息 4.4 完善注册功能 4.5 完善登录功能 4.6 推出用户登录 4.7 用户登录界面 4.8 小结 4.1 添加注册页面 <template><div class="navbar-right"><div class="nav navbar-nav github…

多维时序 | MATLAB实现PSO-CNN-BiGRU多变量时间序列预测

多维时序 | MATLAB实现PSO-CNN-BiGRU多变量时间序列预测 目录 多维时序 | MATLAB实现PSO-CNN-BiGRU多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.多维时序 | MATLAB实现PSO-CNN-BiGRU多变量时间序列预测&#xff1b; 2.运行环境为Matlab20…

kafka 入门到起飞 - 举个栗子一步一步说HW、LEO如何写入

举个简单栗子&#xff0c;如上图 replication.factory 2 副本因子是2一个Leader副本&#xff0c;一个Follower副本初始情况Leader和Follower 副本都是空我们逐步看当producer写入消息时&#xff0c;broker端的副本会做什么&#xff0c;副本的HW和LEO是如何被更新的 步骤一&a…

网上考试系统将会成为提升教育质量的利器

随着信息技术的飞速发展&#xff0c;网上考试系统成为了现代教育的一项重要工具。这种基于网络的考试方式不仅为学校和机构提供了高效管理和评估学生的能力&#xff0c;同时也带来了许多便利和创新。 网上考试系统为学校和机构提供了更高效的管理方式。传统的纸笔考试需要大量…