深入拆解Tomcat & Jetty
李号双
eBay技术主管
立即订阅
6067 人已学习
课程目录
已完结 44 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | Java程序员如何快速成长?
免费
模块一 必备基础 (4讲)
01 | Web容器学习路径
02 | HTTP协议必知必会
03 | 你应该知道的Servlet规范和Servlet容器
04 | 实战:纯手工打造和运行一个Servlet
模块二 整体架构 (9讲)
05 | Tomcat系统架构(上): 连接器是如何设计的?
06 | Tomcat系统架构(下):聊聊多层容器的设计
07 | Tomcat如何实现一键式启停?
08 | Tomcat的“高层们”都负责做什么?
09 | 比较:Jetty架构特点之Connector组件
10 | 比较:Jetty架构特点之Handler组件
11 | 总结:从Tomcat和Jetty中提炼组件化设计规范
12 | 实战:优化并提高Tomcat启动速度
13 | 热点问题答疑(1):如何学习源码?
模块三 连接器 (9讲)
14 | NioEndpoint组件:Tomcat如何实现非阻塞I/O?
15 | Nio2Endpoint组件:Tomcat如何实现异步I/O?
16 | AprEndpoint组件:Tomcat APR提高I/O性能的秘密
17 | Executor组件:Tomcat如何扩展Java线程池?
18 | 新特性:Tomcat如何支持WebSocket?
19 | 比较:Jetty的线程策略EatWhatYouKill
20 | 总结:Tomcat和Jetty中的对象池技术
21 | 总结:Tomcat和Jetty的高性能、高并发之道
22 | 热点问题答疑(2):内核如何阻塞与唤醒进程?
模块四 容器 (8讲)
23 | Host容器:Tomcat如何实现热部署和热加载?
24 | Context容器(上):Tomcat如何打破双亲委托机制?
25 | Context容器(中):Tomcat如何隔离Web应用?
26 | Context容器(下):Tomcat如何实现Servlet规范?
27 | 新特性:Tomcat如何支持异步Servlet?
28 | 新特性:Spring Boot如何使用内嵌式的Tomcat和Jetty?
29 | 比较:Jetty如何实现具有上下文信息的责任链?
30 | 热点问题答疑(3):Spring框架中的设计模式
模块五 通用组件 (4讲)
31 | Logger组件:Tomcat的日志框架及实战
32 | Manager组件:Tomcat的Session管理机制解析
33 | Cluster组件:Tomcat的集群通信原理
特别放送 | 如何持续保持对学习的兴趣?
模块六 性能优化 (8讲)
34 | JVM GC原理及调优的基本思路
35 | 如何监控Tomcat的性能?
36 | Tomcat I/O和线程池的并发调优
37 | Tomcat内存溢出的原因分析及调优
38 | Tomcat拒绝连接原因分析及网络优化
39 | Tomcat进程占用CPU过高怎么办?
40 | 谈谈Jetty性能调优的思路
41 | 热点问题答疑(4): Tomcat和Jetty有哪些不同?
结束语 (1讲)
结束语 | 静下心来,品味经典
深入拆解Tomcat & Jetty
登录|注册

02 | HTTP协议必知必会

李号双 2019-05-14
在开始学习 Web 容器之前,我想先问你一个问题:HTTP 和 HTML 有什么区别?
为什么我会问这个问题?你可以把它当作一个入门测试,检测一下自己的对 HTTP 协议的理解。因为 Tomcat 和 Jetty 本身就是一个“HTTP 服务器 + Servlet 容器”,如果你想深入理解 Tomcat 和 Jetty 的工作原理,我认为理解 HTTP 协议的工作原理是学习的基础。
如果你对这个问题还稍有迟疑,那么请跟我一起来回顾一下 HTTP 协议吧。

HTTP 的本质

