十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
花了半天的時(shí)間寫了個(gè)簡(jiǎn)單的rpc框架,是因?yàn)槲易畛蹩磀ubbo源碼的時(shí)候發(fā)現(xiàn)dubbo雖然看起來(lái)很龐大,但是隱隱約約總感覺(jué),其實(shí)其絕大多數(shù)功能,都是基于可擴(kuò)張性和服務(wù)治理的需要而編寫的。我看過(guò)dubbo和grpc的源碼,這兩個(gè)都是非常優(yōu)秀的rpc框架,但是為了讓初學(xué)rpc的同學(xué)能夠快速抓住rpc的核心,所以寫了這篇文章,希望看過(guò)的同學(xué),再次去看dubbo的源碼的時(shí)候,能夠抓住這個(gè)核心去看。
一:rpc協(xié)議的接口
RpcProtocol.java
public interface RpcProtocol {
void export(int port);
Object refer(Class inrerfaceClass,String host, int port);
}
這個(gè)接口類只提供兩個(gè)接口,那是因?yàn)閷?duì)于一個(gè)rpc框架來(lái)說(shuō),本質(zhì)上就只需要兩個(gè)接口,一個(gè)是consumer引用provider的服務(wù),一個(gè)是provider接收到consumer的請(qǐng)求之后對(duì)外暴露服務(wù)。
下面是具體的實(shí)現(xiàn)。代碼不復(fù)雜,可以直接復(fù)制到idea,慢慢調(diào)試
二:rpc協(xié)議的具體實(shí)現(xiàn)
RpcCore.java
public class RpcCore implements RpcProtocol{
private Socket socket;
private ObjectOutputStream objectOutputStream;
private ObjectInputStream objectInputStream;
private ServerSocket serverSocket;
private Map> services=new ConcurrentHashMap>();
private Map> interfaceAtrributes=new ConcurrentHashMap<>();
@Override
public void export(int port){
start(port);
}
@Override
public Object refer(final Class interfaceClass,String host, int port){
connect(host,port);
return Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{interfaceClass},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String interfaceName=interfaceClass.getName();
String fullName= (String) interfaceAtrributes.get(interfaceName).get("fullName");
return get(fullName,method,args);
}
});
}
public Object get(String interfaceFullName,Method method,Object[] parames){
Object result=null;
try {
objectOutputStream.writeUTF(interfaceFullName);
objectOutputStream.writeUTF(method.getName());
objectOutputStream.writeObject(method.getParameterTypes());
objectOutputStream.writeObject(parames);
objectOutputStream.flush();
result=objectInputStream.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (objectOutputStream!=null) {
objectOutputStream.close();
}
if (objectInputStream!=null) {
objectInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
private void start(int port) {
try {
serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("localhost", port));
init();
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
System.out.println("server has started success port is --->"+port);
Socket socket = null;
try {
socket = serverSocket.accept();
new Thread(new Processsor(socket,services)).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void init(){
RpcDemo rpcDemo=new RpcDemoImplProvider();
String group="rpcDemo";
String version="1.0.0";
String fullName=RpcDemo.class.getName()+"&"+group+"&"+version;
List
三:rpc測(cè)試的接口
所謂接口說(shuō)白了就是協(xié)議,與http,mqtt等其他的協(xié)議本質(zhì)上沒(méi)什么區(qū)別,只不過(guò)rpc是強(qiáng)依賴,而后兩個(gè)是弱依賴而已,另外之所以把實(shí)體作為內(nèi)部類,是為了表達(dá)一種思想,rpc的實(shí)體類和異常都是協(xié)議的一部分,應(yīng)該將他們放到一起。
Rpcdemo.java
public interface RpcDemo {
Student getStudent(Integer id,String name);
class Student implements Serializable{
public long id;
public String name;
public int age;
public boolean man;
public Student(long id, String name, int age, boolean man) {
this.id = id;
this.name = name;
this.age = age;
this.man = man;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isMan() {
return man;
}
public void setMan(boolean man) {
this.man = man;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", man=" + man +
'}';
}
}
}
四:接口的實(shí)現(xiàn):
RpcDemoImplProvider.java
public class RpcDemoImplProvider implements RpcDemo{
public Student getStudent(Integer id,String name){
return new Student(1234,"zhangsan",20,true);
}
public static void main(String[] args) {
RpcCore rpcCore=new RpcCore();
rpcCore.export(8087);
}
}
五:RpcDemoConsumer.java
消費(fèi)端。
public class RpcDemoConsumer {
public static void main(String[] args) {
RpcCore rpcCore=new RpcCore();
RpcDemo rpcDemo = (RpcDemo)rpcCore.refer(RpcDemo.class, "127.0.0.1", 8087);
System.out.println(" 遠(yuǎn)程調(diào)用成功");
System.out.println("返回的結(jié)果是---->"+rpcDemo.getStudent(111,"zhangsan"));
}
}
六:先啟動(dòng)RpcDemoImplProvider
七:?jiǎn)?dòng)RpcDemoConsumer
總共也就250行代碼左右。over
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。