REST API性能比较

标签: rest api 性能 | 发表时间:2014-12-30 22:43 | 作者:tongqingqiu
出处:http://www.iteye.com

REST已然成为最流行的提供外界服务API的方式。同时,随着互联网和物联网的普及,如今的应用需要处理大量并发的请求。因此,开发高性能REST服务已经成为一个成功应用的必备条件。

我这里集中讨论Java和JVM相关技术。基于Java的REST应用比基于python和ruby的应用往往具备更好的性能。而另外一些新兴的语言如Go超出了讨论的范围。

标准

JAX-RS是Java世界定义REST API的通用标准。Jersey 是JAX-RS的官方实现,(其他实现如rest-easy)。这是一个简单的Jersey REST GET例子。

@Path("myresource")
public class MyResource {

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        try {
            Thread.sleep(100); // do some job
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Got it!";
    }
}



标准Jersey及其底层servlet实现最大的问题是每处理一个讲求,就需要一个相应的Socket线程处理。在成千上万的并发请求下,系统性能将会明显下降。

异步

为了解决这个问题,JAX-RS提出了异步的解决方案。在这种模式下,请求线程和用户连接之间的联系被打破。I/O容器不再假设等待请求完成,在关闭连接。这是上面简单的Jersey REST GET例子的异步实现:

@Path("myresource")
public class MyResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public void asyncGet(@Suspended final AsyncResponse asyncResponse) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                String result = veryExpensiveOperation();
                asyncResponse.resume(result);
            }

            private String veryExpensiveOperation() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return "Got it!";
            }
        }).start();

    }
}




非阻塞


标准Jersey及其底层servlet实现最大的问题是每处理一个讲求,就需要一个相应的Socket线程处理。在成千上万的并发请求下,系统性能将会明显下降。

为了解决这个问题,JAX-RS提出了异步的解决方案。在这种模式下,请求线程和用户连接之间的联系被打破。I/O容器不再假设等待请求完成,在关闭连接。这是上面简单的Jersey REST GET例子的异步实现:


@Path("myresource")
public class MyResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public void asyncGet(@Suspended final AsyncResponse asyncResponse) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                String result = veryExpensiveOperation();
                asyncResponse.resume(result);
            }

            private String veryExpensiveOperation() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return "Got it!";
            }
        }).start();

    }

}




使用异步技术可以大幅提高吞吐量,但是后端的工作已然需要创建独立的线程完成。系统的负担已然很大。

另外一种完全不同的实现是把“非阻塞”应用到方方面面,不仅仅是HTTP请求处理。在这种模式下,系统仅仅需要少量线程来检测事件的发生。使用这种方法最为重要的是将任务分解为一个个小部分。每个部分的执行事件非常短。Vert.x就是这样一个非阻塞,事件驱动,跨语言的开发框架。Node.JS则是另外一个JavaScript领域很流行的非阻塞框架。

上面简单REST服务的Vert.x实现如下



public class RestServer extends Verticle {
    public void start() {

        RouteMatcher rm = new RouteMatcher();
        rm.get("/myapp/myresource", new Handler() {
            public void handle(final HttpServerRequest req) {
                // sleep 100 ms
                vertx.setTimer(100, new Handler() {
                    public void handle(Long timerID) {
                        req.response().end("Got it");
                    }
                });
            }
        });

        vertx.createHttpServer().requestHandler(rm).listen(8080);
    }
}



我这里比较了jersey同步,异步和vert.x的实现。这里的服务实现工作100毫秒,然后返回结果。我使用gatling模拟了1000个用户并发,每个用户重复请求100次。测试结果显示vertx具有最高的吞吐率(即每秒中完成请求次数)5K和最低的平均时延105ms。Jersey异步居中,达到1K的吞吐量和300ms的平均时延。Jersey同步表现最差,吞吐量只有70,平均时延高达12秒。完整的例子在我的github项目 vertx-jersey-benchmark。当然,这不意味着Vertx是所有人的最佳选择。Vertx也有很多问题。例如,Vertx缺少JAX—RS那样方便易懂的annotation来描述服务资源路径,参数等等。有一个第三方模块vertx-jersey试图将vertx和jersey集成。但是目前它的性能和jersey同步的性能差不多。

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [rest api 性能] 推荐:

