`
wxyfighting
  • 浏览: 189175 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Web请求异步处理降低依赖风险

 
阅读更多

Author:文初

Emailwenchu.cenwc@alibaba-inc.com

Bloghttp://blog.csdn.net/cenwenchu79

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

问题凸现:

年关到了,商家忙着促销,网站忙着推广,阿里软件的服务集成平台也面临第一次多方大规模的压力考验,根据5.3版本的压力测试结果,估算了一下现有的推广会带来的压力,基本上确定了服务集成平台年底不需要扩容。SA为了保险起见还是通过请求方式来做定时的心跳检测,保证服务集成平台的可靠性。结果旺旺推广开始的第一天,SA的报警短信就在几个忙时段不停的发告警,但是察看生产环境的服务器状况以及应用状况也看不出有什么问题,开始怀疑是否告警机制不是很合理。但几日的访问记录统计报告看过以后,发现了几个问题,首先由于推广是在IM登录时段集中式的推广,因此高峰期比较集中,压力也很大,而告警发生的也是那些时候,再则,发现那些推广使用的API的处理时间比较长,同时还有一些出现了问题,这几天除了服务集成平台告警以外,那些API服务器也在告警,因此可以看出问题应该是由于API提供商响应速度慢而拖累了服务集成平台的处理能力,监控机制在高峰情况下没有得到及时的响应,就认为是服务器已经处于无效状态。其实这类问题在我们现在的应用体系架构中常常出现,现在很少有纯粹“封闭式”应用,对DB的依赖,对存储的依赖,对第三方系统的依赖等等。这也让我回忆到就是前一阵子参加的安全会议中,腾迅的安全技术团队的负责人说起关于安全现在最大的问题就在于第三方合作安全的不受控而引发安全潜在影响。Web应用未尝不是,从最基本的事务处理要小粒度,不要包含第三方依赖到事务中,到心跳检测,容错方案的制定,都已经让我们对这方面的问题有所注意。但是往往这类问题不是局部设计可以看到的,如果没有一个总体架构设计者对于全局的把握以及协调和防范,那么问题出现并且带来的影响将会很大。

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 375.75pt; HEIGHT: 204.75pt" type="#_x0000_t75"><imagedata src="file:///C:/Users/wenchu/AppData/Local/Temp/msohtml1/01/clip_image001.jpg" o:title="Webapp"></imagedata></shape>

早先对于服务集成平台的压力测试主要是在ISP服务“基本正常”的情况下做的,但是这次问题的暴露就要求我们对于这种第三方依赖出现边界问题需要做出一些措施或者改进的设计。

问题分析以及解决方案:

问题原因:

1. Http请求处理的阻塞方式。

2. 后端服务处理时间过长,服务质量不稳定。

3. Web Container接受请求线程资源有限。

解决方案:

1. 改阻塞方式为非阻塞方式处理请求。

2. 设置后端超时时间,主动断开连接,回收资源。

3. 修改容器配置,增加线程池大小以及等待队列长度。

解决方案一是最难做到的,后面的篇幅讲描述对于这方面技术的探索。

解决方案二比较容易,允许各个ISP设置自己API容许的最大超时时间。

解决方案三TomcatJBossConnector中有两个参数配置(maxThreadsacceptCount)可以做调整。

第一个方案其实和Jdk1.5支持的NIO就是一种想法,只是我们在Socket中都已经采用了,而在Http请求处理中要依赖于Web Container开发商的实现所以至今还没有被广泛应用,不过在开源社区已经有用Mina实现的Http协议处理的框架,但是现在的Web应用高效的Web请求处理仅仅是很小的一方面,还有很多类似于安全,缓存,监控等等附加功能也占据着很重要的地位。

Servlet 3规范经过快一年的推广,已经被各大Web Container厂商所接受,Tomcat6JBoss5Jetty7都宣称自己对Servlet3作了较好的支持,而在Servlet3中最广为关注的一个特性就是异步服务处理ServletAsync Servlet),这点也是解决我目前面临问题的最好的手段。

Servlet 3 与服务异步处理:

Servlet 3主要的新特性分成四部分:内嵌式的使用模式,Annotation的支持,Async Servlet的支持,安全提升。内嵌式的使用很早就在Jetty中被实现,也成为Jetty的优势之一,Annotation也只能说是锦上添花的部分,安全暂时没有怎么用到,最关心的还是Async Servlet部分。Async Servlet到底是什么样的概念,这里就大致描述一下在Servlet3规范中的介绍:

1. 支持 Comet(彗星)。最早期Http请求就是无状态的请求和响应,所有的数据一次性在请求后返回给客户端由客户端渲染。后来发展到AJAX,页面的请求和渲染由全局变成了局部。而Comet适合事件驱动的 Web 应用和对交互性和实时性要求很强的应用,通过建立客户端和服务端的长连接通道,在一次请求后可以主动推送服务端数据的变更情况到客户端。长连接建立的策略有两种:Http StreamingHttp Long Polling。前者客户端打开一个单一的与服务器端的 HTTP 持久连接。服务器通过此连接把数据发送过来,客户端增量的处理它们。后者由客户端向服务器端发出请求并打开一个连接。这个连接只有在收到服务器端的数据之后才会关闭。服务器端发送完数据之后,就立即关闭连接。客户端则马上再打开一个新的连接,等待下一次的数据。

2. 支持Suspending a request。通过在ServletRequest中增加suspend,resume,completeHttp请求处理的block模式转变成为not block模式,同时支持对于状态的查询(suspend,resume,timeout)。

3. 请求处理过程中支持事件机制。响应也支持状态查询。

<shape id="图片_x0020_1" style="VISIBILITY: visible; WIDTH: 412.5pt; HEIGHT: 270.75pt" type="#_x0000_t75" o:spid="_x0000_i1026"><imagedata src="file:///C:/Users/wenchu/AppData/Local/Temp/msohtml1/01/clip_image002.emz" o:title=""></imagedata></shape>

图 异步服务请求基本流程

现实中的异步服务处理:

Tomcat 的异步服务处理

这里使用的是Tomcat 6.0.14版本。在Tomcat中对于异步处理描述在Advanced IO中作了说明,主要分成两部分:Comet的支持和异步输出。

Comet的支持作用分成两部分:请求读数据的非阻塞,响应处理的异步执行。前者可以防止在大流量数据上传时在传输过程中信道空闲等待的资源浪费,后者用于在处理请求时,依赖于第三方或者本身处理比较耗时的情况下,悬挂起请求处理线程,提高请求处理能力,完成处理后异步输出结果。

Servlet不再是原来对于几个标准的Http请求类型的方法实现,而是对于事件响应的处理。Comet定义了4个基础的事件:

1EventType.BEGIN:客户端建立起连接时激发的事件,可以用于资源初始化。

2EventType.READ:有数据可以被读入的事件。(熟悉NIO的事件模式应该可以了解)

3EventType.END:请求处理结束时激发的事件,可以用于资源清理。

4EventType.ERROR:当请求处理出现问题时激发的事件。(IO异常,超时等)
还有一些子事件类型,例如超时就属于ERROR的子事件类型,可以在事件处理中更加精确的定位事件类型。

必需的配置:在server.xml中配置如下(红色部分):

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"

connectionTimeout="20000"

redirectPort="8443" />

实际代码范例如下:

//CometProcessor接口必需被实现,一旦实现以后,则该Servlet在配置好以后不会再调用service,get,post等方法的实现。

public class SIPCometTomcatServlet extends HttpServlet implements CometProcessor

{

@Override

//事件处理响应方法实现

public void event(CometEvent event) throws IOException, ServletException

{

if (event.getEventType() == CometEvent.EventType.BEGIN)

{

//设置事件超时时间

event.setTimeout(10 * 1000);

//另起线程处理后台工作,异步返回结果,事件响应将不等待后台处理直接返回

new Handler(event.getHttpServletRequest(),event.getHttpServletResponse()).start();

}

else if (event.getEventType() == CometEvent.EventType.ERROR)

{

//结束事件,回收request,response资源

event.close();

}

else if (event.getEventType() == CometEvent.EventType.END)

{

event.close();

}

}

//另起一个线程异步处理请求。

class Handler extends java.lang.Thread

{

private HttpServletResponse response;

private HttpServletRequest request;

public Handler(HttpServletRequest request,HttpServletResponse response)

{

this.response = response;

this.request = request;

}

@Override

public void run()

{

try

{

String id;

id = request.getParameter("id");

if (id == null)

id = "no id";

Thread.sleep(5000);

PrintWriter pw = response.getWriter();

pw.write(id);

pw.flush();

} catch (Exception e)

{

e.printStackTrace();

}

}

}

}

使用的一些总结:

1. 事件响应框架将服务的请求由完整的一次服务处理切割成为细粒度的多事件处理,为请求多阶段并行处理提供了框架基础。

2. Event对象在事件处理方法结束后就被回收了,但是requestresponse在事件处理完以后还可以继续使用,因此可以看出原来的阻塞式的方式已经可以通过事件的切分成为非阻塞的方式。

3. 没有提供Servlet3中描述suspend,resume,complete方法,无法主动控制request的异步处理。上面的代码可以看出我只使用了Begin方法启动了一个线程,但是由于无法主动地结束请求,因此在向客户端返回数据以后还要等到超时才会结束这次会话。(看了Tomcat的代码,也想模仿close的动作但是由于它使用了protected无法获取封装的request对象,因此无法释放资源)。当然也可以通过客户端配合,由客户端主动发起再次的数据传输激发READ事件来结束会话。这么做对客户端的依赖比较强,同时也增加了客户端的处理复杂度。

4. Tomcat支持异步输出:在APR或者NIO的模式下,Tomcat支持在系统压力增大的时候,支持异步回写大文件数据。

总体上来说实现了部分对于Comet的支持,但是没有对异步服务流程作很好的支持,无法在开发中使用(简单顺畅的使用)。

JBoss的异步服务处理

JBoss 4.2.3版本配置和使用与Tomcat6类似,没有什么差异。

JBoss 5刚刚发布了RC版本,对于异步服务处理作了很大的改动,与Tomcat配置很不同这里具体的说一下JBoss5中的异步服务使用。

JBoss5已经将Tomcat中的Http11NioProtocol给删除了,取而代之的是JBoss自己的servlet包内增加了一个HttpEventServlet接口,这个接口和TomcatCometProcessor类似。

首先,必须配置JBoss内置的Web容器为APR模式,也就是配置jbossweb.sar下面的server.xmlConnector 如下:

<Connector protocol="org.apache.coyote.http11.Http11AprProtocol" port="8080" address="${jboss.bind.address}"

connectionTimeout="2000" redirectPort="8443" />

其次异步服务处理的Servlet必须实现HttpEventServlet接口,接口只有一个方法,就是事件处理方法:public void event(HttpEvent event)事件定义与Tomcat稍有不同,在BEGIN,ERROR,READ,END基础上增加了TIMEOUT,EOF,EVENT,WRITE四个事件,同时去掉了SubType

1. TIMEOUT其实是从原来的ErrorSubType分离出来的,这个方法是在最后一次处理事件到当前时间超过设定的超时时间而被激发的,同时TIMEOUT被激发并不会关闭请求处理流程,必须显示调用事件的close方法才会结束会话。

2. EOF事件将会在客户端主动断连的情况下被触发,就好比IE窗口在请求过程中被关闭就会被触发。

3. EVENT事件在事件对象被调用resume的时候被激发,按照原意应该最好可以附带上一些自定义信息来做一些工作,但是我自己使用过程中还没有发现有什么好的办法可以在事件中附带信息到事件处理中。

4. WRITE方法在调用isWriteReady方法时被激发,可以在网络出现问题或者繁忙的时候异步等待输出。

再则,JBoss的事件对象还支持几个方法来实现异步处理以及Comet机制,方法如下:

1.close方法:表示一次请求处理的结束,会告知客户端没有数据返回了,同时也会激发END事件。

2.setTimeout方法:设置连接超时时间(单位毫秒),计算超时是从最近的事件处理时间开始记录的,如果发生超时,则会激发TIMEOUT事件。

3.isReadReady方法:如果连接有数据可以读取则返回true,如果这个方法返回falseservlet还试图去读去数据,则会阻塞。

4.isWriteReady方法:如果返回true,则连接可以无阻塞的写出数据,如果返回falseservlet必须停止写数据,如果强制写出,则可能会发生IO错误或者会采用异步输出。当客户端的输出通道可用以后,则会激发write事件。

5.suspend方法:suspend连接处理线程直到timeout发生或者resume被调用,实际上意味着servletsuspend以后不再收到READ事件,READ事件将会在后台被不断的激发,除非被suspend.

6.resume方法:会激发event事件,可以利用这个方法来结束异步处理。同时也可以激活因为suspend停止的read事件,同时也可以在resume以后再调用suspend方法。注意,这里未必是要求必须先suspend以后再resume

7.event,request,response在事件响应过程中都可以被使用,但是线程不安全,同时在调用了close以后,request,response资源会被释放,可以通过对event对象做同步来保证线程安全的问题。当READ事件和END事件都发生的时候,首先会完成READ事件,然后再去完成END

具体的实现代码:

public class SIPCometJBossServlet extends HttpServlet implements HttpEventServlet

{

@Override

public void event(HttpEvent event) throws IOException, ServletException

{

switch (event.getType())

{

//will be called at the beginning of the processing of the connection

case BEGIN:

{

event.setTimeout(100 * 1000);//设置超时时间

//event.suspend();//resume之前不必要一定使用suspend

new Handler(event).start();

break;

}

//Error will be called by the container in the case

//where an IO exception or a similar unrecoverable error occurs

case ERROR:

{

event.close();

break;

}

//End may be called to end the processing of the request

case END:

{

//event.close();//可以写也可以不写,因为进入这个方法也就是调用了close方法,起码暂时还不知道有其他什么入口

break;

}

//This indicates that input data is available,

//and that at least one read call can be made without blocking

case READ:

{

break;

}

//The connection timed out according to the timeout value which has been set

//,but the connection will not be closed unless the servlet uses the close method of the event

case TIMEOUT:

{

event.close();//如果不主动关闭,Timeout方法会被循环调用,会话不会结束

break;

}

//The end of file of the input has been reached, and no further data is available

case EOF:

{

event.close();

break;

}

//Event will be called by the container after the resume() method is called,

//during which any operation can be performed, including closing the connection using the close() method.

case EVENT:

{

event.close();//作为resume方法调用后主动释放连接资源的一种手段

break;

}

//Write is sent if the servlet is using the isWriteReady method

case WRITE:

{

break;

}

}

}

class Handler extends java.lang.Thread

{

private HttpEvent event;//event的生命周期已经不限制于事件处理方法,因此随时可以关闭请求处理

private HttpServletResponse response;

private HttpServletRequest request;

public Handler(HttpEvent event)

{

this.event = event;

this.response = event.getHttpServletResponse();

this.request = event.getHttpServletRequest();

}

@Override

public void run()

{

try

{

String id;

id = request.getParameter("id");

if (id == null)

id = "no id";

Thread.sleep(5000);

//危险!!!其实event,response,request都是线程不安全的,因此此时可能response已经被释放,需要同步住event的对象来操作,效率可能会降低

PrintWriter pw = response.getWriter();

pw.write(id);

pw.flush();

event.resume();//发送结束调用resume方法,进入event方法,结束请求处理

} catch (Exception e)

{

e.printStackTrace();

}

}

}

}

使用总结:

1. 对于Servlet描述的异步服务处理有了较好的支持。

2. 事件方法比较丰富,但是对于可定义事件支持不够完善。

3. 对象并发控制需要开发者自己设计,权衡多线程处理的高效以及资源争夺的消耗。

下面对异步服务处理Servlet和普通Servlet做了一下简单的性能测试。

首先我原本想用ab来做一下简单的压力测试即可,但是ab好像对于apr模式下的测试支持的不好,一压就报错(apr_poll: The timeout specified has expired (70007)),也可能是自己不会用吧,因此就自己写了一段测试代码来做测试。

测试场景如下:

两类Servlet都可以设置处理时Hold的时间,来达到消耗连接数的目的。测试客户端可以设置并发多少用户,每个用户发起多少次请求。下表就是测试的结果:

这里设置的是Servlethold1秒钟,APR启动时配置的最大连接数为默认的200个。

客户端设置

普通Servlet总耗时(ms)

异步Servlet总耗时(ms)

普通Servlet单个线程耗时(ms)

异步Servlet单个线程耗时(ms)

100并发线程,每个线程执行1次请求

263866

274430

2638

2744

300并发线程,每个线程执行1次请求

550718

617082

1835

2056

100并发线程,每个线程执行10次请求

1087747

1207920

10877

12079

300并发线程,每个线程执行10次请求

retrying request,connect reject

5193644

retrying request,connect reject

17312

从上表可以看出,就纯粹从处理效率来说,采用事件处理方式在线程切换过程中存在着一定的损失,但是就我们使用异步请求处理的本意来看,对于在高并发下对后端依赖无法避免的性能损耗情况下,异步请求解决了连接耗尽的问题。

最后在来看我在测试过程中用JProfiler来截取的一些线程创建和使用状况:

<shape id="_x0000_i1027" style="WIDTH: 414.75pt; HEIGHT: 331.5pt" type="#_x0000_t75"><imagedata src="file:///C:/Users/wenchu/AppData/Local/Temp/msohtml1/01/clip_image004.jpg" o:title="p1"><font color="#000000" size="3"></font></imagedata></shape>

上图是最初的线程创建情况,还没有任何请求被发送到服务端,因此线程池也没有开任何一个连接。

<shape id="_x0000_i1028" style="WIDTH: 414.75pt; HEIGHT: 331.5pt" type="#_x0000_t75"><imagedata src="file:///C:/Users/wenchu/AppData/Local/Temp/msohtml1/01/clip_image006.jpg" o:title="p2"><font color="#000000" size="3"></font></imagedata></shape>

这是普通的Servlet在压力测试下的线程状况,线程就开到了200最大值,图中由于程序来Hold请求处理线程出现了红色阻塞和黄色等待,同时客户端已经开始出现拒绝连接的错误。下图就是错误的截图:

<shape id="_x0000_i1029" style="WIDTH: 5in; HEIGHT: 4in" type="#_x0000_t75"><imagedata src="file:///C:/Users/wenchu/AppData/Local/Temp/msohtml1/01/clip_image008.jpg" o:title="p3"><font color="#000000" size="3"></font></imagedata></shape>

<shape id="_x0000_i1030" style="WIDTH: 414.75pt; HEIGHT: 323.25pt" type="#_x0000_t75"><imagedata src="file:///C:/Users/wenchu/AppData/Local/Temp/msohtml1/01/clip_image010.jpg" o:title="p4"><font color="#000000" size="3"></font></imagedata></shape>

上图是异步服务处理Servlet在压力测试开始的情况,可以发现它的http线程还是200,但是其他事件处理线程在不断增长。下图已经增长到了3000多个线程。(这里需要注意的就是这种异步处理资源申请没有设置上限,因此对于资源消耗来说也是比较大的,同时要防范攻击性请求造成服务端垮掉)

<shape id="_x0000_i1031" style="WIDTH: 414.75pt; HEIGHT: 323.25pt" type="#_x0000_t75"><imagedata src="file:///C:/Users/wenchu/AppData/Local/Temp/msohtml1/01/clip_image012.jpg" o:title="p5"><font color="#000000" size="3"></font></imagedata></shape>

<shape id="_x0000_i1032" style="WIDTH: 414.75pt; HEIGHT: 323.25pt" type="#_x0000_t75"><imagedata src="file:///C:/Users/wenchu/AppData/Local/Temp/msohtml1/01/clip_image014.jpg" o:title="p6"><font color="#000000" size="3"></font></imagedata></shape>

上图是压力测试结束以后,异步服务事件处理线程都被释放恢复到了初始状态。

后语:

多线程、分布式计算、erlang其实这些编程方式、框架设计、语言都在实现这一个理论,那就是分而治之,多线程是站在单应用的角度去考虑解决方案,分布式计算是在多机协作考虑解决方案,erlang在单机多处理器的角度去考虑解决方案。但彼此的理念都是一样,将能够分割的不相关联的独立任务并行处理,最终实现最优化的处理效果。

对于服务集成平台是否采用这种技术,我自己还没有最终的决定,首先就如上面的测试结果来看,有的还是有失的,其次这种并发异步处理带来的多线程维护控制复杂度,也需要考虑到成本中。Jetty的开发者对于是否将异步服务处理Servlet来交由开发者控制而不是容器本身来控制表示出了反对意见,的却将这样复杂的控制交给开发者来处理会增加开发者的学习成本以及维护成本。
分享到:
评论

相关推荐

    异步依赖关系图:可以遍历异步节点的依赖关系图

    异步依赖图 可以遍历异步节点的依赖关系图。 关于 设计用于在Web应用程序中请求相关数据( )。 每个节点都可以包含一个承诺,该承诺可以进行一些异步操作,例如http请求。 Angular和Vue友好。 受启发 安装 npm ...

    shiro-guice-async-webapp:使用 Apache Shiro 1.2.3、JBoss RestEasy 3 和 Google Guice 3 的 RESTful Web 服务,支持异步 HTTP 请求处理

    shiro-guice-async-webapp 使用 Apache Shiro 1.2.3、JBoss RestEasy 3 和 Google Guice 3 和异步 HTTP 请求处理支持构建 RESTful Web 服务的示例项目。包含的依赖项Servlet 3.1.0 ( ) JBoss RestEasy 3.0.9.Final ...

    RUST web框架axum快速入门教程

    3. 基本概念:了解axum中的基本概念,如路由、请求处理、响应处理等。 4. 实现算法:在axum中实现算法是构建web应用的关键。本节将介绍如何在axum中实现常见的算法,如排序、查找等。 5. 难点解析:在实现算法的过程...

    aardwolf:Aardwolf 是 C# 的异步 HTTP API 服务提供者,不依赖于 ASP.NET 和 IIS

    注意:我并不积极支持这个项目。 请您自己承担风险使用... 向想要编写快速、异步 Web 服务或网站的开发人员公开了一个非常简单且高效的 C# 库。 此时,框架是稳固的并且运行非常高效。 但是,它在功能方面是不完整的。

    第十五届蓝桥杯Web应用试题考察重点

    Vue.js:Vue核心(常用指令、常用模板语法、生命周期、数据渲染、事件绑定、自定义指令、组合式函数、插件等)、Vue组件(组件定义及使用、父子组件、兄弟组件、异步组件、组件插槽、依赖注入等)、vue-router(v4.x...

    atto:单一文件,低依赖性,纯PHP Web服务器等

    Atto是请求事件驱动的,支持Web流量的异步I / O。 与类似PHP软件不同,作为Web或Gopher Server,它实例化了传统PHP超全局变量,例如$ _GET,$ _ POST,$ _ REQUEST,$ _ COOKIE,$ _ SESSION,$ _ FILES等,并努力...

    20步打造最安全的NginxWeb服务器

    跟传统的服务器不同,Nginx不依赖线程来处理请求。相反,它使用了更多的可扩展的事件驱动(异步)架构。Nginx为一些高流量的网站提供动力,比如WordPress,人人网,腾讯,网易等。这篇文章主要是介绍如何提高运行在...

    webshooters:用于开发安全 Java Web 服务的 Web 框架

    ), Jetty 9 推荐) ##特征符合 Java 8 Servlet 3.x 异步请求和过滤器Google Guice 依赖注入Apache Shiro 安全上下文与 JAX-RS 2.x 兼容的 JBoss RestEasy ##用法在你的 pom.xml 中插入这个依赖项: ...

    Actix Web 是一个功能强大、实用且速度极快的 Rust 网络框架。

    Actix网站Actix Web 是一个功能强大、实用且速度极快的 Rust 网络框架特征支持HTTP/1.x和HTTP/2流媒体和流水线保持活动和缓慢的请求处理客户端/服务器WebSockets支持透明内容压缩/解压(br、gzip、deflate)强大的...

    DMJobManager:作业队列系统

    DM 作业管理器 一个简单的库,用于在可以异步处理的队列中管理“作业”,例如 Web 请求。 通常,您希望在用户执行操作后执行 Web 请求。 在许多情况下,如果没有网络连接,您不想阻止用户。 DMJobManager 帮助您对...

    SpringBoot新手学习手册.pdf

    6.2使用AOP统一处理Web请求日志 9 七、 缓存支持 9 7.1注解配置与EhCache使用 9 使用Redis做集中式缓存 9 八、 其他内容 9 8.1、使用@Scheduled创建定时任务 9 8.2、使用@Async实现异步调用 9 8.3、自定义...

    application-insights-best-practics:针对MVC和Web API的Application Insights最佳实践

    1.依赖关系和异步操作与请求不相关 Application Insights的重要功能之一是查看所有遥测,以了解同一操作,这实际上意味着对于Web API操作,每个自定义事件,依赖项,异常,跟踪都应与请求链接。 不幸的是,这在某些

    异步网络控制恒温器:ESP32异步网络控制恒温器

    换句话说,这里的想法是执行来自客户端浏览器的异步请求,以查询要显示的数据状态的微控制器,然后在ESP32提供的数据被获取后立即执行用户界面的本地更新。收到。 有几种技术可以做到这一点,包括WebSockets的使用...

    ASP.NET4高级程序设计(第4版) 3/3

    3.2 Web窗体处理阶段 73 3.2.1 页面框架初始化 74 3.2.2 用户代码初始化 74 3.2.3 验证 74 3.2.4 事件处理 75 3.2.5 自动数据绑定 75 3.2.6 清除 76 3.2.7 页面流示例 76 3.3 作为控件容器的页面 ...

    JQuery基于FormData异步提交数据文件

    我们希望达到一个无刷新的、异步的提交效果来给用户更好的体验,这时候就要使用ajax,ajax可以不依赖表单自行发起一次http请求并且取回服务器响应的数据,这就是ajax的简便之处。我们这里使用JQuery中封装好的ajax...

    httpfetch:用于简单 HTTP 请求的库(使用 RingPHP)

    作为file_get_contents替代品,但具有异步支持、对所有 HTTP 功能的正确支持、请求标头的轻松传递、响应标头的解析以及正确处理 HTTPS 使用的证书。 file_get_contents在没有正确配置的情况下与 HTTPS 一起使用时是...

    ceenhttpd:使用C#编写的轻量级HTTP兼容Web服务器,具有完整的asyncawait实现

    主要特征: 小代码库-简单的代码概述SSL支持-安全连接异步实现-处理大量并发请求没有依赖关系-嵌入到您需要的地方建立在TCP级别上-易于调试包括基本模块-W3C日志和静态文件服务可选模块: REST意识-使用Ceen.Mvc实

    SpringBoot新手学习手册

    6.2使用AOP统一处理Web请求日志 32 6.3Spring Boot集成lombok让代码更简洁 33 七、 缓存支持 35 7.1注解配置与EhCache使用 35 7.2使用Redis集成缓存 37 八、 热部署 37 8.1 什么是热部署 37 8.2 项目演示案例...

Global site tag (gtag.js) - Google Analytics