分布式通信框架-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接口

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

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

4. 创建客户端程序

代码如下:

接口:模拟PRC的远程方法

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

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

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject; /**
* @Auther: Anthony
* @Date: 2018/10/16 22:15
* @Description:
*/
public class SayHelloImpl extends UnicastRemoteObject implements ISayHello{ protected SayHelloImpl() throws RemoteException {
} @Override
public String sayHello(String name) throws RemoteException {
return "hello->"+name;
}
}

创建server端

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; /**
* @Auther: Anthony
* @Date: 2018/10/16 22:19
* @Description:
*/
public class HelloServer { public static void main(String[] args) {
try {
ISayHello hello = new SayHelloImpl();
LocateRegistry.createRegistry(8888);//注册服务
Naming.bind("rmi://localhost:8888/sayHello",hello);//绑定服务
System.out.println("server start success"); } catch (RemoteException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
}
}
}

创建Client端

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException; /**
* @Auther: Anthony
* @Date: 2018/10/16 22:22
* @Description:
*/
public class HelloClient {
public static void main(String[] args) {
try {
ISayHello hello = (ISayHello) Naming.lookup("rmi://localhost:8888/sayHello");
System.out.println(hello);
System.out.println(hello.sayHello("wangqian"));
} catch (NotBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}

这里我们需要做的就是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框架的代码来说吧

ISayHello hello = new SayHelloImpl();
LocateRegistry.createRegistry(8888);//注册服务
Naming.bind("rmi://localhost:8888/sayHello",hello);//绑定服务
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. Linux Shell 返回值之 PIPESTATUS

    BASH SHELL中,通常使用 $? 来获取上一条命令的返回码,对于管道中的命令,使用$?只能获取管道中最后一条命令的返回码,例如: 下面的例子 /djdjal/dajiojidksj.file是一 ...

  2. Bootstrap -- 下拉菜单、输入框组、导航菜单

    Bootstrap -- 下拉菜单.输入框组.导航菜单 1. 下拉菜单 可以使用带有各种大小按钮的下拉菜单:.btn-lg..btn-sm 或 .btn-xs. 实现下拉菜单: <!DOCTYP ...

  3. 5.4Python数据处理篇之Sympy系列(四)---微积分

    目录 目录 前言 (一)求导数-diff() 1.一阶求导-diff() 2.多阶求导-diff() 3.求偏导数-diff() (二)求积分-integrate() (三)求极限-limit() ( ...

  4. MySql 学习之路-聚合函数

    下面是mysql 数据库中经常用到的聚合函数的简单实例 -- 创建学生表 create table student ( id int primary key auto_increment commen ...

  5. 简单用数组模拟顺序栈(c++)

    **栈是一种操作受限制的线性表,太多官方的话我也不说了,我们都知道栈元素是先进后出的,它有两种存储结构,分别是顺序存储结构和链式存储结构. **今天我先记一下顺序存储结构,后面我会加上链式存储结构的. ...

  6. laravel学习笔记二

    代码编写提示工具

  7. ElasticSearch(九):elasticsearch-head插件安装

    安装node 安装elasticsearch-head需要node.js的支持. 下载最新的node.js,下载地址:https://nodejs.org/en/download/ 将下载后的安装包放 ...

  8. python中的struct模块的学习

    由于TCP协议中的黏包现象的发生,对于最low的办法,每次发送之前让他睡一秒,然后在发送,可是这样真的太low了,而且太占用资源了. 黏包现象只发生在tcp协议中: 1.从表面上看,黏包问题主要是因为 ...

  9. 选择语句--switch

    switch语句 格式: 执行流程 首先计算出表达式的值 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结束. 最后,如果所有的case都和表达式的值 ...

  10. wget命令使用报错 certificate common name 'xxx' doesn't match requestde host name

    使用wget命令 wget http://www.monkey.org/~provos/libevent-1.2.tar.gz 报如下错 error:certificate common name & ...