容易被忽视的后端服务 chunked 性能问题

举报
开发者学堂小助 发表于 2017/11/28 10:17:45 2017/11/28
【摘要】 在一次性能压测的时候我们发现一个细节问题,我们使用 spring boot 创建的 web rest 项目,使用默认 spring mvc 作为 web rest 框架。这在使用上没有太大问题,但是有一个影响性能的细节问题被发现了。

背景

在之前的一次性能压测的时候我们发现一个细节问题,我们使用 spring boot 创建的 web rest 项目,使用默认 spring mvc 作为 web rest 框架。

这在使用上没有太大问题,但是有一个影响性能的细节问题被发现了,说实话这个问题很难被发现。

2017-11-28_100539.png

spring boot创建的默认spring mvc项目

我们来看一个简单的 demo ,我使用 IDEA 创建一个 spring boot 项目,创建过程中没有什么特别的选项需要调整,一路 next 。然后我们创建一个简单的 controller 。

2017-11-28_100627.png

再创建一个简单的 model 。

2017-11-28_100819.png

然后启动访问这个 controller ,注意看下返回的 http 信息里多了一个 Transfer-Encoding:chunked 。 Transfer-Encoding:chunked 在 HTTP 协议里的意思是无法计算 Content-Length 长度,需要分块传输。

这是 spring mvc 的默认 complex object 传输方式,如果我们返回的是一个简单的对象就不会有这个问题。

Transfer-Encoding:chunked带来的性能问题就是访问一次数据需要不止一次的 http 请求,而一次 http 请求的成本也是比较大的。

(我没有通过抓包工具来测试具体哪种对象大小需要访问几次,感兴趣的可以自己试下。)

集成JAX-RS规范框架Jersey

解决这个问题两个层面都可以,一种是采用比较粗暴的方式在 servlet 容器层面解决,但是这个会带来一个后果就是当我们计算 complex object 大小的时候会比较复杂而且容易出错,也会影响项目未来的分块传输功能,效果不太好。

还有一种就是在应用层面解决,比较柔性也易于扩展,我们可以集成一个 rest 框架,最好是符合 JAX-RS 规范,本文我们集成 Jersey 框架。

jersey集成如果通过 __@Component_ _ 方式那么 jersey 会默认接管所有的 web servlet 请求处理,所以就需要我们手动的配置专门用来处理 jersey servlet 的容器。

spring boot解决了以前 spring 繁重的配置,提供了 auto config 功能,原来通过 web.xml 配置 servlet 的,现在需要用代码来配置。 spring boot 提供了让我们手动注册 servlet bean 的方式。

2017-11-28_101051.png

ServletRegistrationBean 可以让我们注册servlet,我们来看下完整代码。

2017-11-28_101143.png

这和原来在 web.xml 配置的是一样的,设置 routing 地址,设置 Init 初始化参数,对应的 servlet class name 。

所有的 __"rest/v1/*"__ 请求都将被 ServletContainer jersey servlet 容器接管。

2017-11-28_101324.png

ResourceConfig其实是一个 jersey Application 类型。这是 __jersey 注册 servlet 时规定的。

2017-11-28_101448.png

这是我们应用代码 Controller ,使用 JAX-RS 规范的注解进行设置即可。

这样就解决了 sprng mvc 和 jersey rest 共同存在的问题,我们也不需要将所有的返回 chunked 的接口都改成 JAX-RS 的 rest 服务,只需要将有性能瓶颈的接口改造下即可。


作者:佚名    来源:王清培技术博客

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。