前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手写服务器笔记记录与tomcat相关笔记(无源码)

手写服务器笔记记录与tomcat相关笔记(无源码)

作者头像
devi
发布2021-08-19 14:58:54
4130
发布2021-08-19 14:58:54
举报
文章被收录于专栏:搬砖记录搬砖记录搬砖记录

目录

1. 前言

阅读之前,请先理解以下概念:

  • web服务器:如tomcat,它是web应用的载体。由于我们平时老是说“客户端与服务端进行交互”,然后容易误以为我们写的web应用就是服务器,这种理解是错误的。web服务器相当于一个容器,装载着我们写的web应用,与浏览器进行交互的是web服务器,处理逻辑的是我们的web应用。
  • webApp(web应用):
  • servlet:web应用中处理业务逻辑的类(或者说处理request返回response的类)
  • HTTP:这个自行百度,主要理解三次握手、请求与响应

2. 逻辑推导

从已有知识推导服务器逻辑: start–>

  1. 浏览器与服务器直接通过HTTP协议进行数据传输==》
  2. HTTP协议分为请求报文和响应报文,浏览器发送请求报文,服务器返回响应报文==》
  3. 请求报文中关键数据包括:请求路径(统一资源定位符),请求体(发送的数据包);响应报文中关键数据包括:响应体(响应的数据包)==》
  4. 所以,大概逻辑如下==》
  5. 浏览器通过IO流发送请求资源路径和请求数据包给服务端==》
  6. 服务端获取IO流,得到请求路径和请求数据包==》
  7. 根据请求路径找到对应的请求资源,并处理响应的数据包==》
  8. 将上述过程的结果封装到响应体中,通过IO流返回。

end<–

3. 关键问题:

  1. 如何利用统一资源定位符找到对应的服务器资源?
  2. IO流传输的是字节流,html页面最终是怎样渲染到浏览器的?

回答: 如果是静态的html页面,则直接根据uri找到服务器中的静态页面,然后通过IO流返回。 直接返回的是字符串,这个解析过程,只要带上对应的响应协议,浏览器会自动渲染。

4. servlet

问:如果是xxx.html结尾,显然只需要读取服务器html资源然后响应即可,但是对于?username=xx&psw=xxx这样的uri,需要业务逻辑来处理,该如何解决?

答:显然,这种写法也是HTTP规范之一,因此,也可以通过遵守规范而正确解析。服务器只做转发功能(web),而逻辑功能,则是服务来完成(webApp),这类webApp,就是servlet。(server Applet的缩写) 关键逻辑如下:

  1. 浏览器发送的/project/login?username=xx&psw=xxx,到达web服务器
  2. web服务器根据HTTP协议,首先解析uri问号的前半部分/project/login,然后建立uri与servlet的映射关系(这就是web.xml的由来),并通过解析web.xml反射得到servlet,然后解析得到参数键值对并封装到request中(同时初始化响应的response请求头,避免由webApp来拼接响应头协议)
  3. 通过servlet.service(request,response)调用webapp中的servlet,执行相关的do方法。

关键知识: 这里面有两大规范:HTTP协议、servlet规范 HTTP协议制定浏览器与服务器之间的交互规则,体现在HTTP请求与HTTP响应上。 servlet规范制定了服务器与webApp之间的交互规则。体现在:webApp的servlet实现servlet规范,然后在web服务器中,直接通过servlet接口调用具体实现。

5. 问题思考

为什么需要web.xml文件(或者相关的注解)? web.xml文件中定义了uri与servlet的映射关系,如果不在配置文件中定义,那就只能在web服务器启动类的解析过程中预先定义所有uri与servlet的关系映射,这显然不可能。只能通过反射获取。

6. 图解与说明

在这里插入图片描述
在这里插入图片描述
  1. 端口开发JDK 的ServerSocket已提供相应方法
  2. socket网络编程主要包含端口监听、请求监听、解析输入流得到请求、构建输出流进行响应。
  3. 线程调度器即线程池,每个请求都会从池中拿一个线程进行执行,可以用ExecutorService创建
  4. servlet需要解析web.xml文件得到url与servlet映射关系,然后解析浏览器传递过来的url,用反射获取对应的servlet进行执行。

7. 优化

servlet缓存池

如果解析完url之后就直接根基web.xml中的映射关系反射获取servlet,这样必定出现servlet爆炸(每个相同的url都会创建一个servlet)。 因此需要建立一个servlet缓存池。 逻辑: 维护一个url:servlet缓存池。 请求过来之后,先从池中拿,拿不到,再反射创建一个,同时放到池中。

servlet线程安全

对于相同的url,servlet都是同一个,即会有多个用户同时使用同一个servlet对象的情况,自然可能存在线程安全。

一般只用一种方式进行规范,那就是不要定义会变化的servlet的成员变量。 非要使用的话,请用TheadLocal

8. 应用联想

springmvc的dispatchservlet也是一个servlet,只不过他不直接处理请求与响应,而是做请求与响应的中转站。

在这里插入图片描述
在这里插入图片描述

springboot中的web开发,controller也有线程安全问题,原因与servlet相同,解决办法也相同。

9. 推荐阅读

TomCat架构分析

Tomcat连接器

Tomcat配置文件详解(配置文件基本展现了Tomcat的架构,建议重视)

servlet工作原理

另外,还可以打开百度图片,搜索 “tomcat架构图” “tomcat时序图” 等图。

10. 关键信息记录

  1. 在初始化过程中,tomcat大量使用观察者模式,以便于实现链式初始化
  2. 容器层级之间基于pipeline(管道)和valve(阀门)的形式处理request(类似过滤器、责任链)相当于提供了可在每层容器之间设置过滤器的功能
  3. tomcat没有遵循双亲委派类加载机制,而是自定义类加载顺序。原因:tomcat本身是一个java程序(即便它运行着多个不同的java项目),如果还是按照双亲委派,则多个不同的项目可能发生冲突,比如说不同项目中相同的类名。因此,基本要求就是不同的webapp应该用各自不同的类加载器。 (延伸阅读
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-06-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 1. 前言
  • 2. 逻辑推导
  • 3. 关键问题:
  • 4. servlet
  • 5. 问题思考
  • 6. 图解与说明
  • 7. 优化
    • servlet缓存池
      • servlet线程安全
      • 8. 应用联想
      • 9. 推荐阅读
      • 10. 关键信息记录
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档