`
pxchen
  • 浏览: 85156 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Jetty 7 Continuation 总结

    博客分类:
  • java
阅读更多

最近开始研究jetty 7。已经出到稳定版了。我相信大多JETTY的爱好者已经看过了。
这里呢。对jetty 7的continuation总结一下。

为了做一个server long push的WEB应用。我选择了jetty。对于Jetty,我只能说是一个新手,在网上搜资料的时候,发现相关资料少个可怜,中文的资料都是一个抄一 个,或者就是翻译的。对于jetty我走了弯路。迫使自己看是看jetty的源文件。

大家肯定都知道jetty的 continuation是建立的NIO技术的基础上。使WEB 服务器对大量的HTTP申请做阻塞不必开启过多的线程。避免了浪费。而jetty是将封装好的servlet加入一个等待队列。之后做轮询。哪个满足条 件。就调用用户的方法去操作response。

刚开始作为一个第一次用jetty的人,我把suspend/complete和 suspend/resunme产生了一个错误的理解。我以为这个方法只是阻塞申请。于是我建立了一个方法。里面做了一个循环去判断某个值,如果存在就反 馈并complete。而最后发现jetty自带了遍历的功能。不用你去写循环。
正确的写法如下:

//判断applition中是否有msg有的话反馈,没有的话就阻塞。
protected void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
//得到applition对象
ServletContext applition = getServletConfig().getServletContext();
//获取continuation
Continuation continuation = ContinuationSupport.getContinuation(request);
//设定超时时间、可以不设置。默认为30秒
continuation.setTimeout(0);
//阻塞
continuation.suspend();
//如果applition中有msg这个字符。开放阻塞
if(applition.getAttribute("msg").toString() != null){
continuation.complete();
response.getServletResponse().getWriter().print(
applition.getAttribute("msg").toString()
);
}
}


其他你都不用管。服务器会做循环来调用你的serlvet。然后调用你的判断方法做处理。
要注意的一点是:
我做了一个小小的 测试。我挂起了20个长连接去判断自己需求的信息,但是呢。我第一步就给与第9个长连接做判断的对象赋值,按理论上来说,它应该立即反馈的。
错!
它不会反馈给你。因为服务器端对每个客户端挂起的长连接做了限制。代码如下:

package org.eclipse.jetty.continuation;
import java.util.ArrayList;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.ServletResponseWrapper;
class FauxContinuation
implements ContinuationFilter.FilteredContinuation
{
private static final ContinuationThrowable __exception = new ContinuationThrowable();
//这里就是限制你为什么不能一台机器申请挂起多个长连接的原因。
private static final int __HANDLING = 1;
private static final int __SUSPENDING = 2;
private static final int __RESUMING = 3;
private static final int __COMPLETING = 4;
private static final int __SUSPENDED = 5;
private static final int __UNSUSPENDING = 6;
private static final int __COMPLETE = 7;
private final ServletRequest _request;
private ServletResponse _response;
private int _state = 1;
private boolean _initial = true;
private boolean _resumed = false;
private boolean _timeout = false;
private boolean _responseWrapped = false;
private long _timeoutMs = 30000L;
private ArrayList<ContinuationListener> _listeners;
FauxContinuation(ServletRequest request)
{
this._request = request;
}
public void onComplete()
{
if (this._listeners != null)
for (ContinuationListener l : this._listeners)
l.onComplete(this);
}
public void onTimeout()
{
if (this._listeners != null)
for (ContinuationListener l : this._listeners)
l.onTimeout(this);
}
public boolean isResponseWrapped()
{
return this._responseWrapped;
}
public boolean isInitial()
{
synchronized (this)
{
return this._initial;
}
}
public boolean isResumed()
{
synchronized (this)
{
return this._resumed;
}
}
public boolean isSuspended()
{
synchronized (this)
{
switch (this._state)
{
case 1:
return false;
case 2:
case 3:
case 4:
case 5:
return true;
case 6:
}
return false;
}
}
public boolean isExpired()
{
synchronized (this)
{
return this._timeout;
}
}
public void setTimeout(long timeoutMs)
{
this._timeoutMs = timeoutMs;
}
public void suspend(ServletResponse response)
{
this._response = response;
this._responseWrapped = response instanceof ServletResponseWrapper;
suspend();
}
public void suspend()
{
synchronized (this)
{
switch (this._state)
{
case 1:
this._timeout = false;
this._resumed = false;
this._state = 2;
return;
case 2:
case 3:
return;
case 4:
case 5:
case 6:
throw new IllegalStateException(getStatusString());
}
throw new IllegalStateException("" + this._state);
}
}
public void resume()
{
synchronized (this)
{
switch (this._state)
{
case 1:
this._resumed = true;
return;
case 2:
this._resumed = true;
this._state = 3;
return;
case 3:
case 4:
return;
case 5:
fauxResume();
this._resumed = true;
this._state = 6;
break;
case 6:
this._resumed = true;
return;
default:
throw new IllegalStateException(getStatusString());
}
}
}
public void complete()
{
synchronized (this)
{
switch (this._state)
{
case 1:
throw new IllegalStateException(getStatusString());
case 2:
this._state = 4;
break;
case 3:
break;
case 4:
return;
case 5:
this._state = 4;
fauxResume();
break;
case 6:
return;
default:
throw new IllegalStateException(getStatusString());
}
}
}
public boolean enter(ServletResponse response)
{
this._response = response;
return true;
}
public ServletResponse getServletResponse()
{
return this._response;
}
void handling()
{
synchronized (this)
{
this._responseWrapped = false;
switch (this._state)
{
case 1:
throw new IllegalStateException(getStatusString());
case 2:
case 3:
throw new IllegalStateException(getStatusString());
case 4:
return;
case 5:
fauxResume();
case 6:
this._state = 1;
return;
}
throw new IllegalStateException("" + this._state);
}
}
public boolean exit()
{
synchronized (this)
{
switch (this._state)
{
case 1:
this._state = 7;
onComplete();
return true;
case 2:
this._initial = false;
this._state = 5;
fauxSuspend();
if ((this._state == 5) || (this._state == 4))
{
onComplete();
return true;
}
this._initial = false;
this._state = 1;
return false;
case 3:
this._initial = false;
this._state = 1;
return false;
case 4:
this._initial = false;
this._state = 7;
onComplete();
return true;
case 5:
case 6:
}
throw new IllegalStateException(getStatusString());
}
}
protected void expire()
{
synchronized (this)
{
this._timeout = true;
}
onTimeout();
synchronized (this)
{
switch (this._state)
{
case 1:
return;
case 2:
this._timeout = true;
this._state = 3;
fauxResume();
return;
case 3:
return;
case 4:
return;
case 5:
this._timeout = true;
this._state = 6;
break;
case 6:
this._timeout = true;
return;
default:
throw new IllegalStateException(getStatusString());
}
}
}
private void fauxSuspend()
{
long expire_at = System.currentTimeMillis() + this._timeoutMs;
long wait = this._timeoutMs;
while ((this._timeoutMs > 0L) && (wait > 0L))
{
try
{
super.wait(wait);
}
catch (InterruptedException e)
{
break label51:
}
wait = expire_at - System.currentTimeMillis();
}
if ((this._timeoutMs > 0L) && (wait <= 0L))
label51: expire();
}
private void fauxResume()
{
this._timeoutMs = 0L;
super.notifyAll();
}
public String toString()
{
return getStatusString();
}
String getStatusString()
{
synchronized (this)
{
return ((this._state == 4) ? "COMPLETING" : (this._state == 6) ? "UNSUSPENDING" : (this._state == 3) ? "RESUMING" : (this._state == 5) ? "SUSPENDED" : (this._state == 2) ? "SUSPENDING" : (this._state == 1) ? "HANDLING" : new StringBuilder().append("???").append(this._state).toString()) + ((this._initial) ? ",initial" : "") + ((this._resumed) ? ",resumed" : "") + ((this._timeout) ? ",timeout" : "");
}
}
public void addContinuationListener(ContinuationListener listener)
{
if (this._listeners == null)
this._listeners = new ArrayList();
this._listeners.add(listener);
}
public Object getAttribute(String name)
{
return this._request.getAttribute(name);
}
public void removeAttribute(String name)
{
this._request.removeAttribute(name);
}
public void setAttribute(String name, Object attribute)
{
this._request.setAttribute(name, attribute);
}
public void undispatch()
{
if (isSuspended())
{
if (ContinuationFilter.__debug)
throw new ContinuationThrowable();
throw __exception;
}
throw new IllegalStateException("!suspended");
}
}


所以遇到这个问题的朋友不必担心。我使用多台机器测试过。服务器的servlet轮询队列是很长的。但对于单独用户来说只能接受6个 suspend.在发送长连接挂起请求。他们加入到你所处的用户等待列表。当你挂起的6个连接中有一个被释放了。你的第7个连接将被挂起。

之 前用了webbench做压测。

不管你怎么测非阻塞技术的长连接。你都会被jetty拒之门外。。。

就是因为这个做 了限制。这样的限制大大降低对服务器的压力。

分享到:
评论

相关推荐

    jetty-continuation-8.1.8.v20121106-API文档-中文版.zip

    赠送jar包:jetty-continuation-8.1.8.v20121106.jar; 赠送原API文档:jetty-continuation-8.1.8.v20121106-javadoc.jar; 赠送源代码:jetty-continuation-8.1.8.v20121106-sources.jar; 赠送Maven依赖信息文件:...

    jetty-continuation-7.4.2.v20110526.jar

    jetty-continuation-7.4.2.v20110526.jar jetty 服务jar包

    jetty-continuation-8.1.8.v20121106-API文档-中英对照版.zip

    赠送jar包:jetty-continuation-8.1.8.v20121106.jar; 赠送原API文档:jetty-continuation-8.1.8.v20121106-javadoc.jar; 赠送源代码:jetty-continuation-8.1.8.v20121106-sources.jar; 赠送Maven依赖信息文件:...

    jetty相关的全部jar包

    jetty-security-9.4.8.v20171121.jar,jetty-io-9.4.8.v20171121.jar,jetty-continuation-9.4.8.v20171121.jar,jetty-client-9.4.8.v20171121.jar,jetty-jmx-9.4.8.v20171121.jar,jetty-plus-9.4.8.v20171121....

    jetty-continuation-9.2.9.v20150224.jar

    java运行依赖jar包

    Jetty cometd(Continuation)学习笔记

    Jetty cometd(Continuation)学习笔记,自己用的,别人那down的网页

    jetty 8及依赖包

    这个压缩包包含Jetty 8版本的实现及其依赖库,是学习和理解Jetty工作原理,尤其是NIO(非阻塞I/O)和Servlet容器实现的宝贵资源。 Jetty 8在设计时特别强调了性能和可扩展性,它使用了Java NIO(New I/O)API来处理...

    jetty7.4.2

    总结,Jetty 7.4.2是一个针对Servlet 3.0标准的Web服务器,具有高性能、易用和可扩展的特性。对于开发者来说,这是一个理想的选择,尤其适合于需要轻量级、快速部署的Web应用。通过下载并使用jetty-distribution-...

    jetty-continuation-9.2.15.v20160210.jar

    java运行依赖jar包

    jetty-continuation-9.2.17.v20160517.jar

    java运行依赖jar包

    jetty-continuation-7.6.10.v20130312.jar

    java运行依赖jar包

    jetty-continuation-8.1.15.v20140411.jar

    java运行依赖jar包

    jmeter测试相关jar包

    org.eclipse.jetty.continuation_9.1.1.v20140108.jar org.eclipse.jetty.continuation.source_9.1.1.v20140108.jar org.eclipse.jetty.deploy_9.1.1.v20140108.jar org.eclipse.jetty.deploy.source_9.1.1.v...

    jetty-distribution-9.4.12.v20180830

    Jetty由Eclipse基金会维护,是Java社区中的一个重要组件,尤其在嵌入式系统和微服务领域中备受青睐。下面我们将深入探讨Jetty的核心特性、与Tomcat的对比以及如何使用。 1. **Jetty的核心特性** - **轻量级**:...

    jetty-io-8.1.8.v20121106.jar

    Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立...

    jetty-client-9.4.43.v20210629-API文档-中文版.zip

    赠送jar包:jetty-client-9.4.43.v20210629.jar; 赠送原API文档:jetty-client-9.4.43.v20210629-javadoc.jar; 赠送源代码:jetty-client-9.4.43.v20210629-sources.jar; 赠送Maven依赖信息文件:jetty-client-...

    jetty-io-9.4.43.v20210629.jar

    Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立...

    jetty-continuation-8.1.8.v20121106.jar中文-英文对照文档.zip

    注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 ...

    jetty-hightide-8.1.15.v20140411.zip

    7. **IDE Integration**:对于Eclipse和IntelliJ IDEA这样的集成开发环境(IDE),Jetty有专门的插件,便于开发者在IDE内部直接调试和运行Jetty应用。 此压缩包的文件名列表"jetty-hightide-8.1.15.v20140411"暗示...

Global site tag (gtag.js) - Google Analytics