无第三方框架架调用接口超时无法渲染,调用的无第三方框架架,怎么优化

《Spring实战》是学习Spring框架的一本非常經典的书籍之前阅读了这本书,只是在书本上写写画画最近整理了一下《Spring实战》的读书笔记,通过博客的方式进行记录分享俗话说,好记性不如烂笔头把学习到的知识记录下来,方便温故知新让更多的读者可以学习到有关Spring框架的知识。

《Spring实战》读书笔记-第3章 高级裝配

《Spring实战》读书笔记-第6章 渲染Web视图

    Spittr应用在两个地方需要文件上传当新用户注册应用的时候,我们希望他们能够上传一张图片从而与怹们的个人信息相关联。当用户提交新的Spittle时除了文本消息以外,他们可能还会上传一张照片

    对于传送二进制数据,如上传图片与典型的基于文本的表单提交有所不同,multipart格式的数据会将一个表单拆分为多个部分(part)每个部分对应一个输入域。在一般的表单输入域中咜所对应的部分中会放置文本型数据,但是如果上传文件的话它所对应的部分是二进制,下面展示了multipart的请求体:

    在这个multipart的请求中我们鈳以看到profilePicture部分与其他部分明显不同。除了其他内容以外它还有自己的Content-type头,表明它是一个JPEG图片尽管不一定那么明显,但profilePicture部分的请求体是②进制数据而不是简单的文本。

    在编写控制器方法之前我们必须要配置一个multipart解析器,通过它来告诉DispatcherServlet该如何读取multipart请求

    StandardServletMultipartResolver没有构造器参数,也没有要设置的属性这样,在Spring应用上下文中将其声明为bean就会非常简单,如下所示:

    如果想配置StrandardServletMultipartResolver的限制条件不在Spring中配置,而是要在ServletΦ指定multipart的配置至少,我们必须要指定在文件上传的过程中所写入的临时文件路径。如果不设定这个最基本配置的话就无法正常工作叻。具体来讲我们必须要在web.xml或Servlet初始化类中,将multipart的具体细节作为DispatcherServlet配置的一部分

    • 上传文件的最大容量(以字节为单位)。默认是没有限制嘚
    • 整个multipart请求的最大容量(以字节为单位),不会关心有多少个part以及每个part的大小默认是没有限制的。
    • 在上传的过程中如果文件大小达箌了一个指定最大容量(以字节单位),将会写入到临时文件路径中默认值为0,也就是所上传的文件都会写入到磁盘上

    例如,假设我們想限制文件的大小不超过2MB整个请求不超过4MB,而且所有的文件都要写到磁盘中下面的代码使用MultipartConfigElement设置了这些临界值:

    在这里,我们将最夶的文件容量设置为2MB最大的内存大小设置为0字节,表明不能上传超过2MB的文件并不管文件的大小如何,所有的文件都会写到磁盘中但昰与MultipartConfigElement有所不同,我们无法设定multipart请求整体的最大容量

    要实现控制器方法来接收上传的文件,最常见的方式就是在某个控制器方法参数上添加@RequestPart注解

    假设我们允许用户在注册Spittr应用的时候上传一张图片,那么我们需要修改表单以允许用户选择要上传的图片,同时还需要修改SpitterController中嘚processRegistration() 方法来接收上传的图片如下的代码片段来源于JSP注册表单视图:

    除了注册表单中已有的输入域,我们还要添加了一个新的<input>域其type为file。这能够让用户选择要上传的图片文件accept属性用来将文件类型限制为JPEG、PNG以及GIF图片。根据其name属性图片数据将会发送到multipart请求中的profilePicture part之中。

    现在我们需要修改processRegistration()方法使其能够接受上传的图片。其中一种方式是添加byte数组参数并为其添加@RequestPart注解。如下为示例:

    当注册表单提交的时候profilePicture属性將会给定一个byte数组,这个数组中包含了请求中对应part的数据(通过@RequestPart指定)如果用户提交表单的时候没有选择文件,那么这个数组会是空(洏不是null)获取到图片数据后,processRegistration() 方法剩下的任务就是将文件保存到某个位置

    使用上传文件的原始byte比较简单但是功能有限。因此Spring还提供叻MultipartFile接口,它为处理multipart数据提供了内容更为丰富的对象如下的程序清单展示了MultipartFile接口的概况。

    它提供了获取上传文件byte的方式还能获得原始的攵件名、大小以及内容类型。它还提供了一个InputStream用来将文件数据以流的方式进行读取。

    除此之外MultipartFile还提供了一个便利的transferTo()方法,它能够帮助峩们将上传的文件写入到文件系统中作为样例,我们可以在processRegistration() 方法中添加如下的几行代码从而将上传的图片文件写入到文件系统中:

    其Φ用到的SpitterForm类,如下所示:

    那么将上传的文件写入文件系统中的代码为:

    值得一提的是如果在编写控制器方法的时候,通过Part参数的形式接受文件上传那么就没有必要配置MultipartResolver了。只有使用MultipartFile的时候我们才需要MultipartResolver。

    不管发生什么事情不管是好的还是坏的,Servlet请求的输出都是一个Servlet响應如果在请求处理的时候,出现了异常那它的输出依然会是Servlet响应。异常必须要以某种方式转换为响应

    Spring提供了多种方式将异常转换为響应:

    • 特定的Spring异常将会自动映射为指定的HTTP状态码;
    • 异常上可以添加@ResponseStatus注解,从而将其映射为某一个HTTP状态码;
    • 在方法上可以添加@ExceptionHandler注解使其用來处理异常。

    将异常映射为HTTP状态码

    在默认情况下Spring会将自身的一些异常自动转换为合适的状态码。下表列出了这些映射关系

    对于应用所拋出的异常,这些内置的映射就无能为力了幸好,Spring提供了一种机制能够通过@RequestStatus注解将异常映射为HTTP状态码。

    为了阐述这项功能请参考SpittleController中洳下的请求处理方法,它可能会产生HTTP 404状态(但目前还没有实现):

    对于@ExceptionHandler注解标注的方法来说比较有意思的一点在于它能处理同一个控制器中所有处理器方法所抛出的异常。所有我们不用在每一个可能抛出DuplicateSpittleException的方法中添加异常处理代码,这一个方法就涵盖了所有的功能

    7.4 为控制器添加通知

    如果控制器类的特定切面能够运用到整个应用程序的所有控制器中,那么这将会便利很多举例说明,如果要在多个控制器中处理异常那@ExceptionHandler注解所标注的方法是很有用的。不过如果多个控制器类中都会抛出某个特定的异常,那么你可能会发现要在所有的控淛器方法中重复相同的@ExceptionHandler方法或者,为了避免重复我们会创建一个基础的控制器类,所有控制器类要扩展这个类从而继承通用的@ExceptionHandler方法。

    Spring 3.2为这类问题引入了一个新的解决方案:控制器通知 控制器通知(controller advice)是任意带有@ControllerAdvice注解的类,这个类会包含一个或多个如下类型的方法:

    茬带有@ControllerAdvice注解的类中以上所述的这些方法会运用到整个应用程序所有控制器中带有@RequestMapping注解的方法上。

    @ControllerAdvice最为实用的一个场景就是将所有的@ExceptionHandler方法收集到一个类中这样所有控制器的异常就能在一个地方进行一致的处理。例如我们想将DuplicateSpittleException的处理方法用到整个应用程序的所有控制器上。

    在处理完POST请求后通常来讲一个最佳实践就是执行一下重定向。除了其他的一些因素外这样做能够防止用户点击浏览器的刷新按钮或後退箭头时,客户端重新执行危险的POST请求

    “redirect:”前缀能够让重定向功能变得非常简单。Spring为重定向功能还提供了一些其他的辅助功能

    一般來讲,当一个处理器方法完成之后该方法所指定的模型数据将会复制到请求中,并作为请求中的属性请求会转发(forward)到视图上进行渲染。因为控制器方法和视图所处理的是同一个请求所以在转发的过程中,请求属性能够得以保存

    但是,当控制器的结果是重定向的话原始的请求就结束了,并且会发起一个新的GET请求原始请求中所带有的模型数据也就随着请求一起消亡了。在新的请求属性中没有任哬的模型数据,这个请求必须要自己计算数据

    显然,对于重定向来说模型并不能用来传递数据。但是我们也有一些其他的方案能够從发起重定向的方法传递数据给处理重定向方法中:

    • 使用URL模板以路径变量和/或查询参数的形式传递数据;
    • 通过flash属性发送数据。

    通过URL模板进荇重定向

    通过路径变量和查询参数传递数据看起来非常简单例如

    这能够正常运行,但是还远远不能说没有问题当构建URL或SQL查询语句的时候,使用String连接是很危险的

    除了连接String的方式来构建重定向URL,Spring还提供了使用模板的方式来定义重定向URL例如

    现在,username作为占位符填充到了URL模板Φ而不是直接连接到重定向String中,所以username中所有的不安全字符都会进行转义这样会更加安全,这里允许用户输入任何想要的内容作为username并會将其附加在路径上。

    除此之外模型中所有其他的原始类型值都可以添加到URL中作为查询参数。作为样例假设除了username以外,模型中还要包含新创建Spitter对象的id属性那processRegistration()方法可以改为如下写法:

    所返回的重定向String并没有太大的变化。但是因为模型中的spitterId属性没有匹配重定向URL中的任何占位符,所以它会自动以查询参数的形式附加到重定向URL上

    如果在重定向的时候,需要实际发送对象例如前面的例子中,我们需要重定姠的时候传递Spitter对象Spitter对象要比String和int更为复杂。因此我们不能想路径变量或查询参数那么容易地发送Spitter对象。

    正如我们前面讨论的那样模型數据最终是以请求参数的形式复制到请求中的,当重定向发生的时候这些数据就会丢失。因此我们需要将Spitter对象放到一个位置,使其能夠在重定向的过程中存活下来

    有个方案是将Spitter放到会话中,Spring也认为将跨重定向存活的数据放到会话中是一个很不错的方式但是,Spring认为我們并不需要管理这些数据相反,Spring提供了将数据发送为flash属性(flash attribute)的功能 按照定义,flash属性会一直携带这些数据直到下一次请求然后才会消失。

    在这里我们调用了addFlashAttribute() 方法,并将spitter作为keySpitter对象作为值。另外我们还可以不设置key参数,让key根据值的类型自行推断得出:

    在重定向执行の前所有的flash属性都会复制到会话中。在重定向后存在会话中flash属性会被取出,并从会话转移到模型之中处理重定向的方法就能从模型Φ访问Spitter对象了,就像获取其他的模型对象一样下图阐述了它是如何运行的

    flash属性保存在会话中,然后再放到模型中因此能够在重定向的過程中存活

    为了完成flash属性的流程,如下展现了更新版本的showSpitterProfile()方法在从数据库中查找之前,它会首先从模型中检查Spitter对象:

    方法所做的第一件倳就是检查是否存有key为spitter的model属性如果模型中包含spitter属性,那就什么都不用做了这里面包含的Spitter对象将会传到视图中进行渲染。但是如果模型Φ不包含spitter属性的话那么showSpitterProfile()将会从Repository中查找Spitter,并将其存放到模型中

    在Spring中,总是会有“还没有结束”的感觉:更多的特性、更多的选择以及实現开发目标的更多方式Spring MVC有很多功能和技巧。

    当然Spring MVC的环境搭建是有多种可选方案的一个领域。在本章中我们首先看了一下搭建Spring

    然后,峩们了解了如何处理Spring MVC控制器所抛出的异常尽管带有@RequestMapping注解的方法可以在自身的代码中处理异常,但是如果我们将异常处理的代码抽取到单獨的方法中那么控制器的代码会整洁得多。

    为了采用一致的方式处理通用的任务包括在应用的所有控制器中处理异常,Spring 3.2引入了@ControllerAdvice它所創建的类能够将控制器的通用行为抽取到同一个地方。最后我们看了一下如何跨重定向传递数据,包括Spring对flash属性的支持:类似于模型的属性但是能在重定向后存活下来。这样的话就能采用非常恰当的方式为POST请求执行一个重定向回应,而且能够将处理POST请求时的模型数据传遞过来然后在重定向后使用或展现这些模型数据。

    如果你还有疑惑的话那么可以告诉你,这就是我所说的“更多的功能”!其实我們并没有讨论到Spring MVC的每个方面。我们将会在第16章中重新讨论Spring MVC到时你会看到如何使用它来创建REST API。

    但现在我们将会暂时放下Spring MVC,看一下Spring Web Flow这是┅个构建在Spring MVC之上的流程框架,它能够引导用户执行一系列向导步骤

    本文由来源 ,由 system_mush 整理编辑其版权均为 1 所有,文章内容系作者个人观點不代表 Java架构师必看 对观点赞同或支持。如需转载请注明文章来源。

}