HTTP 协议是浏览器与服务器之间的数据传送协议。作为应用层协议,HTTP 是基于 TCP/IP 协议来传递数据的(HTML 文件、图片、查询结果等),HTTP 协议不涉及数据包(Packet)传输,主要规定了客户端和服务器之间的通信格式。
下面我通过一个例子来告诉你 HTTP 的本质是什么。
假如浏览器需要从远程 HTTP 服务器获取一个 HTML 文本,在这个过程中,浏览器实际上要做两件事情。
与服务器建立 Socket 连接。
生成请求数据并通过 Socket 发送出去。
第一步比较容易理解,浏览器从地址栏获取用户输入的网址和端口,去连接远端的服务器,这样就能通信了。
我们重点来看第二步,这个请求数据到底长什么样呢?都请求些什么内容呢?或者换句话说,浏览器需要告诉服务端什么信息呢?
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入拆解Tomcat & Jetty 》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(71)

  • 吃饭饭 置顶
    我一直不太理解什么是无状态,restful经常听说是无状态的,是一个概念吗?求解答

    作者回复: 我的理解是REST是一种架构风格:将网络上的信息实体看作是资源,可以是图片、文件、一个服务...资源用URI统一标识,URI中没有动词哦,这是因为它是资源的标识,那怎么操作这些资源呢,于是定义一些动作:GET、POST、PUT和DELETE。通过URI+动作来操作一个资源。所谓的无状态说的是,为了完成一个操作,请求里包含了所有信息,你可以理解为服务端不需要保存请求的状态,也就是不需要保存session,没有session的好处是带来了服务端良好的可伸缩性,方便failover,请求被LB转到不同的server实例上没有差别。从这个角度看,正是有了REST架构风格的指导,才有了HTTP的无状态特性,顺便提一下,REST和HTTP1.1出自同一人之手。但是理想是丰满的,现实是骨感的,为了方便开发,大多数复杂的Web应用不得不在服务端保存Session。为了尽量减少Session带来的弊端,往往将Session集中存储到Redis上,而不是直接存储在server实例上..

    2019-05-13
    1
    33
  • 阿斯蒂芬
    Http的无状态我理解是指不同请求间协议内容无相关性,即本次请求与上次请求没有内容的依赖关系,本次响应也只针对本次请求的数据,至于服务器应用程序为用户保存的状态是属于应用层,与协议是无关的。
    keep-alive表示tcp的连接可以复用,指的是利用已有的传输通道进行http协议内容的传输,省去创建/关闭连接的开销达到提升性能的效果。应用程序其实一般不关心这次Http请求的TCP传输细节,只关心Http协议的内容,因此只要复用tcp连接时做好必要的数据重置,是不算有状态的。

    作者回复: 说的很清楚 👍

    2019-05-13
    76
  • 星辰
    http1.0: 买一个信封只能传送一个来回的信。
    http1.1: keep–alive:买一个信封可以重复使用,但前提是得等到服务端把这个信封送回来。

    作者回复: 优秀👍

    2019-05-13
    32
  • 刘为红
    sessionid是服务端生成的,服务端通过set-cookie放在http的响应头里,然后浏览器写到cookie里,后续每次请求就会自动带上来了,这点感觉讲得不是很清楚

    作者回复: 谢谢指出~

    2019-05-14
    2
    28
  • 老王的老李头
    无状态的协议,使用cookie、session等机制实现有状态的的web。
    无状态是指协议对于事务处理没有记忆功能,对同一个url请求没有上下文关系,每次的请求都是独立的,服务器中没有保存客户端的状态。HTTP协议长连接、短连接实质上是TCP协议的长连接、短连接。长连接省去了较多的TCP建立、关闭操作,减少了浪费,节约时间;短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。
    那为什么HTTP协议会被设计成无状态的呢?http最初设计成无状态的是因为只是用来浏览静态文件的,无状态协议已经足够,也没什么其他的负担。随着web的发展,它需要变得有状态,但是不是就要修改http协议使之有状态呢?是不需要的。因为我们经常长时间逗留在某一个网页,然后才进入到另一个网页,如果在这两个页面之间维持状态,代价是很高的。其次,历史让http无状态,但是现在对http提出了新的要求,按照软件领域的通常做法是,保留历史经验,在http协议上再加上一层实现我们的目的。所以引入了cookie、session等机制来实现这种有状态的连接。

    作者回复: 说的很好很详细👍

    2019-05-14
    26
  • 许童童
    Connection:keep-alive只是建立TCP层的状态,省去了下一次的TCP三次握手,而HTTP本身还是继续保持无状态的特点。
    2019-05-13
    19
  • 微信小助手
    HTTP的无状态性与共用TCP连接发送多个请求之间没有冲突,
    这些请求之间相对独立,唯一的关系可能只有发送的先后顺序关系。
    此外,HTTP/1.1中的长连接依然没有解决 head of line blocking 的问题,
    后面的连接必须等待前面的返回了才能够发送,
    这个问题直到HTTP/2.0采取二进制分帧编码方式才彻底解决。

    作者回复: 👍Tomcat和Jetty都支持HTTP2.0了

    2019-05-13
    1
    17
  • 逍遥哥哥
    老师,您好,现在的web容器都支持将session存储在第三方中间件(如redis)中,为什么很多公司喜欢绕过容器,直接在应用中将会话数据存入中间件中?

    作者回复: 用Web容器的Session方案需要侵入特定的Web容器,用Spring Session可能比较简单,不需要跟特定的Servlet容器打交道。

    这正是Spring喜欢做的事情,它使得程序员甚至感觉不到Servlet容器的存在,可以专心开发Web应用。但是Spring到底做了什么,Spring Session是如何实现的,我们还是有必要了解了解~

    其实它是通过Servlet规范中的Filter机制拦截了所有Servlet请求,偷梁换柱,将标准的Servlet请求对象包装了一下,换成它自己的Request包装类对象,这样当程序员通过包装后的Request对象的getSession方法拿Session时,是通过Spring拿Session,没Web容器什么事了。

    2019-05-14
    1
    15
  • Geek_28b75e
    老师,我们经常说的cookie跨域问题中,跨域是什么概念呢

    作者回复: cookie有两个重要属性:
    domain字段 :表示浏览器访问这个域名时才带上这个cookie
    path字段:表示访问的URL是这个path或者子路径时才带上这个cookie

    跨域说的是,我们访问两个不同的域名或路径时,希望带上同一个cookie,跨域的具体实现方式有很多..

    2019-05-24
    7
  • 二两豆腐
    建立tcp链接是可以理解为先修路 ,每次建立推出链接也就是先把路给修好,路修好之后才能走在这条路上送信(http),keep-alive指的就是需要送信的时候要不要修路,还是在走已经修好的路上去送信,信是一封一封的送,上一封信和下一封信没啥联系,这就是无状态
    2019-05-14
    6
  • 今夜秋风和
    服务端怎么检测这个tcp链接什么时候可以销毁释放?如果一个连接里面处理一个长事物,其他的请求会不会排队等待

    作者回复: 服务端会设置连接超时时间,如果TCP连接上超过一段时间没有请求数据,服务端会关闭这个连接。

    在HTTP1.1中,请求是按顺序排队处理的,前面的HTTP请求处理会阻塞后面的HTTP请求,虽然HTTP pipelining对连接请求做了改善,但是复杂度太大,并没有普及,这个问题在HTTP2.0中得到了解决。

    2019-05-14
    4
  • Royal
    您好!上面提到的引入session是因为cookie存在客户端,有安全隐患;但是session id也是通过cookie由客户端发送到服务端,同样有安全隐患啊?

    作者回复: 是的,虽然敏感的用户信息没有在网络上传输了,但是攻击者拿到sessionid也可以冒充受害者发送请求,这就是为什么我们需要https,加密后攻击者就拿不到sessionid了,另外CSRF也是一种防止session劫持的方式。

    2019-05-13
    4
  • 八百
    老师我有二个问题
    1.如果没请求中没有jsessionid ,每次发起http请求是否都会生成session,如果每次请求都生成session,那么是不是可以作为一个攻击的手段啊,让服务器存在大量session,导致oom
    2.如果我从别人的浏览器中拿到jsessionid,把它放在我自己的请求头中,是不是在服务端对应同一个session,那是不是就可以窃取人家信息了。。

    作者回复: 1. 会不会产生session取决于Web应用如何实现,如果在用户没有登录的情况下调用Request.getSession(true),会产生Session,也就有你说的那个问题。
    2.对的

    2019-05-26
    3
  • 业余草
    这里没有讲,为什么 Tomcat 等要采用 HTTP,为什么不采用其他的一些协议?HTTP 协议的好处是什么?以及扩展到 HTTPS 上!
    2019-05-21
    3
  • 暮色听雨声
    HTTP 的特点是无状态的,多个请求之间是没有关系的,这是不矛盾了么?老师我对这句话不理解呀! 怎么就矛盾了呀。多个HTTP请求之间本来就没有关系呀,关系跟状态怎么就会矛盾呢?

    作者回复: 多个请求之间共用一个TCP连接,是不是会让人觉得它们有关系呢。

    2019-05-13
    1
    3
  • 有所思
    用token机制呢

    作者回复: token比如jwt token本质是个加密的cookie

    2019-08-08
    2
  • Joker
    老师,我这样进行比喻您看看合不合适,原来的http老师,我这样进行比喻您看看合不合适。原来的http/1.0的时期,如果把每次发送http数据包都看成一次送信的过程的话,那么就是每次发送都会新叫一个送信员(也就是新建一个TCP连接)。
    http/1.1的长链接就相当于给了你和服务器和客户端有了专属的随时待命的送信员,你就免去了以前每次都要寻找送信员的过程。
    而http 的无状态我认为就是代表:每次寄信都是用的新的信封。额,这个和评论区上面的那个同学的观点有些差异,还请老师详细说说,谢谢了。
    像cookie这些信息就像在信封表面的那些发信人的地址这些信息。
    虽然设置长连接开启是在应用层的http协议,但是真正起作用的是在传输层的TCP协议。

    作者回复: Joker你好,把TCP连接当做送信员的比喻很形象也很贴切!无状态表示每次寄信都是新的信封,这也是对的,我再多说几句,在服务端看来这些信没有关系的,并且服务端通过阅读这封信就得到了它要的全部信息,不需要从其他地方(比如Session里)来获取这封信的更多上下文信息,服务端就知道怎么处理和回信。

    2019-05-18
    2
  • 唐木儿
    对本期内容,作以下总结:
    1.HTTP是服务器与浏览器之间的数据传输协议,规定了数据传输的格式,与数据如何传输无关。统一的数据格式规范有利于各端交互,而具体的交互方式不是协议做的事!
    2.Cookie是存储在浏览器的信息,Session是存储在服务器端的信息。
    3.浏览器和客户端之间的交互,主要是两个过程:建立连接和数据传输!建立连接需要经过TCP/IP的三次握手!数据传输需要统一按照HTTP协议规定的格式!
    4.关于作者的问题,我认为两者不冲突!HTTP请求的无状态是必然的,HTTP服务器并非为某类状态使用的,而是要适应普适性的请求,因此采用无状态是必然的,要让一个请求专注做自己业务内的事,而不是乱七八糟管一通!而一个服务,各个请求之间又是有联系的,因此需要通过Cookie和Session来把请求联系起来,提供良好的用户体验!我觉得Java里的类和方法设计跟这个是同样的道理,一个类只专注于某个业务,一个方法只专注于某个操作!😂第一次评论,好紧张
    2019-05-15
    2
  • 凌霄
    http是无状态的,理解是没有记忆存储功能,每次的请求都是幂等的,而长连接只是共享了tcp连接,跟java中的池技术一样,避免了重复的开销,节省效率,降低响应时间。
    2019-05-14
    2
  • 郑泽洲
    请教李号双老师,现在流行的token验证机制和session技术相比如何?
    服务器集中维护session;客户端有对应的cookie保存session id,优点是一次登录后就不用输入密码了;但是缺点很多,首先是服务器内存压力大,要来维护session,并且要将session持久化,也有成本;其次是不能动态扩展,另外是存在浪费,比如用于直接关闭了浏览器后只能超时退出。
    token验证机制,反客为主,由客户端来管理和验证session。服务器压力小,相当于颁发了一张证书给客户端,里面规定了这个客户有效登录和超时时间,并有服务器对此的签名,然后服务器就不管了,服务器易于横向扩展,服务器也不需要将其持久化。
    2019-08-04
    1
收起评论
71
返回
顶部