1 dubbo是远程服务调用rpc框架

2 dubbo缺省协议采用单一长连接和NIO通讯

1client端生成一个唯一的id,封装方法调用信息obj(接口名,方法名,参数,处理结果的回调对象),在全局的ConcurrentHashMap中保存put(id,obj), 将id和obj发送到server端,当前线程使用callback的get()方法试图获取远程返回的结果,在get()内部,则使用synchronized获取回调对象callback的锁, 先检测是否已经获取到结果,如果没有,然后调用callback的wait()方法,释放callback上的锁,让当前线程处于等待状态。

2server端接收到请求并处理后,返回给client端处理结果,client从中取到ID,再从前面的ConcurrentHashMap里面get(ID),从而找到callback,将方法调用结果设置到callback对象里 ,使用synchronized获取回调对象callback的锁(因为前面调用过wait(),那个线程已释放callback的锁了),再notifyAll(),唤醒前面处于等待状态的线程继续执行

参考:https://blog.csdn.net/paul_wei2008/article/details/19355681

在实际项目有类似的需求,不过没有用锁机制,线程等待,直接使用sleep方法了

package com.moreas.r1;

public interface Event {
public void handlerEvent(Object params);
}

  

package com.moreas.r1;

import java.util.HashMap;
import java.util.Map; public class RemoteService implements Event { private int monitor_result = 0; public Object remoteLocate(String deviceID) { Map<String, Object> returnMap = new HashMap<>();
returnMap.put("code", 1); @SuppressWarnings("unchecked")
Map<String, Object> deviceMap = (Map<String, Object>) ServerManager.application.get(deviceID); // 生成指令
String msgID = Utils.createMsgID();
OrderEntity order = new OrderEntity();
order.setMsgID(msgID);
order.setCmd("Monitor");
order.setDeviceID(deviceID); deviceMap.put("MsgId", msgID);
ServerManager.application.put(deviceID, deviceMap); // 将自己添加到回调的map中
LocateService.addHandlerEvent(deviceID + "_Monitor", this); // 使用socket将指令order发送出去 // 等待
try { int cnt = 0;
while ((monitor_result == 0) && cnt < 280) {
Thread.sleep(100);
cnt++;
} } catch (InterruptedException e) {
e.printStackTrace();
}
if (monitor_result != 0) { // 通过handlerEvent方法将处理结果设置到monitor_result中
returnMap.put("code", 2);
} else {
System.out.println("请求超时了");
returnMap.put("code", 2);
} LocateService.removeHandlerEvent(deviceID + "_Monitor");
return returnMap; } @Override
public void handlerEvent(Object params) {
Map map = (Map) params;
if (((String) map.get("result")).equals(123)) {
monitor_result = 11;
}
} }

  

package com.moreas.r1;

import java.util.HashMap;

public class LocateService extends CallBack {

	@SuppressWarnings({ "rawtypes", "unchecked" })
public void handlerUploadLctDataByApp(OrderEntity receiveOrder, String deviceID) {
// 通过receiveOrder取得参数,调用本地方法获取结果result
int resultData = 1; if (resultData == 1) { Event event = getEvent(deviceID + "_Monitor");
if (event != null) {
HashMap map = new HashMap<>();
map.put("locResult", "123");
event.handlerEvent(map);
}
}
} }

  

package com.moreas.r1;

import java.util.HashMap;
import java.util.Map; public class CallBack { private static Map<String, Event> eventList = new HashMap<>(); public static void addHandlerEvent(String key, Event eventClass) { if (eventList.containsKey(key)) {
return;
} synchronized (eventList) {
eventList.put(key, eventClass);
}
} public static void removeHandlerEvent(String key) { if (!eventList.containsKey(key)) {
return;
} synchronized (eventList) {
eventList.remove(key);
}
} public static void clearHandlerEvent() { synchronized (eventList) {
eventList.clear();
}
} public static boolean containsKey(String key) { return eventList.containsKey(key);
} public static Event getEvent(String key) { if (!containsKey(key))
return null; return eventList.get(key);
} }

  

package com.moreas.r1;

import java.util.Map;

public class ReceiveData {

	//order是接受到的指令,接受到指令后,进行处理
@SuppressWarnings({ "unused", "unchecked" })
private void handler(OrderEntity order) { if(order.getCmd().equals("Monitor")){
//获取application中的MsgId
String deviceID = order.getDeviceID();
Map<String, Object> deviceMap = (Map<String, Object>)ServerManager.application.get(deviceID);
String msgID = (String)deviceMap.get("MsgId");
//order中的MsgId
if(msgID.equals(order.getMsgID())) { new LocateService().handlerUploadLctDataByApp(order, deviceID); deviceMap.remove("MsgId");
ServerManager.application.put(deviceID,deviceMap);
} } }
}

  

package com.moreas.r1;

public class OrderEntity {

	private String msgID; // 消息ID

	private String cmd;

	private String deviceID;

	public String getDeviceID() {
return deviceID;
} public void setDeviceID(String deviceID) {
this.deviceID = deviceID;
} public String getCmd() {
return cmd;
} public void setCmd(String cmd) {
this.cmd = cmd;
} public String getMsgID() {
return msgID;
} public void setMsgID(String msgID) {
this.msgID = msgID;
} public String getMsg() {
return "123";
};
}

  

package com.moreas.r1;

import java.util.HashMap;
import java.util.Map; public class ServerManager { private static final String flag = "ServerManger"; public static Map<String, Object> application = new HashMap<String, Object>(); }

  

