Jetty的NIO可以有效地减少请求的线程数,但是对于servlet而言,依然是每个servlet需要一个线程,Continuation的出现有效地解决了servlet中耗时操作占用请求线程的境况。
Continuation用于处理异步请求,可以在请求处理的上下文交给应用线程去处理并挂起当前请求,这样减少了请求线程的数量,最后当应用线程处理完成后恢复该请求。比如使用该功能可以解决ajax长轮询服务端的境况,异步长连接的功能可见一斑。
Jetty8已经将Continuation集成到了整个框架中,虽然目前并没有很大的应用场景,但是了解该功能亦能无障碍地阅读Jetty的源码。
Continunation结构
1、Continunation的类图
究其名字就是异步长连接的含义,首先了解下其体系结构
蓝色的留作拓展;红色的是恢复请求的基础;黄色的持有Continunation,拥有每个阶段的状态,因此可以有效地控制请求的流转。
2、Continunation的状态
01 | private static final int __IDLE= 0 ; // Idle request |
02 | private static final int __DISPATCHED= 1 ; // Request dispatched to filter/servlet |
03 | private static final int __ASYNCSTARTED= 2 ; // Suspend called, but not yet returned to container |
04 | private static final int __REDISPATCHING= 3 ; // resumed while dispatched |
05 | private static final int __ASYNCWAIT= 4 ; // Suspended and parked |
06 | private static final int __REDISPATCH= 5 ; // Has been scheduled |
07 | private static final int __REDISPATCHED= 6 ; // Request redispatched to filter/servlet |
08 | private static final int __COMPLETING= 7 ; // complete while dispatched |
09 | private static final int __UNCOMPLETED= 8 ; // Request is completable |
10 | private static final int __COMPLETED= 9 ; // Request is complete |
图中不同颜色对应这请求不同的流程,理解该图对于本节的总结至关重要。
1)蓝色的表示正常请求流程
2)红色的表示请求被挂起,并交出线程
3)橙色的表示请求先是被挂起,交出线程前,又被resume恢复了,因此会重复被server去handle。
4)黑色的表示被挂起的请求在调用resume或者超时的情况下被重新恢复。
5)绿色有两层涵义:线程挂起后交出线程前和交出线程之后。可以看到,无论哪种情况走的流程都是一样的。但是区别于resume,complete正如其含义:“完成,结束”,请求是不会再次被递交给server去执行的,因此只适用于交出线程前需要提前结束的时候调用(交出线程之后就算超时了被再次调用也不会被server去执行,因此没有意义)
6)为了简要,图中状态图并不全,但是对于理解Continunation已经足够了。