1、先講講 protobuf
protobuf 一直是高效能序列化的代表之一(google 出品)。但是用起來,可難受了,你得先申明 “.proto” 配置檔案,並且要把這個配置檔案編譯轉成類。所以必然要學習新語法、新工具。
可能真的太難受了!於是乎,(有不爽的人)搞了個有創意的框架 protostuff(“buf” 變成 "stuff")。它借用註解,替代了 “.proto” 檔案申明和生成類的過程,豐常的接地氣。
2、再講講 rpc
一講 rpc ,很多人會想到 dubbo (國產)和 grpc。估計還會聯想到註冊與發現服務;可能還會聯想到微服務。可能就會覺得這個事兒“老重啦”,害怕!
其實很簡單的,你請求一次 http 就是個 rpc 請求了(遠端過程呼叫嘛)。最典型的就是 http + json 請求了。
3、現在講 httputils + protostuff
這裡我們會用到兩個重要的 solon 框架的外掛:一個是 httputils 工具外掛,一個是 protostuff 序列化外掛。
<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
註解,它是替代 “.proto” 配置檔案的關鍵。
@Setter
@Getter
public class MessageDo {
@Tag(1) // Protostuff 註解,順序位從 1 開始
private long id;
@Tag(2)
private String title;
}
- 服務端(只支援 @Body 資料接收,只支援實體類)
在 solon web 專案裡,新增一個控制器(註解可以用 @Remoting
或 @Controller
)。使用 @Remoting
時,方法上不需要加 @Mapping
註解。
#新增外掛
org.noear:solon-web
org.noear:solon-serialization-protostuff
@Mapping("/rpc/demo")
@Remoting
public class HelloServiceImpl {
@Override
public MessageDo hello(@Body MessageDo message) { //還可接收路徑變數,與請求上下文
return message;
}
}
- 客戶端應用 for HttpUtils(只支援 body 資料提交,只支援實體類)
#新增外掛
org.noear:solon-net-httputils
//應用程式碼
@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 客戶端,都可用!)
- 新增兩個依賴包
#新增外掛
org.noear:nami-coder-protostuff # protostuff 編解碼支援
org.noear:nami-channel-http # http 請求通道支援,也可以是 socketd(支援 tcp, udp, ws)
- 程式碼應用(只支援 body 資料提交,只支援實體類)
@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);
}
}