什麼是 RPC
由于各服務部署在不同機器,服務間的調用免不了網絡通信過程,服務消費方每調用一個服務都要寫一坨網絡通信相關的代碼,不僅複雜而且極易出錯。
如果有一種方式能讓我們像調用本地服務一樣調用遠端服務,而讓調用者對網絡通信這些細節透明,那麼将大大提高生産力,比如服務消費方在執行helloWorldService.sayHello(“test”)時,實質上調用的是遠端的服務。這種方式其實就是RPC(Remote Procedure Call Protocol),在各大網際網路公司中被廣泛使用,如阿裡巴巴的hsf、dubbo(開源)、Facebook的thrift(開源)、Google grpc(開源)、Twitter的finagle(開源)等。
RPC 是遠端過程調用(Remote Procedure Call)的縮寫形式,Birrell 和 Nelson 在 1984 發表于 ACM Transactions on Computer Systems 的論文《Implementing remote procedure calls》對 RPC 做了經典的诠釋。RPC 是指計算機 A 上的程序,調用另外一台計算機 B 上的程序,其中 A 上的調用程序被挂起,而 B 上的被調用程序開始執行,當值傳回給 A 時,A 程序繼續執行。調用方可以通過使用參數将資訊傳送給被調用方,而後可以通過傳回的結果得到資訊。而這一過程,對于開發人員來說是透明的。
模拟RPC
API接口
package com.xueqing.demo.test.rpc;
public interface Barty {
public static final long versionID = 10010;
public String sayHi(String name);
}
RPCServer
package com.xueqing.demo.test.rpc;
import java.io.IOException;
import org.apache.hadoop.HadoopIllegalArgumentException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.RPC.Server;
public class RPCServer implements Barty{
public static void main(String[] args) throws HadoopIllegalArgumentException, IOException {
Server server = new RPC.Builder(new Configuration())
.setInstance(new RPCServer())
.setBindAddress("192.168.8.100")
.setPort(9527)
.setProtocol(Barty.class)
.build();
server.start();
}
public String sayHi(String name) {
// TODO Auto-generated method stub
return "HI~" + name;
}
}
RPCClient
package com.xueqing.demo.test.rpc;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
public class RPCClient {
public static void main(String[] args) throws IOException {
Barty proxy = RPC.getProxy(Barty.class, 10010,
new InetSocketAddress("192.168.8.100", 9527), new Configuration());
String sayHi = proxy.sayHi("tomcat");
System.out.println(sayHi);
}
}