REST API性能比较

- - Java - 编程语言 - ITeye博客
REST已然成为最流行的提供外界服务API的方式. 同时,随着互联网和物联网的普及,如今的应用需要处理大量并发的请求. 因此,开发高性能REST服务已经成为一个成功应用的必备条件. 我这里集中讨论Java和JVM相关技术. 基于Java的REST应用比基于python和ruby的应用往往具备更好的性能.

MongoDB REST Api介绍

- peigen - NoSQLFan
MongoDB默认会开启一个HTTP协议的端口提供REST的服务,这个端口是你Server端口加上1000,比如你的Server端口为27017,那么这个HTTP端口就是28017,默认的HTTP端口功能是有限的,你可以通过添加–rest参数启动更多功能. 下面是在这个端口通过其RESTFul 的API操作MongoDB数据的几个例子,来源是MongoDB官方文档.

撰写合格的REST API

- - 博客园_知识库
  两周前因为公司一次裁人,好几个人的活都被按在了我头上,这其中的一大部分是一系列REST API,撰写者号称基本完成,我测试了一下,发现尽管从功能的角度来说,这些API实现了spec的显式要求,但是从实际使用的角度,欠缺的东西太多(各种各样的隐式需求). REST API是一个系统的backend和frontend(或者3rd party)打交道的通道,承前启后,有很多很多隐式需求,比如调用接口与RFC保持一致,API的内在和外在的安全性等等,并非提供几个endpoint,返回相应的json数据那么简单.

Elasticsearch使用REST API实现全文检索

- - zzm
通过rest api添加检索数据,阅读官方文档可以发现,elasticsearch支持动态映射,但是其中有不少问题,且听慢慢详解. 1 Elasticsearch常用的rest api. 2 Elasticsearch使用bulk命令添加索引数据.   elasticsearch支持通过http请求响应服务,因此通过curl命令,可以发送http请求,并得到json返回内容.

使用performance api监测页面性能

- - jackyrong
对于前端开发来说,知道整个页面从开始加载到有内容展示出来的时间是很重要的事情. 通常我们要知道页面加载的时间的话.是采用计算几个关键的时间点的方法来得出页面加载的时间.但是这个方式存在一些问题,比如:我们不知道浏览器在开始解析页面之前卸载前一个文档,解析dns的时间. 那么performance API是啥,能做啥和不能做啥呢.

经典论文 — REST

- ripwu - kernelchina
牛人Roy Thomas Fielding的博士论文,此处可以访问到英文版,中文版可以google一下. HTTP1.0,1.1版本以及URI规范的主要作者,Apache的co-founder. 在写这篇论文之前已经很牛了,笔者不明白的是这种档次牛人还要读博士,文凭有这么重要吗. 文中没有任何令人眼花的数学公式和统计图表,实际上是一篇描述URI,HTTP设计经验教训总结的文章.

WebSockets与REST之争?

- - 酷勤网-挖经验 [expanded by feedex.net]
WebSockets变得越来越流行并积累了不少用户. 去年年底,WebSockets成为了. W3C的推荐候选,这使得其向标准更迈进了一步. Oracle等其他厂商最近也提交了申请,来启动在Java企业版的下一个版本中引入WebSockets(. JSR 356)的标准流程工作. 绝大部分的主流浏览器,如Chrome、Firefox、Safari和IE,都支持某个WebSockets修正本,并最终会采用最后成形的标准.

REST 与 SOAP巅峰对话

- - CSDN博客互联网推荐文章
随着Restful的流行,soap似乎有点贵族落寞了. 下面我们先详细分析一下他们的各自的特点. REST(Representational State Transfer)是 Roy Fielding 提出的一个描述互联系统架构风格的名词. Web 本质上由各种各样的资源组成,资源由 URI 唯一标识.

为啥REST如此重要?

- - 博客园_知识库
  英文原文: Why REST is so important.   本文我们将讨论 REST,它定义了一组体系架构原则,您可以根据这些原则设计以系统资源为中心的 Web 服务,这是一个非常容易让人误解的概念. 本文主要是写给那些想设计 WebService API 但却对 REST 没有十分清晰认识的开发者们.