首页 > 范文大全 > 申报材料 正文
【java精品课申报】Java internet体系结构-实现1000万级流量体系结构所需的手写RPC框架

时间:2023-03-10 13:27:07 阅读: 评论: 作者:佚名

欢迎登上头条:Java Little Margo

周一到周日早上9:30!下午三点半!精品技术文章请准时发送!

精品学习资料获取通道见文末

用手把手写RPC给你。

什么是1.1 RPC

定义:远程过程调用协议(RPC)——远程过程调用协议,RPC协议假定存在某些传输协议(如TCP或UDP),以便在通信程序之间传递信息数据。在OSI网络通信模型中,RPC跨越传输层和应用层,RPC使开发应用程序(包括网络分布式多程序)变得更加容易。

我的理解:最好以客户端/服务器交互模式查看RPC,而不是以协议查看,但RPC必须基于TCP或其他通信协议。

现在,让我们看一下RPC调用过程中涉及的通信详细信息。

服务消费者(客户端)调用将作为本地调用调用服务。(1)客户端存根负责在收到调用后将方法、参数等汇编成可以进行网络传输的消息正文。(2)客户端存根找到服务地址,向服务端发送消息。(3)server stub收到消息后对其进行解码。(4)服务器存根根据解码结果调用本地服务。(5)本地服务将运行,结果将返回到serverstub。(6)server stub将返回结果包装成消息发送给消费者。(7)客户端存根接收和解码消息。(8)服务消费者取得了最终结果。(9)RPC的目标是封装2-8个步骤,使用户对这些细节透明。

1.2手动实施

1.2.1首先创建null接口以实现序列化接口

public interface irpc service extends serial izable {

}

1.2.2创建需要远程调用的接口及其接口实现类

public interface ihello service extends irpc service {

String sayhi(字串名称,字串讯息);

}

public class hello service implements ihello service {

private static final long serial versionuid=146468468464364698 l;

@Override

Public string sayhi(字串名称,字串讯息){

Return new stringbuilder()。append ('hi ~!'))。append('')。append (message)。tostring();

}

}

1.2.3需要编写服务器端,以执行服务注册(接口注册),接收客户端的调用参数,并返回调用请求执行结果

注意:此处没有用dom4j解析概要文件注册接口。有时间的朋友可以再加一层。

Public interface Server {

//插座端口

Int PORT=8080

//服务器端启动

void start()throws io exception;

//停止服务器端

void stop();

/* *

*服务登记

*-服务接口外部暴露接口

* -内部实施类

*/

Void regist(Class)?extends irpc service service interface,class?扩展irpcservice impl

);

}

public class ServerCenter implements Server{

/**线程池 接收客户端调用**/

private static ThreadPoolexecutor executor = new ThreadPoolExecutor(5, 20, 200, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));

/**服务注册缓存**/

public static final Map<String,Class<?>> serviceRegistry = new HashMap<>();

/**

* 启动服务

*/

@Override

public void start() throws IOException {

ServerSocket server = new ServerSocket();

(new InetSocketAddress(PORT));

try {

while(true){

execu(new ServiceTask()));

}

} finally {

();

}

}

/**

* 停止服务

*/

@Override

public void stop() {

execu();

}

/**

* 注册服务

*/

@Override

public void regist(Class<? extends IRpcService> serviceInterface, Class<? extends IRpcService> impl) {

(), impl);

}

private static class ServiceTask implements Runnable{

Socket client = null;

public ServiceTask(Socket client) {

= client;

}

@Override

public void run() {

ObjectInputStream input = null;

ObjectoutputStream output = null;

try {

input = new ObjectInputStream());

String serviceName = in();

String methodName = in();

Class<?>[] parameterTypes = (Class<?>[]) in();

Object[] arguments = (Object[]) in();

Class<?> serviceClass = (serviceName);

if(serviceClass == null){

throw new ClassNotFoundException(serviceName + "not found");

}

Method method = (methodName, parameterTypes);

Object result = me(), arguments);

//将执行结果反序列化 通过socket返给客户端

output = new ObjectOutputStream());

ou(result);

} catch (Exception e) {

e.printStackTrace();

} finally {

if(input != null){

try {

in();

} catch (IOException e) {

e.printStackTrace();

}

}

if(output != null){

try {

out();

} catch (IOException e) {

e.printStackTrace();

}

}

if(client != null){

try {

client.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

public static void main(String[] args) throws Exception {

ServerCenter center = new ServerCenter();

cen HelloServiceImpl().getClass());

cen();

}

}

1.2.4 写一个客户端,用动态代理 获取被代理接口的 各种参数 传输给 服务端,接收返回结果,打印到控制台

public class Client {

@SuppressWarnings("unchecked")

public static <T extends IRpcService>T getRemoteProxyObj(final Class<? extends IRpcService> serviceInterface,final InetSocketAddress addr){

return (T) Proxy.newProxyInstance(), new Class<?>[]{serviceInterface}, new InvocationHandler() {

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

Socket socket = null;

ObjectOutputStream output = null;

ObjectInputStream input = null;

try {

//1.创建Socket客户端,根据指定地址连接远程服务提供者

socket = new Socket();

(addr);

//2.将远程服务调用所需的接口类、方法名、参数列表等编码后发送给服务提供者

output = new ObjectOutputStream());

ou());

ou());

ou());

ou(args);

//3.同步阻塞等待服务器返回应答 获取应答后返回

input = new ObjectInputStream());

return in();

} finally{

if(socket != null){

();

}

if(output != null){

out();

}

if(input != null){

in();

}

}

}

});

}

}

1.2.5 测试

注:测试之前 需要开启服务端

public class RpcTest {

public static void main(String[] args) throws IOException {

IHelloService service = Client.getRemoteProxyObj, new InetSocketAddress(8080));

Sy("张三", "新年快乐!"));

}

}

就这样我们实现了一个简陋的RPC

本文意在通过实现简单的RPC,去真正意义上对RPC框架的实现原理有初步的了解,而不是人云亦云。

此RPC实现有诸多缺点,但是 我们只要明白RPC的基座 其他的RPC框架只是完善基座以及扩展而已 。

rpc简单实现git代码地址

封面图源网络,侵权删除)

私信头条号,发送:“资料”,获取更多“秘制” 精品学习资料

如有收获,请帮忙转发,您的鼓励是作者最大的动力,谢谢!

一大波微服务、分布式、高并发、高可用的原创系列文章正在路上,

欢迎关注头条号:java小马哥

周一至周日早九点半!下午三点半!精品技术文章准时送上!!!

十余年BAT架构经验倾囊相授

精品推荐:Java架构师,Java直播课 |打造一线互联网java架构师

地址:

(复制链接到浏览器即可)

> 看到这里,说明你喜欢本文,你的转发,是对我最大的鼓励!在看亦是支持↓

  • 评论列表

发表评论: