背景
创新互联建站专注为客户提供全方位的互联网综合服务,包含不限于网站建设、网站设计、忻城网络推广、微信小程序开发、忻城网络营销、忻城企业策划、忻城品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联建站为所有大学生创业者提供忻城建站搭建服务,24小时服务热线:13518219792,官方网址:www.cdcxhl.com
在之前的一次性能压测的时候我们发现一个细节问题,我们使用 spring boot 创建的 web rest 项目,使用默认 spring mvc 作为 web rest 框架。
这在使用上没有太大问题,但是有一个影响性能的细节问题被发现了,说实话这个问题很难被发现。
spring boot创建的默认spring mvc项目
我们来看一个简单的 demo ,我使用 IDEA 创建一个 spring boot 项目,创建过程中没有什么特别的选项需要调整,一路 next 。然后我们创建一个简单的 controller 。
- package springboot.demo.controller;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- import springboot.demo.model.User;
- /**
- * Created by plen on 2017/11/25.
- */
- @RestController
- public class SpringMvcController {
- @RequestMapping("/user/{id}")
- public User hello(@PathVariable Long id) {
- User user = new User();
- user.setID(id);
- user.setUserName("mvc.");
- return user;
- }
- }
再创建一个简单的 model 。
- package springboot.demo.model;
- import lombok.Data;
- import lombok.EqualsAndHashCode;
- /**
- * Created by plen on 2017/11/25.
- */
- @Data
- @EqualsAndHashCode
- public class User {
- private Long ID;
- private String userName;
- }
然后启动访问这个 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 的方式。
- org.springframework.boot.web.servlet.ServletRegistrationBean
ServletRegistrationBean 可以让我们注册servlet,我们来看下完整代码。
- package springboot.demo.config;
- import org.glassfish.jersey.servlet.ServletContainer;
- import org.glassfish.jersey.servlet.ServletProperties;
- import org.springframework.boot.web.servlet.ServletRegistrationBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.stereotype.Component;
- /**
- * Created by plen on 2017/11/25.
- */
- @Component
- public class JerseyServletBeanConfig {
- @Bean
- public ServletRegistrationBean jerseyServlet() {
- ServletRegistrationBean registrationBean = new ServletRegistrationBean(new ServletContainer(), "/rest/v1/*");
- registrationBean.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyResourceConfig.class.getName());
- return registrationBean;
- }
- }
这和原来在 web.xml 配置的是一样的,设置 routing 地址,设置 Init 初始化参数,对应的 servlet class name 。
所有的 __"rest/v1/*"__ 请求都将被 ServletContainer jersey servlet 容器接管。
- package springboot.demo.config;
- import org.glassfish.jersey.server.ResourceConfig;
- import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
- import springboot.demo.controller.JerseyController;
- /**
- * Created by plen on 2017/11/25.
- */
- public class JerseyResourceConfig extends ResourceConfig {
- public JerseyResourceConfig() {
- register(JerseyController.class);
- register(RequestContextFilter.class);
- }
- }
ResourceConfig其实是一个 jersey Application 类型。这是 __jersey 注册 servlet 时规定的。
- package springboot.demo.controller;
- import springboot.demo.model.User;
- import javax.ws.rs.GET;
- import javax.ws.rs.Path;
- import javax.ws.rs.PathParam;
- import javax.ws.rs.Produces;
- import javax.ws.rs.core.MediaType;
- /**
- * Created by plen on 2017/11/25.
- */
- @Path("/user/")
- public class JerseyController {
- @Path("{id}")
- @GET
- @Produces(MediaType.APPLICATION_JSON)
- public User hello(@PathParam("id") Long id) {
- User user = new User();
- user.setID(id);
- user.setUserName("jersey.");
- return user;
- }
- }
这是我们应用代码 Controller ,使用 JAX-RS 规范的注解进行设置即可。
这样就解决了 sprng mvc 和 jersey rest 共同存在的问题,我们也不需要将所有的返回 chunked 的接口都改成 JAX-RS 的 rest 服务,只需要将有性能瓶颈的接口改造下即可。
名称栏目:容易被忽视的后端服务chunked性能问题
URL链接:http://www.mswzjz.cn/qtweb/news27/127227.html
攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能