热门标签 | 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


推荐阅读
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 本文深入探讨了Go语言中的接口型函数,通过实例分析其灵活性和强大功能,帮助开发者更好地理解和运用这一特性。 ... [详细]
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • Hadoop MapReduce 实战案例:手机流量使用统计分析
    本文通过一个具体的Hadoop MapReduce案例,详细介绍了如何利用MapReduce框架来统计和分析手机用户的流量使用情况,包括上行和下行流量的计算以及总流量的汇总。 ... [详细]
  • 在使用mybatis进行mapper.xml测试的时候发生必须为元素类型“mapper”声明属性“namespace”的错误项目目录结构UserMapper和UserMappe ... [详细]
  • 本文由chszs撰写,详细介绍了Apache Mina框架的核心开发流程及自定义协议处理方法。文章涵盖从创建IoService实例到协议编解码的具体步骤,适合希望深入了解Mina框架应用的开发者。 ... [详细]
  • 本文基于Java官方文档进行了适当修改,旨在介绍如何实现一个能够同时处理多个客户端请求的服务端程序。在前文中,我们探讨了单客户端访问的服务端实现,而本篇将深入讲解多客户端环境下的服务端设计与实现。 ... [详细]
  • 本文探讨了如何在 Spring MVC 框架下,通过自定义注解和拦截器机制来实现细粒度的权限管理功能。 ... [详细]
  • 本文详细介绍了Oracle 11g中的创建表空间的方法,以及如何设置客户端和服务端的基本配置,包括用户管理、环境变量配置等。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • JUnit下的测试和suite
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 一、Advice执行顺序二、Advice在同一个Aspect中三、Advice在不同的Aspect中一、Advice执行顺序如果多个Advice和同一个JointPoint连接& ... [详细]
  • 问题场景用Java进行web开发过程当中,当遇到很多很多个字段的实体时,最苦恼的莫过于编辑字段的查看和修改界面,发现2个页面存在很多重复信息,能不能写一遍?有没有轮子用都不如自己造。解决方式笔者根据自 ... [详细]
  • 2023年1月28日网络安全热点
    涵盖最新的网络安全动态,包括OpenSSH和WordPress的安全更新、VirtualBox提权漏洞、以及谷歌推出的新证书验证机制等内容。 ... [详细]
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社区 版权所有