热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

javarmi与springmvcrest性能简单对比

场景描述:服务端用rest和rmi发布两个接口,两个接口提供同样的功能,获取同一个bean;服务端用httpclient

场景描述:

服务端用rest和rmi发布两个接口,两个接口提供同样的功能,获取同一个bean;

服务端用httpclient和rmi分别起十个线程调用,打印时间;

废话少说,程序猿用代码说话: 

首先定义一个Bean:
package net.tt.rest.domain;
 
import java.io.Serializable;
 
import lombok.Data;
 
/**
 *
 * @author tbc 
 * @version 1.0 {2016年6月13日 上午11:29:56}
 */
@Data
public class MyBean implements Serializable {
    private static final long serialVersionUID = -3442523325988510637L;
    private String uuid;
    private String name;
    private String value;
 
    public static MyBeanBuilder builder() {
        return new MyBeanBuilder();
    }
 
    public static class MyBeanBuilder {
        private String uuid;
        private String name;
        private String value;
 
        public MyBeanBuilder uuid(String uuid) {
            this.uuid = uuid;
            return this;
        }
 
        public MyBeanBuilder name(String name) {
            this.name = name;
            return this;
        }
 
        public MyBeanBuilder value(String value) {
            this.value = value;
            return this;
        }
 
        public MyBean build() {
            MyBean b = new MyBean();
            b.setName(name);
            b.setUuid(uuid);
            b.setValue(value);
            return b;
        }
 
    }
 
}

 

要发布的接口:

package net.tt.rest.service;
 
import java.rmi.Remote;
import java.rmi.RemoteException;
 
import net.tt.rest.domain.MyBean;
 
/**
 *
 * @author tbc 
 * @version 1.0 {2016年6月13日 上午10:14:43}
 */
public interface RmiRest extends Remote {
 
    MyBean getBean() throws RemoteException;
 
}


接口实现:

package net.tt.rest.service.impl;
 
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.UUID;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
 
import net.tt.rest.domain.MyBean;
import net.tt.rest.service.RmiRest;
 
/**
 * UnicastRemoteObject用于导出的远程对象和获得与该远程对象通信的存根。
 * 
 * @author tbc 
 * @version 1.0 {2016年6月13日 上午10:39:26}
 */
@Service("rmiRestImpl")
public class RmiRestImpl extends UnicastRemoteObject implements RmiRest {
    private static final long serialVersionUID = 1L;
    private Logger log = LoggerFactory.getLogger(RmiRestImpl.class);
 
    public RmiRestImpl() throws RemoteException {
    }
 
    @Override
    public MyBean getBean() throws RemoteException {
        MyBean bean = MyBean.builder()//
                .uuid(UUID.randomUUID().toString())//
                .name("MyName")//
                .value("thid is a test!")//
                .build();
        return bean;
    }
 
}
 


spring mvc controller -> 

package net.tt.rest.controller;
 
import java.rmi.RemoteException;
import java.util.Map;
 
import javax.annotation.Resource;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import com.google.common.collect.Maps;
 
import net.tt.rest.domain.MyBean;
import net.tt.rest.service.RmiRest;
 
/**
 *
 * @author tbc 
 * @version 1.0 {2016年6月13日 上午10:57:03}
 */
@RestController
public class MyRestController {
    private Logger log = LoggerFactory.getLogger(MyRestController.class);
 
    @Resource(name = "rmiRestImpl")
    RmiRest rmiRest;
 
    @RequestMapping(value = "bean", method = { RequestMethod.GET })
    public MyBean getBean() throws RemoteException {
        return rmiRest.getBean();
    }
 
}
 
 
监听器,发布RMI :

package net.tt.rest.listener;
 
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
 
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import net.tt.rest.service.RmiRest;
import net.tt.rest.service.impl.RmiRestImpl;
 
/**
 *
 * @author tbc
 * @version 1.0 {2016年6月13日 上午10:44:13}
 */
