RPC(Remote Procedure Call Protocol)——遠程過程調用協議,它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。
RPC采用客戶機/服務器模式。請求程序就是一個客戶機,而服務提供程序就是一個服務器。首先,客戶機調用進程發送一個有進程參數的調用信息到服務進程,然后等待應答信息。在服務器端,進程保持睡眠狀態直到調用信息到達為止。當一個調用信息到達,服務器獲得進程參數,計算結果,發送答復信息,然后等待下一個調用信息,最后,客戶端調用進程接收答復信息,獲得進程結果,然后調用執行繼續進行。
以上是百度百科對RPC的解釋。
一個通俗的描述是:客戶端在不知道調用細節的情況下,調用存在于遠程計算機上的某個對象,就像調用本地應用程序中的對象一樣。
RPC(Remote Procedure Call Protocol)——遠程過程調用協議,它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。
RPC采用客戶機/服務器模式。請求程序就是一個客戶機,而服務提供程序就是一個服務器。首先,客戶機調用進程發送一個有進程參數的調用信息到服務進程,然后等待應答信息。在服務器端,進程保持睡眠狀態直到調用信息到達為止。當一個調用信息到達,服務器獲得進程參數,計算結果,發送答復信息,然后等待下一個調用信息,最后,客戶端調用進程接收答復信息,獲得進程結果,然后調用執行繼續進行。
以上是百度百科對RPC的解釋。
一個通俗的描述是:客戶端在不知道調用細節的情況下,調用存在于遠程計算機上的某個對象,就像調用本地應用程序中的對象一樣。
早期單機時代,一臺電腦上運行多個進程,大家各干各的,老死不相往來。假如A進程需要一個畫圖的功能,B進程也需要一個畫圖的功能,程序員就必須為兩個進程都寫一個畫圖的功能。這不是整人么?于是就出現了IPC(Inter-process communication,單機中運行的進程之間的相互通信)。OK,現在A既然有了畫圖的功能,B就調用A進程上的畫圖功能好了。
到了網絡時代,大家的電腦都連起來了。以前程序只能調用自己電腦上的進程,能不能調用其他機器上的進程呢?于是就程序員就把IPC擴展到網絡上,這就有了RPC。
這個時候畫圖功能就可以作為一個獨立的服務提供給客戶機使用。
既然是協議就只是一套規范,那么就需要有人遵循這套規范來進行實現。目前典型的RPC實現包括:Dubbo、Thrift、GRPC、Hetty等。
既然RPC的客戶端認為自己是在調用本地對象。那么傳輸層使用的是TCP/UDP還是HTTP協議,者是一些其他的網絡協議它就不需要關心了。既然網絡協議對其透明,那么調用過程中,使用的是哪一種網絡IO模型調用者也不需要關心。
在本地應用程序中,對象調用需要傳遞一些參數,會返回一個調用結果。對象內部是如何使用這些參數,并計算出處理結果的,調用方是不需要關心的。那么對于RPC來說,這些參數會以某種信息格式傳遞給網絡上的另外一臺計算機,這個信息格式是怎樣構成的,調用方是不需要關心的。
調用方實際上也不清楚遠程服務器的應用程序是使用什么語言運行的。那么對于調用方來說,無論服務器方使用的是什么語言,本次調用都應該成功,并且返回值也應該按照調用方程序語言所能理解的形式進行描述。
1. 調用客戶端句柄;執行傳送參數
2. 調用本地系統內核發送網絡消息
3. 消息傳送到遠程主機
4. 服務器句柄得到消息并取得參數
5. 執行遠程過程
6. 執行的過程將結果返回服務器句柄
7. 服務器句柄返回結果,調用遠程系統內核
8. 消息傳回本地主機
9. 客戶句柄由內核接收消息
10. 客戶接收句柄返回的數據
1、 設計對外的接口
public interface IService extends Remote {
public String queryName(String no) throws RemoteException;
}
2、 服務端的服務實現
public class ServiceImpl extends UnicastRemoteObject implements IService {
private static final long serialVersionUID = 682805210518738166L;
protected ServiceImpl() throws RemoteException {
super();
}
@Override
public String queryName(String no) throws RemoteException {
// 方法的具體實現
return String.valueOf(System.currentTimeMillis());
}
}
3、 RMI服務端實現
public class Server {
public static void main(String[] args) {
Registry registry = null;
try {
// 創建一個服務注冊管理器
registry = LocateRegistry.createRegistry(8088);
} catch (RemoteException e) {
}
try {
// 創建一個服務
ServiceImpl server = new ServiceImpl();
// 將服務綁定命名
registry.rebind("vince", server);
} catch (RemoteException e) {
}
}
}
4、 客戶端實現
public class Client {
public static void main(String[] args) {
Registry registry = null;
try {
// 獲取服務注冊管理器
registry = LocateRegistry.getRegistry("127.0.0.1",8088);
} catch (RemoteException e) {
}
try {
// 根據命名獲取服務
IService server = (IService) registry.lookup("vince");
// 調用遠程方法 ,獲取結果。
String result = server.queryName("ha ha ha ha");
} catch (Exception e) {
}
}
}
]]>