分布式通信框架-RMI讲解

什么是RPC

Remote procedure call protocal

RPC协议其实是一个规范。常用PRC框架:Dubbo、Thrif、RMI、Webservice、Hessain

网络协议和网络IO对于调用端和服务端来说是透明; 可以简单的理解为用户调用远程方法。不必在乎这个远程方法是怎么出现的,就跟调用本地方法一样。RPC框架做的事就是让我们像使用本地方法一样的去使用远程方法,但是其实RPC框架的底层有自己写好协议以便能远程通讯。

一个RPC框架包含的要素

RPC的框架自然少不了 RPC的服务器和要使用PRC框架的客户端。

自底向上分析:

1.一个通讯协议最基本的就是通讯,常见的通讯协议有TCP和UDP,这属于传输层 。

2.其次就是数据链路层,也可以认为是消息层(毕竟都是数据).

3.而RPC通讯框架在客户端连接时会返回给客户端一个代理对象来执行想要远程调用的方法。

服务器端则是通过RPC框架获取一个处理器。

4.再接着就是服务器端和客户端

这里只是先阐述一个概念,当然这个图并不完整,清接着往下看。

RMI的概述

RMI(remote method invocation) , 可以认为是RPC的java版本

RMI使用的是JRMP(Java Remote Messageing Protocol), JRMP是专门为java定制的通信协议,所以踏实纯java的分布式解决方案

如何实现一个RMI程序

1. 创建远程接口, 并且继承java.rmi.Remote接口

  1. 2. 实现远程接口,并且继承:UnicastRemoteObject

3. 创建服务器程序: createRegistry方法注册远程对象

4. 创建客户端程序

代码如下:

接口:模拟PRC的远程方法

  1. import java.rmi.Remote;
  2. import java.rmi.RemoteException;
  3.  
  4. /**
  5. * @Auther: Anthony
  6. * @Date: 2018/10/16 22:14
  7. * @Description:接口 模拟PRC的远程方法
  8. */
  9. public interface ISayHello extends Remote{
  10. public String sayHello(String name) throws RemoteException;
  11. }

具体实现:真正执行方法(继承UnicastRemoteObject表明是一个远程服务)

  1. import java.rmi.RemoteException;
  2. import java.rmi.server.UnicastRemoteObject;
  3.  
  4. /**
  5. * @Auther: Anthony
  6. * @Date: 2018/10/16 22:15
  7. * @Description:
  8. */
  9. public class SayHelloImpl extends UnicastRemoteObject implements ISayHello{
  10.  
  11. protected SayHelloImpl() throws RemoteException {
  12. }
  13.  
  14. @Override
  15. public String sayHello(String name) throws RemoteException {
  16. return "hello->"+name;
  17. }
  18. }