@WebListener("rmi")
public class MyServletContextListener implements ServletContextListener {
    private Logger log = LoggerFactory.getLogger(MyServletContextListener.class);
 
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("启动监听,启动rmi服务...");
        try {
            RmiRest rr = new RmiRestImpl();
            LocateRegistry.createRegistry(8888);
 
            Naming.bind("rmi://localhost:8888/rr", rr);
 
            log.info("远程RmiRest对象绑定成功--->");
        } catch (RemoteException e) {
            log.error("创建远程对象发生异常");
            e.printStackTrace();
        } catch (MalformedURLException e) {
            log.error("发生重复绑定对象异常!");
            e.printStackTrace();
        } catch (AlreadyBoundException e) {
            log.error("发生URL畸形异常!");
            e.printStackTrace();
        }
 
    }
 
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("销毁监听器...");
    }
 
}
 
 OK,到此服务端代码就完成了,至于spring及监听的相关配置,不是本文重点,不再赘述,启动jetty,OK,成功!

下面写客户端代码进行测试: 

package net.tt.mytest.rmirest;
 
import java.io.IOException;
import java.rmi.Naming;
import java.util.concurrent.TimeUnit;
 
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.fluent.Request;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import net.tt.rest.domain.MyBean;
import net.tt.rest.service.RmiRest;
 
/**
 *
 * @author tbc 
 * @version 1.0 {2016年6月13日 上午11:15:05}
 */
public class RmiRestTest {
    private static Logger log = LoggerFactory.getLogger(RmiRestTest.class);
 
    public static void main(String[] args) throws ClientProtocolException, IOException, InterruptedException {
        log.info("springMvcRest testing ...");
        for (int i &#61; 0; i <10; i&#43;&#43;) {
            new Thread(() -> {
                long restStart &#61; System.currentTimeMillis();
                String restContent &#61; "";
                try {
                    restContent &#61; Request.Get("http://localhost:8080/spring/bean")//
                            .execute()//
                            .returnContent()//
                            .asString();
                    log.info("rest return -> {}", restContent);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                // log.info("exec result : {}", restCode);
                log.info("本次耗时&#xff1a;{}", (System.currentTimeMillis() - restStart));
            }).start();
        }
 
        TimeUnit.SECONDS.sleep(3);
        System.out.println("--------------------------------->");
        log.info("rmi testing ...");
        for (int i &#61; 0; i <10; i&#43;&#43;) {
            new Thread(() -> {
                long rmiStart &#61; System.currentTimeMillis();
                int restCode &#61; 0;
                try {
                    RmiRest rr &#61; (RmiRest) Naming.lookup("rmi://localhost:8888/rr");
                    MyBean b &#61; rr.getBean();
                    log.info("rmi return -> {}", b);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                log.info("本次耗时&#xff1a;{}", (System.currentTimeMillis() - rmiStart));
            }).start();
        }
 
    }
 
}
 
OK&#xff0c;一段简单的代码&#xff0c;进行一下简单的对比测试&#xff0c;全程裸奔&#xff0c;那么看一下结果&#xff1a;

程序猿能用代码说明的问题咱就用图片说明。。。

注&#xff1a;本文不讨论rest和RMI 甚至 RPC方案的优劣&#xff0c;不涉及跨平台等等属性&#xff0c;仅仅是在纯JAVA方案的前提下&#xff0c;测试rest与rmi两种方案的性能问题&#xff0c;本测试也不是十分严谨&#xff0c;事实上&#xff0c;这种测试是很不公平的&#xff0c;可以说拿RMI的优势来对比REST的劣势&#xff0c;非常偏&#xff0c;但在纯JAVA系统中&#xff0c;只关心性能的情况下&#xff0c;应该还是有一定的参考意义的&#xff1b;

另外&#xff0c;据说jersey的实现方案性能要比spring mvc强&#xff0c;下次做一下这方面的相关测试&#xff1b;

 

转自https://blog.csdn.net/tbc3697/article/details/51656637


推荐阅读
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文介绍了在多平台下进行条件编译的必要性,以及具体的实现方法。通过示例代码展示了如何使用条件编译来实现不同平台的功能。最后总结了只要接口相同,不同平台下的编译运行结果也会相同。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
author-avatar
mobiledu2502911403
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有