W-RPC开发问题
手搓RPC
序列化、反序列化问题
RPC远程调用时,需要将对象进行序列化/反序列化操作。
比如RPC框架的response、request对象需要传递给服务提供方/服务消费方。所以需要对RPC的response、request对象进行序列化、反序列化操作。
实现方式:
- 第三方序列化框架
- 推荐。比较方便,但是该项目不需要太复杂,所以暂不使用。
- 继承Serializable接口
Serializable
接口本身不包含任何方法或字段,它是一个标记接口(marker interface)- 具体的序列化方法主要通过
ObjectOutputStream
和ObjectInputStream
这两个类来完成 - 如果更好的控制序列化过程,还需要使用
writeObject()
和readObject()
方法 - 每一个继承该接口,同时想要精细化控制的类都需要实现
writeObject()
和readObject()
方法
- 自定义一个Serializer序列化器
- 自己定义序列化、反序列化方法,将控制序列化的方法都写在序列化器中,不需要每个类自己写一遍。
1 | package org.example.serializer; |
注意:
- 流的
flush方法
和close方法
flush()
方法的主要作用是立即将缓冲区中的所有数据写入到目标输出流中。这保证了即使在程序异常终止的情况下,已经调用过的方法所要写入的数据能够被保存下来。
close()
方法不仅会调用flush()
方法来清空缓冲区,还会关闭底层的输出流,释放与之关联的所有系统资源。一旦流被关闭,就不能再进行任何读写操作,否则会抛出IOException
。使用建议
在实际编程中,推荐的做法是在完成所有写入操作后,总是调用
close()
方法来关闭流。由于close()
方法内部会调用flush()
,所以通常不需要显式地调用flush()
,除非有特定的需求(例如,在多次写入之间需要立即同步数据)。
消费方发起调用的方法
rpc本质就是远程调用,比如服务提供方A,消费方B、C…,无论消费方有多少,获取提供方A的某个数据所需要的请求代码都是相同的。所以可以采用代理的方法(代理本来要用作方法的增强,在这里直接调用相同的代码逻辑)。
缺点:这样实现的接口UserService
必须在common包里定义,提供方实现这个接口才可以。因为消费方也需要。
评论