创建server端

  1. import java.net.MalformedURLException;
  2. import java.rmi.AlreadyBoundException;
  3. import java.rmi.Naming;
  4. import java.rmi.RemoteException;
  5. import java.rmi.registry.LocateRegistry;
  6.  
  7. /**
  8. * @Auther: Anthony
  9. * @Date: 2018/10/16 22:19
  10. * @Description:
  11. */
  12. public class HelloServer {
  13.  
  14. public static void main(String[] args) {
  15. try {
  16. ISayHello hello = new SayHelloImpl();
  17. LocateRegistry.createRegistry(8888);//注册服务
  18. Naming.bind("rmi://localhost:8888/sayHello",hello);//绑定服务
  19. System.out.println("server start success");
  20.  
  21. } catch (RemoteException e) {
  22. e.printStackTrace();
  23. } catch (MalformedURLException e) {
  24. e.printStackTrace();
  25. } catch (AlreadyBoundException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }

创建Client端

  1. import java.net.MalformedURLException;
  2. import java.rmi.Naming;
  3. import java.rmi.NotBoundException;
  4. import java.rmi.RemoteException;
  5.  
  6. /**
  7. * @Auther: Anthony
  8. * @Date: 2018/10/16 22:22
  9. * @Description:
  10. */
  11. public class HelloClient {
  12. public static void main(String[] args) {
  13. try {
  14. ISayHello hello = (ISayHello) Naming.lookup("rmi://localhost:8888/sayHello");
  15. System.out.println(hello);
  16. System.out.println(hello.sayHello("wangqian"));
  17. } catch (NotBoundException e) {
  18. e.printStackTrace();
  19. } catch (MalformedURLException e) {
  20. e.printStackTrace();
  21. } catch (RemoteException e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. }

这里我们需要做的就是Server端注册服务,Client端找到服务并调用方法

如果自己要去实现一个RMI

1. 编写服务器程序,暴露一个监听, 可以使用socket

2. 编写客户端程序,通过ip和端口连接到指定的服务器,并且将数据做封装(序列化)

3. 服务器端收到请求,先反序列化。再进行业务逻辑处理。把返回结果序列化返回

RMI给客户端返回的代理为(调用方法名+Stub),这里统一称为Stub。

服务器使用处理器是为Skeleton

具体RMI框架是怎么操作的呢?

1.server端在注册服务的时候,registry(可以理解为Dubbo里的注册中心 = =)就创建了一个代理对象Stub,

2.同时registry里也同时生成了skeleton对象

3.客户端访问远程服务,就返回创建好的Stub对象

4.Stub远程调用(这里其实就是底层通讯了),Skeleton(这里相当于是一个不断监听的socket)发现有请求过来就指定相应的服务,返回服务给Client。

这里就不贴代码了(知乎写博客是真的难受....)

给个地址:

https://github.com/MelonAnthony/BaseStudy/tree/master/qiansion-day1/src/main/java/per/wq/mvp/qiansion/demo​github.com

MelonAnthony/BaseStudy

源码分析

就拿上面的一段使用RMI框架的代码来说吧

  1. ISayHello hello = new SayHelloImpl();
  2. LocateRegistry.createRegistry(8888);//注册服务
  3. Naming.bind("rmi://localhost:8888/sayHello",hello);//绑定服务
  4. System.out.println("server start success");

先看这个createRegistry

if分支是判断安全性的,而我们传的端口是8888,所以走的是else分支

setup里的主要方法就是这个exportObject,可以认为是暴露服务。

先看第一个红框-创建了一个代理这里var4 就是RegistryImpl也就是一个Registry。由于var2是true,这里创建的就是一个Stub对象(不信的同学可以去这个createProxy里验证一下)。算了,我还是贴出来吧:逻辑或,这我就不解释了吧

然后是setSkeleton,详见下图:

同样是创建一个Skeleton。

这样我们上面说的时序图的1,2步就能说得通了。

至于3,4步,希望大家自己看一看源码,今天太晚了,我就不补充了。下次再来吧。

以上为本人自己的分析,有错误希望各路高人指点江山,指正一下。

1.5分布式通讯框架-RMI的更多相关文章

  1. 分布式通信框架RMI

    1.RPC概念: Remote procedure call protocal,远程过程调用协议,一般用来实现部署在不同机器上的系统之间的方法调用, 使得程序能够像访问本地系统资源一样,通过网络传输去 ...

  2. 分布式服务通讯框架XXL-RPC

    <分布式服务通讯框架XXL-RPC>    一.简介 1.1 概述 XXL-RPC 是一个分布式服务通讯框架,提供稳定高性能的RPC远程服务调用功能.现已开放源代码,开箱即用. 1.2 特 ...

  3. 高性能的分布式服务框架 Dubbo

    我思故我在,提问启迪思考! 1. 什么是Dubbo? 官网:http://dubbo.io/,DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及作为SOA服务治理的 ...

  4. 【转帖】Dubbo:来自于阿里巴巴的分布式服务框架

    http://www.biaodianfu.com/dubbo.html Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被 ...

  5. dubbo 分布式服务框架 介绍

    Dubbo是阿里巴巴内部的SOA服务化治理方案的核心框架,每天为2000+ 个服务提供3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点.Dubbo自2011年开源后, ...

  6. 阿里巴巴分布式服务框架dubbo学习笔记

    Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的 ...

  7. 5个强大的Java分布式缓存框架推荐

    在开发中大型Java软件项目时,很多Java架构师都会遇到数据库读写瓶颈,如果你在系统架构时并没有将缓存策略考虑进去,或者并没有选择更优的 缓存策略,那么到时候重构起来将会是一个噩梦.本文主要是分享了 ...

  8. 阿里巴巴分布式服务框架Dubbo介绍(1)主要特色

    引言 互联网服务和BS架构的传统企业软件相比,系统规模上产生了量级的差距.例如 传统BS企业内部门户只需要考虑数百人以及几千人的访问压力,而大型互联网服务有时需要考虑的是千万甚至上亿的用户: 传统企业 ...

  9. 【转】Dubbo是Alibaba开源的分布式服务框架

    Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,Dubbo采用的是一种非常简单的模 ...

随机推荐

  1. VS根据数据库生成实体类

    一.在类库项目上添加新项 二. 三.依次填入数据库连接 选择数据库 就可以生成数据库实体

  2. Saltstack_使用指南04_数据系统-Grains

    1. 主机规划 Grains文档 https://docs.saltstack.com/en/latest/topics/grains/index.html 注意事项 修改了master或者minio ...

  3. Spring Boot使用注解实现AOP

    第一步: 添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...

  4. 解决topjui中工具栏按钮删除刷新从属表

    遇到了这么个问题:当在从属datagrid表格中,点击主表工具栏按钮中的删除,通过后台的多表删除的sql,返回给前台之后,从属表的数据成功在数据库中删除,但是在前台页面显示的时候,只刷新了主表,子表未 ...

  5. 爬虫系列二(数据清洗--->xpath解析数据)

    一 xpath介绍 XPath 是一门在 XML 文档中查找信息的语言.XPath 用于在 XML 文档中通过元素和属性进行导航. XPath 使用路径表达式在 XML 文档中进行导航 XPath 包 ...

  6. Python标准库之ConfigParser模块

    配置文件的格式 a) 配置文件中包含一个或多个 section, 每个 section 有自己的 option: b) section 用 [sect_name] 表示,每个option是一个键值对, ...

  7. 创建DVWA环境时遇到的问题

    前言:我下载了PHP Study,也按照步骤下载保存了DVWA,之后我又按照百度的准备登陆检查是否正确安装DVWA,于是,我登录了百度上查到的链接:http://localhost/DVWA-mast ...

  8. Settings > Editor > Live Templates 中自定义快速输入

    Settings > Editor > Live Templates 中自定义快速输入

  9. .net core2.1 三层中使用Autofac代替原来Ioc

    首先,现有的三层项目的结构 其中  Repository public interface IPersonRepository { string Eat(); } public class Perso ...

  10. CGPoint、CGSize、CGRect、CGRectEdge的详细使用

    http://blog.sina.com.cn/s/blog_953e22700101r7lz.html 在CGGeometry.h里的 CGPoint.CGSize.CGRect.CGRectEdg ...