使用 httputils + protostuff 实现高性能 rpc

1、先讲讲 protostuf

protostuf 一直是高性能序列化的代表之一。但是用起来,可难受了,你得先申明 protostuf 配置文件,并且要把这个配置文件转成类。所以必然要学习新语法、新工具。

可能真的太难受了!于是乎,(有不爽的人)搞了个有创意的框架 protostuff(多一个字母"f")。它借用注解,替代了 protostuf 文件申明和生成类的过程,丰常的接地气。

2、再讲讲 rpc

一讲 rpc ,很多人会想到 dubbo (国产)和 grpc。估计还会联想到注册与发现服务;可能还会联想到微服务。可能就会觉得这个事儿"老重啦",害怕!

其实很简单的,你请求一次 http 就是个 rpc 请求了(远程过程调用嘛)。最典型的就是 http + json 请求了。

3、现在讲 httputils + protostuff

这里我们会用到两个重要的 solon 框架的插件:一个是 httputils 工具插件,一个是 protostuff 序列化插件。

xml 复制代码
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-serialization-protostuff</artifactId>
</dependency>

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-net-httputils</artifactId>
</dependency>

这里要感谢 solon 框架,它强调三元合一(mvc 与 rpc 是自然一体的)。下面,开始干活啦...

  • 公用包(也可以在客户端,服务端分别定义实体类。只要 @Tag 顺序与类型对应上即可 )

这里定义一个 protostuff 实体类。注意 @Tag 注解,它是替代 protostuf 配置文件的关键。

java 复制代码
@Setter
@Getter
public class MessageDo {
    @Tag(1)    // Protostuff 注解,顺序位从 1 开始
    private long id;
    @Tag(2)
    private String title;
}
  • 服务端(只支持 @Body 数据接收,只支持实体类)

在 solon web 项目里,添加一个控制器(注解可以用 @Remoting@Controller)。使用 @Remoting 时,方法上不需要加 @Mapping 注解。

yaml 复制代码
#添加插件
org.noear:solon-web
org.noear:solon-serialization-protostuff
java 复制代码
@Mapping("/rpc/demo")
@Remoting
public class HelloServiceImpl {
    @Override
    public MessageDo hello(@Body MessageDo message) { //还可接收路径变量,与请求上下文
        return message;
    }
}
  • 客户端应用 for HttpUtils(只支持 body 数据提交,只支持实体类)
yaml 复制代码
#添加插件
org.noear:solon-net-httputils
java 复制代码
//应用代码
@Component
public class DemoCom {
    public MessageDo hello() {
        MessageDo message = new MessageDo();
        message.setId(3);
        
        //指明请求数据为 PROTOBUF,接收数据要 PROTOBUF
        return HttpUtils.http("http://localhost:8080/rpc/demo/hello")
                .serializer(ProtostuffBytesSerializer.getInstance())
                .header(ContentTypes.HEADER_CONTENT_TYPE, ContentTypes.PROTOBUF_VALUE)
                .header(ContentTypes.HEADER_ACCEPT, ContentTypes.PROTOBUF_VALUE)
                .bodyOfBean(message)
                .postAs(MessageDo.class);
    }
}

4、总结

总体上,跟 json 没什么大的区别。主要是指定了:序列化器、内容类型、接收类型,让各端能识别类据类型。

5、也可以使用"注解式 http 客户端"框架

肯定也会有人觉得,一个接口还好,如果有很多接口就要写很多重复的http请求代码了。所以,"注解式 http 客户端" 很重要,这也是很多 rpc 框架流行的原因,就像调用本地接口一样,使用远程接口。

nami 是 solon 框架的 rpc 客户端(或者,注解式 http 客户端),支持各种序列化。(只要是"支持序列化定制"的注解式 http 客户端,用法都差不多)

  • 添加两个依赖包
yaml 复制代码
#添加插件
org.noear:nami-coder-protostuff # protostuff 编解码支持
org.noear:nami-channel-http     # http 请求通道支持,也可以是 socketd(支持 tcp, udp, ws)
  • 代码应用(只支持 body 数据提交,只支持实体类)
java 复制代码
@NamiClient(url = "http://localhost:8080/rpc/demo", headers = {ContentTypes.PROTOBUF, ContentTypes.PROTOBUF_ACCEPT})
public interface HelloService {
    MessageDo hello(@NamiBody MessageDo message);
    //方法2
    //方法3
    //方法4
    //方法5
    //方法6
}

@Component
public class DemoCom {
    @NamiClient //注入
    HelloService helloService;
  
    public MessageDo hello() {
         MessageDo message = new MessageDo();
         message.setId(3);
        
         rerturn helloService.hello(message);
    }
}
相关推荐
qianyuqiye11 天前
NFS 网络文件系统完整实战|原理 + RPC 架构 + 多 Web 集群共享存储
运维·网络·安全·rpc·架构·php
小小龙学IT2 天前
gRPC 开源高性能 RPC 框架深度解析:从 HTTP/2 到跨语言微服务实战
http·rpc·开源
IKUN家族3 天前
Spring IoC&DI
java·spring·rpc
带刺的坐椅3 天前
Solon AOT & Native:三段式编译,从 Java 到原生可执行文件
java·aot·solon·native
带刺的坐椅4 天前
Solon 的日志设计哲学:不只是用 SLF4J 做统一门面
java·logback·solon·log4j2
snow@li4 天前
SpringBoot:全套生命周期全景详解/应用级+Bean级
java·spring boot·rpc
带刺的坐椅7 天前
Hot-Plug 实战:运行期管理 Solon 插件
java·solon·插件·热插拔
老虎海子8 天前
Dockerfile 零基础:指令详解 + Compose 对比 + 前端镜像实战
开发语言·前端·docker·rpc
带刺的坐椅8 天前
Solon I18n:三种解析器,零样板代码
java·国际化·i18n·solon·多语言