成 web-view ul、li没有了都用view替代 audio 不再推荐使用,改成api方式背景音频api文档其实老HTML标签也可以在uni-app里使用,uni-app编译器会在编译时把老标签转为新标签但不推荐这种用法,调试H5端时容噫 ...

一个发布云平台上当时选择它主要考虑几个方面,一是本人是C++,iOS开发对JAVA不懂又不想学;二是学好JS就即可做后端又可做前端;三是拿它做接口api高效,性能好;四是开发环境搭起来很简单部署也很简单。刚开始用它重写了整个云平台api供APP ...

存储但是,下面是MongoDB 真正适合於Node.js 套件一些原因 针对文档:因为MongoDB 是针对文档,数据在数据库中存储格式接近于你将在服务器端和客户端脚本中处理它们格式這消除了把数据从行转换为对象和转换回来需要

1.前言 因为公司业务需要在自己私有云服务器上添加添加WebSsh终端,同时提供输入命令审计功能. 从google上可以了解到xterm.js是一个非常出色web终端库,包括VSCode很多成熟产品都使用这个前端库. 1.前言 因为公司业务 ...

模块内代码。require函数让你能够随时去依赖一个模块即取得模块引用,从而即使模块没有作为参数定义也能够被使用。他风格是依赖注入比如: /api.js define('myMoudle',['foo',' ...

等等。 [attachment=87505] [attachment=87506] 除此之外通過查看性能表现差第三方 API、Web Services、内存使用量等性能数据,还能够帮助你快速定位性能瓶颈;通过事务深度 Traces 记录协助你完成应用性能管悝从抽象到具象追溯过程。如果你想对 Node.js 应用性能进行优化话可以点击这里进行下载,免费试用一下! ...

因此仅有一个好参考还鈈够,下面再试图展开去讨论一些更细节问题 Document well 写详细文档 写详细文档,并保持更新 关于这一点,其实无需赘述现实是,很多API设计和维护者不重视文档工作

  好程序员技术文档HTML5开发中js创建和继承,JavaScript对每个创建对象都会设置一个原型,指向它原型对象  当我们用obj.xxx访问一个对象属性时,JavaScript引擎先在当前对象上查找该属性如果没有找到,就到其原型对象 ...

高效Node.js特别适合于web应用或API服务器,例如手机上APP如果它服务器端采用Node.js来搭建,整体开发效率会提高很多倍而且也非常适合IoT服务端应用。 [attachment=107120] 图一 Node.js和APM

公司想做个微应鼡接入自己请假系统事实上这个微应用url也是要走企业鉴权流程,现在想做免登就是不需要再登陆企业登陆系统,建议怎么做 现在是建议使用js-api吗?我有个疑问js-api是加载了H5之后才能调用,但是企业鉴权是申请这个H5时候就要了啊到底流程是怎样? ...

servername这方媔要很小心,设置错一点都可能导致你整个备份流程都无法实现 Sybase api与tsm api联用方面: 注意用sybase用户去备份东西要用sybase用户去查询,而用root用户去备份东西要用root用户去查询因为,用户A备份东西用户B是看不到 接口, 在线, 备份, SYBASE, 文档 ...

。 想找到关于如何开发一款真正区块链产品(不只昰调用某款加密货币API图书吗这可能是目前世界上第一本,也可能是唯一一本 想找到关于Node.js大型实践项目图书吗?这可能是世界仩少有一本也可能找不到第二本。 想找到亿书、Lisk等基于 ...

}

原标题:深入剖析通信层和 RPC 调用嘚异步化:应用场景、实践及技术难点

《Netty 进阶之路》、《分布式服务框架原理与实践》作者李林锋深入剖析通信层和 RPC 调用的异步化李林鋒在 InfoQ 上开设了 Netty 专题持续出稿,感兴趣的同学可以持续关注后台回复关键词:Netty,可以获取专栏链接

异步 RPC 调用的应用场景

随着业务分布式架构的发展,系统间的系统调用日趋复杂以电商的商品购买为例,前台界面的购买操作涉及到底层上百次服务调用形成复杂的调用链,示例如下:

图 1 分布式消息调用链

对于一些逻辑上不存在互相依赖关系的服务可以通过异步 RPC 调用,实现服务的并行调用通过并行调用來降低服务调用总耗时,以手游购买道具流程为例消费次数限制鉴权、账户余额鉴权和下载记录鉴权三个服务可以通过异步的方式并行調用,来降低游戏道具购买的耗时:

图 2 购买道具异步 RPC 调用流程

服务调用耗时波动较大场景

对于一些业务场景服务调用耗时与消息本身、調用的资源对象有关系,例如上传和下载接口如果下载的资源较多则耗时就会相应的增加。对于这类场景接口的调用超时时间比较难配置,如果配置过大服务端自身响应慢之后会拖垮调用方,如果配置过小万一遇到一个需要较长耗时的 RPC 调用就会超时。通过异步 RPC 调用就不用再担心调用方业务线程被阻塞,超时时间可以相应配置大一些减少超时导致的失败。

对于大部分的第三方服务调用都需要采鼡防御性编程,防止因为第三方故障导致自身不能正常工作如果采用同步 RPC 方式调用第三方服务,一旦第三方服务的处理耗时增加就会導致客户端调用线程被阻塞,当超时时间配置不合理时系统很容易被阻塞。通过异步化的 RPC 调用可以防止被第三方服务端阻塞,Hystrix 的第三方故障隔离就是采用类似机制只不过它底层创建了线程池,通过 Hystrix 的线程池将第三方服务调用与业务线程做了隔离实现了非侵入式的故障隔离。

对于一个同步串行化调用的系统大量的业务线程都在等待服务端返回响应,系统的 CPU 使用率很低但是性能却无法有效提升,这個问题几乎是所有采用同步 RPC 调用的业务都遇到的一个通病要想充分利用 CPU 资源,需要让业务线程尽可能的跑满 CPU而不是经常性的处于同步等待状态。采用异步 RPC 调用之后在单位时间内业务线程可以接收并处理更多的请求消息,更充分的利用 CPU 资源提升系统的吞吐量。

根据一些公开的测试数据一些业务采用异步 RPC 替换同步 RPC 调用之后,综合性能提升 2-3 倍 +

异步 RPC 调用实践

点一下好看试试微信的新功能??

}

我要回帖

更多关于 无第三方框架 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信