RPC 框架几行代码就够了

本贴最后更新于 2740 天前,其中的信息可能已经时移俗易

转自梁飞的博客(http://javatar.iteye.com/blog/1123915)
Java 代码
/*

  • Copyright 2011 Alibaba.com All right reserved. This software is the
  • confidential and proprietary information of Alibaba.com ("Confidential
  • Information"). You shall not disclose such Confidential Information and shall
  • use it only in accordance with the terms of the license agreement you entered
  • into with Alibaba.com.
    */
    package com.alibaba.study.rpc.framework;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.ServerSocket;
import java.net.Socket;

/**

  • RpcFramework

  • @author william.liangf
    */
    public class RpcFramework {

    /**

    • 暴露服务
    • @param service 服务实现
    • @param port 服务端口
    • @throws Exception
      */
      public static void export(final Object service, int port) throws Exception {
      if (service == null)
      throw new IllegalArgumentException("service instance == null");
      if (port <= 0 || port > 65535)
      throw new IllegalArgumentException("Invalid port " + port);
      System.out.println("Export service " + service.getClass().getName() + " on port " + port);
      ServerSocket server = new ServerSocket(port);
      for(;;) {
      try {
      final Socket socket = server.accept();
      new Thread(new Runnable() {
      @Override
      public void run() {
      try {
      try {
      ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
      try {
      String methodName = input.readUTF();
      Class[] parameterTypes = (Class[])input.readObject();
      Object[] arguments = (Object[])input.readObject();
      ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
      try {
      Method method = service.getClass().getMethod(methodName, parameterTypes);
      Object result = method.invoke(service, arguments);
      output.writeObject(result);
      } catch (Throwable t) {
      output.writeObject(t);
      } finally {
      output.close();
      }
      } finally {
      input.close();
      }
      } finally {
      socket.close();
      }
      } catch (Exception e) {
      e.printStackTrace();
      }
      }
      }).start();
      } catch (Exception e) {
      e.printStackTrace();
      }
      }
      }

    /**

    • 引用服务
    • @param 接口泛型
    • @param interfaceClass 接口类型
    • @param host 服务器主机名
    • @param port 服务器端口
    • @return 远程服务
    • @throws Exception
      */
      @SuppressWarnings("unchecked")
      public static T refer(final Class interfaceClass, final String host, final int port) throws Exception {
      if (interfaceClass == null)
      throw new IllegalArgumentException("Interface class == null");
      if (! interfaceClass.isInterface())
      throw new IllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!");
      if (host == null || host.length() == 0)
      throw new IllegalArgumentException("Host == null!");
      if (port <= 0 || port > 65535)
      throw new IllegalArgumentException("Invalid port " + port);
      System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);
      return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[] {interfaceClass}, new InvocationHandler() {
      public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {
      Socket socket = new Socket(host, port);
      try {
      ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
      try {
      output.writeUTF(method.getName());
      output.writeObject(method.getParameterTypes());
      output.writeObject(arguments);
      ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
      try {
      Object result = input.readObject();
      if (result instanceof Throwable) {
      throw (Throwable) result;
      }
      return result;
      } finally {
      input.close();
      }
      } finally {
      output.close();
      }
      } finally {
      socket.close();
      }
      }
      });
      }

}
用起来也像模像样:

(1) 定义服务接口

Java 代码

/*

  • Copyright 2011 Alibaba.com All right reserved. This software is the
  • confidential and proprietary information of Alibaba.com ("Confidential
  • Information"). You shall not disclose such Confidential Information and shall
  • use it only in accordance with the terms of the license agreement you entered
  • into with Alibaba.com.
    */
    package com.alibaba.study.rpc.test;

/**

  • HelloService

  • @author william.liangf
    */
    public interface HelloService {

    String hello(String name);

}

(2) 实现服务

Java 代码

/*

  • Copyright 2011 Alibaba.com All right reserved. This software is the
  • confidential and proprietary information of Alibaba.com ("Confidential
  • Information"). You shall not disclose such Confidential Information and shall
  • use it only in accordance with the terms of the license agreement you entered
  • into with Alibaba.com.
    */
    package com.alibaba.study.rpc.test;

/**

  • HelloServiceImpl

  • @author william.liangf
    */
    public class HelloServiceImpl implements HelloService {

    public String hello(String name) {
    return "Hello " + name;
    }

}

(3) 暴露服务

Java 代码

/*

  • Copyright 2011 Alibaba.com All right reserved. This software is the
  • confidential and proprietary information of Alibaba.com ("Confidential
  • Information"). You shall not disclose such Confidential Information and shall
  • use it only in accordance with the terms of the license agreement you entered
  • into with Alibaba.com.
    */
    package com.alibaba.study.rpc.test;

import com.alibaba.study.rpc.framework.RpcFramework;

/**

  • RpcProvider

  • @author william.liangf
    */
    public class RpcProvider {

    public static void main(String[] args) throws Exception {
    HelloService service = new HelloServiceImpl();
    RpcFramework.export(service, 1234);
    }

}

(4) 引用服务

Java 代码

/*

  • Copyright 2011 Alibaba.com All right reserved. This software is the
  • confidential and proprietary information of Alibaba.com ("Confidential
  • Information"). You shall not disclose such Confidential Information and shall
  • use it only in accordance with the terms of the license agreement you entered
  • into with Alibaba.com.
    */
    package com.alibaba.study.rpc.test;

import com.alibaba.study.rpc.framework.RpcFramework;

/**

  • RpcConsumer

  • @author william.liangf
    */
    public class RpcConsumer {

    public static void main(String[] args) throws Exception {
    HelloService service = RpcFramework.refer(HelloService.class, "127.0.0.1", 1234);
    for (int i = 0; i < Integer.MAX_VALUE; i ++) {
    String hello = service.hello("World" + i);
    System.out.println(hello);
    Thread.sleep(1000);
    }
    }

}

  • RPC
    16 引用 • 22 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3169 引用 • 8208 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • lijp

    感谢分享

  • 感谢分享,看完才明白 rpc 原来也没这么复杂,重点是 socket 和动态代码,写的精辟!!!

  • Tnima

    抄袭转载过来的,这原本是 dubbo 作者当年写的 csdn 博客

  • someone

    请看正文第一行

推荐标签 标签

  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    76 引用 • 429 回帖
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    324 引用 • 1395 回帖 • 1 关注
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 556 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 712 关注
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    23 引用 • 31 回帖 • 8 关注
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    4 引用 • 16 回帖 • 1 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    544 引用 • 3531 回帖
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    77 引用 • 159 回帖
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 224 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 94 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    20156 引用 • 77715 回帖 • 1 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 705 关注
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    123 引用 • 168 回帖
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 624 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 458 关注
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    85 引用 • 122 回帖 • 618 关注
  • 七牛云

    七牛云是国内领先的企业级公有云服务商,致力于打造以数据为核心的场景化 PaaS 服务。围绕富媒体场景,七牛先后推出了对象存储,融合 CDN 加速,数据通用处理,内容反垃圾服务,以及直播云服务等。

    26 引用 • 222 回帖 • 167 关注
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 248 回帖 • 124 关注
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 125 关注
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    675 引用 • 535 回帖
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    21 引用 • 140 回帖 • 12 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    131 引用 • 1114 回帖 • 137 关注
  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    45 引用 • 25 回帖
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    5 引用 • 62 回帖
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 9 关注