package com.moreas.r1;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random; public class Utils { public static String createMsgID() { Random random = new Random();
int nonce = random.nextInt(1000);
String nonceStr = "" + nonce;
if (nonce < 100) {
nonceStr = "0" + nonceStr;
if (nonce < 10) {
nonceStr = "0" + nonceStr;
}
} SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String currTime = df.format(new Date()); return currTime + "-" + nonceStr;
}
}

  

dubbo远程方法调用的基本原理的更多相关文章

  1. 沉淀再出发:dubbo的基本原理和应用实例

    沉淀再出发:dubbo的基本原理和应用实例 一.前言 阿里开发的dubbo作为服务治理的工具,在分布式开发中有着重要的意义,这里我们主要专注于dubbo的架构,基本原理以及在Windows下面开发出来 ...

  2. Dubbo基本原理机制

      分布式服务框架: –高性能和透明化的RPC远程服务调用方案 –SOA服务治理方案 -Apache MINA 框架基于Reactor模型通信框架,基于tcp长连接 Dubbo缺省协议采用单一长连接和 ...

  3. Dubbo+Zookeeper实现简单的远程方法调用示例

    1. Dubbo介绍 示例代码:Github 1.1 RPC Remote Procedure Call:远程过程调用 1.2 Dubbo架构 Subscribe 订阅:签署:赞成 Monitor 监 ...

  4. RPC基本原理

    RPC非常重要,很多人面试的时候都挂在了这个地方!你要是还不懂RPC是什么?他的基本原理是什么?你一定要把下边的内容记起来!好好研究一下!特别是文中给出的一张关于RPC的基本流程图,重点中的重点,Du ...

  5. 精选 Dubbo RPC 面试题,比较全面,含答案

    精选 Dubbo RPC 面试题,比较全面,含答案 hu1991die 搜云库技术团队 搜云库技术团队 微信号 souyunku 功能介绍 专注于分享最有价值的互联网技术干货文章,内容覆盖,Java后 ...

  6. RPC原来就是Socket——RPC框架到dubbo的服务动态注册,服务路由,负载均衡演化

    序:RPC就是使用socket告诉服务端我要调你的哪一个类的哪一个方法然后获得处理的结果.服务注册和路由就是借助第三方存储介质存储服务信息让服务消费者调用.然我们自己动手从0开始写一个rpc功能以及实 ...

  7. 分布式服务框架dubbo原理解析(转)

    libaba有好几个分布式框架,主要有:进行远程调用(类似于RMI的这种远程调用)的(dubbo.hsf),jms消息服务(napoli.notify),KV数据库(tair)等.这个框架/工具/产品 ...

  8. Java的RMI远程方法调用实现和应用

    最近在学习Dubbo,RMI是很重要的底层机制,RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一 ...

  9. dubbo+zookeeper例子

    0.原理   Alibaba有好几个分布式框架,主要有:进行远程调用(类似于RMI的这种远程调用)的(dubbo.hsf),jms消息服务(napoli.notify),KV数据库(tair)等.这个 ...

随机推荐

  1. java体系架构

    java概念 java本身是一种面向对象的语言,最显著的特性有两方面,一是所谓的“书写一次,到处运行”(write once ,run anywhrer),能够非常容易的获得跨平台能力,另外就是垃圾收 ...

  2. Docker部署Nginx并修改配置文件

    Docker部署Nginx并修改配置文件 一.拉取nginx镜像 docker pull nginx 二.在宿主机中创建挂载目录 mkdir -p /data/nginx/{conf,conf.d,h ...

  3. PS换脸操作

    1,使用套索工具抠出人的五官. 2,Ctrl+C复制黏贴到另一张头像中,调节透明度50%,与需要换脸的头像的眼睛,嘴巴,鼻子重合,透明度回归100%. 3,为了不该变原图,需要新建一张原图. 4,在抠 ...

  4. 【linux】如何开放防火墙端口

    linux默认大部分端口的是关闭的.而我们在开发.部署环境时,需要用到大量的服务,如mysql.tomcat.redis.zk等,需要开放指定的端口号. 以mysql端口3306为例 首先编辑服务器的 ...

  5. BZOJ2434: [Noi2011]阿狸的打字机(AC自动机 树状数组)

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4140  Solved: 2276[Submit][Status][Discuss] Descript ...

  6. Windows下git设置代理服务器

    SVN中,使用TortoiseSVN来进行版本控制时,设置代理非常简单,只需要在设置里面添加代理的信息即可.而 git 在GUI(v0.17.GITGUI)中却无法找到类似的设置,只能求助 git b ...

  7. Python 利用Python操作excel表格之openyxl介绍Part1

    利用Python操作excel表格之openyxl介绍 by:授客 QQ:1033553122 欢迎加入全国软件测试交流qq群(群号:7156436),免费获取以下性能监控工具(类似Nmon精简版) ...

  8. 【效率工具】史上最好用的SSH一键登录脚本,第三版更新!

    说明 时隔一周,GotoSSH又迎来了一次重大更新,让这个史诗级的shell工具变得更加丝般顺滑了~ 这次的主要更新是对自定义全局命令以及自定义属性的支持,让设置更加灵活,此外,对各个细节进行了调整, ...

  9. 算法: 包含min函数的栈

    * @Description 包含min函数的栈* @问题:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)).* @思路: 1:Stack 类中的p ...

  10. (后端)SpringBoot中Mybatis打印sql(转)

    原文地址:https://www.cnblogs.com/expiator/p/8664977.html 如果使用的是application.properties文件,加入如下配置: logging. ...