自实现RPC调用
服务提供者
服务接口:
public interface HelloService {
public String sayHello(String name);
}
服务实现类:
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "hello:" + name;
}
}
服务注册:
public class ProviderReflect {
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 1, TimeUnit.MINUTES, new LinkedBlockingDeque<Runnable>(1000), new MyThreadFactory("providerReflact"));
/**
* 服务发布
*
* @param service
* @param port
*/
public static void provider(final Object service, int port) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
while (true) {
Socket socket = serverSocket.accept();
executor.execute(new Runnable() {
@Override
public void run() {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(socket.getInputStream());
// 请求调用的方法名
String methodName = ois.readUTF();
// 请求的参数
Object[] args = (Object[]) ois.readObject();
oos = new ObjectOutputStream(socket.getOutputStream());
Object result = MethodUtils.invokeExactMethod(service, methodName, args);
System.out.println(result);
// 写结果
oos.writeObject(result);
} catch (IOException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
static class MyThreadFactory implements ThreadFactory {
/**
* 线程池中的线程名称前缀
*/
private String namePrefix;
/**
* 原子的整型
*/
private AtomicInteger atomicInteger = new AtomicInteger(1);
public MyThreadFactory(String whatFeaturOfGroup) {
this.namePrefix = "From MyThreadFactory:" + whatFeaturOfGroup + "-worker-";
}
@Override
public Thread newThread(Runnable r) {
String name = namePrefix + atomicInteger.getAndIncrement();
Thread thread = new Thread(r, name);
System.out.println(thread.getName());
return thread;
}
}
/**
* 发布服务
*
* @param args
*/
public static void main(String[] args) {
HelloService helloService = new HelloServiceImpl();
ProviderReflect.provider(helloService, 8082);
}
}
pom.xml:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
服务消费者
消费接口:
public interface HelloService {
public String sayHello(String name);
}
接口的代理:
public class ConsumerProxy {
public static <T> T consume(final Class<?> serviceClass, final String host, final int port) {
return (T) Proxy.newProxyInstance(serviceClass.getClassLoader(), new Class<?>[]{serviceClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket socket = null;
ObjectOutputStream output = null;
ObjectInputStream input = null;
try {
socket = new Socket(host, port);
output = new ObjectOutputStream(socket.getOutputStream());
// output.writeUTF(serviceClass.getName());
output.writeUTF(method.getName());
// output.writeObject(method.getParameterTypes());
output.writeObject(args);
input = new ObjectInputStream(socket.getInputStream());
return input.readObject();
} finally {
if (socket != null) {
socket.close();
}
if (output != null) {
output.close();
}
if (input != null) {
input.close();
}
}
}
});
}
public static void main(String[] args) {
HelloService helloService = ConsumerProxy.consume(HelloService.class, "127.0.0.1", 8082);
String response = helloService.sayHello("yangyongjie");
System.out.println(response);
}
}
输出:
hello:yangyongjie
自实现RPC调用的更多相关文章
- 闲话RPC调用
原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com 自SOA架构理念提出以来,应用程序间如何以最低耦合度通信的问题便呈现在所有架构师面前. 互联网系统的复杂度让我们不 ...
- RabbitMQ学习笔记5-简单的RPC调用
利用空的queue名字("")让rabbitMQ生成一个唯一的队列名称,同时指定队列是:临时的(auto-delete).私有的(exclusive). 在发送的RPC调用消息里设 ...
- Hadoop学习记录(3)|HDFS API 操作|RPC调用
HDFS的API操作 URL方式访问 package hdfs; import java.io.IOException; import java.io.InputStream; import java ...
- 使用RPC 调用NameNode中的方法
用户在Client 端是很难对 NameNode中的信息进行直接访问的, 所以 ,在Hadoop系统中为 Client端 提供了一系列的方法调用,这些方法调用是通过RPC 方法来实现的, 根据RPC ...
- Unity3D RPC调用顺序问题
使用Unity自带的Network实现多人协同任务时,因为使用RPC传递消息.RPC即远程过程调用,对于它的使用,第一反应的问题就是如果连续两次调用RPC,RPC的函数会顺序执行吗?还是只要RPC的消 ...
- 给Pomelo的聊天室添加time的RPC调用
为了练手,给聊天应用增加一个rpc调用和一个time类型的服务器,在servers/time/remote/timeRemote.js中,添加如下代码: module.exports.getCurre ...
- [svc]简单理解什么是rpc调用?跟restapi有何区别?
什么是rpc调用 restapi调用方式是对数据的crud. 常见的我们写flash写个api,或者借助django drf写个标准的resetapi,一个url可以借助httpget post pu ...
- RPC调用与GC垃圾回收
RPC调用 多个服务协同完成一次业务时,由于业务约束(如红包不符合使用条件.账户余额不足等).系统故障(如网络或系统超时或中断.数据库约束不满足等),都可能造成服务处理过程在任何一步无法继续,使数据处 ...
- rpc调用过程
在openstack中,各个组件之间的调用遵循RESTful风格,而组件内部各服务之间的相互调用采用rpc远程调用,比如nova-conductor和nova-compute rpc原理: 首先了解什 ...
- 浅谈RPC调用
RPC英文全称remote procedure call 翻译成中文的意思就是远程过程调用.RPC的出现其实主要是为了解决分布式系统间的通信透明性的问题. 那什么是分布式系统的通信透明性问题?这个问题 ...
随机推荐
- 动态生成navmeshi-进击的新版NavMesh系统:看我飞檐走壁
http://forum.china.unity3d.com/thread-25421-1-1.html0x00 前言 unity5.6作为Unity5最后的一个版本,的确起到了一个承上启下的作用.除 ...
- 51nod1153(dfs/单调队列)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1153 题意:中文题诶- 思路:一个比较简单的方法是dfs隐式 ...
- 2017-9-12 NOIP模拟赛[hkd]
NOIP 2017 全假模拟冲刺 T1 Spfa 题目描述B 国在耗资百亿元之后终于研究出了新式武器——连环阵(Zenith ProtectedLinked Hybrid Zone).传说中,连环阵是 ...
- 18.使用for循环计算+1-3+5-7+9-11+13...99的结果
j = 1 # -1 num1 = 0 #1-3 for i in range(1,100,2): num1 += j * i # -3 j = j * -1 # 1 print(num1) sum1 ...
- SpringBoot(1)—启动原理之SpringApplication对象的创建
创建SpringApplication对象 SpringBoot版本为 2.1.1.RELEASE @SpringBootApplication public class SpringbootDemo ...
- Delphi调用C# 编写dll动态库
Delphi调用C# 编写dll动态库 编写C#dll的方法都一样,首先在vs2005中创建一个“类库”项目WZPayDll, using System.Runtime.InteropServices ...
- kettle的使用(ETL,数据仓库技术)
本周项目上用到了kettle并且需要做任务调度,听老师说用kettle自带的调度不大稳定于是便baidu了下,参照这篇文章完成了通过kitchen的调度,简单说就是通过windows的计划任务来调用. ...
- 058 Length of Last Word 最后一个单词的长度
给定一个字符串, 包含大小写字母.空格 ' ',请返回其最后一个单词的长度.如果不存在最后一个单词,请返回 0 .注意事项:一个单词的界定是,由字母组成,但不包含任何的空格.案例:输入: " ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(下)
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/12/es-code03/ 前提 上篇文章写完了 ES 流程启动的一部分,main 方法都入 ...
- PHP+Mysql+jQuery找回密码
通常所说的密码找回功能不是真的能把忘记的密码找回,因为我们的密码是加密保存的,一般开发者会在验证用户信息后通过程序生成一个新密码或者生成一个特定的链接并发送邮件到用户邮箱,用户从邮箱链接到网站的重置密 ...