您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Java中RPC的原理是什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
package com.wish.RPC; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; /** * RPC原理解析: * 服務器端: * 1、RPCServer#registService:主要作用就是提供了一個服務注冊管理中心, * 用來保存被注冊服務(如果是dubbo則是分布式服務框架,對應了不同機器的地址及端口發布的服務(dubbo還使用了zookeeper)) * 2、RPCServer#startServer:開啟一個ServerSocket連接(new 一個ServiceTask服務,使用線程循環監聽等待), * 等待客戶端的遠程socket連接調用 * 3、RPCServer#registService:定義一個注冊服務接口。即將所有需要注冊的服務保存起來,后續ServiceTask需要使用該接口對象, * 動態代理調用該接口對象方法,并將方法返回值通過socket網絡通信方式,傳遞給該服務的Client客戶端。 * * 客戶端: * 1、RPCClient#findService:根據serviceInterface接口名,通過動態代理生成被請求對象及通過InvocationHandler調用遠程方法。 * 其中InvocationHandler里面,通過傳入的ip和prot地址,開啟一個socket連接,遠程發送調用遠端RPCServer注冊的服務方法 * 然后通過遠端RPCServer,的socket連接,講返回對象通過socket網絡通信傳遞過來,這樣即獲取到了遠端服務的返回結果。 * * 啟動服務端: * 1、TestRPCServer#main:啟動服務端,通過server.registService(new HelloWorld()) ; * 注冊HelloWorld服務方法到RPCServer * 2、TestRPCServer#main:通過server.startServer(51234);啟動RPCServer,監聽來自client的socket請求 * * 啟動客戶端: * 1、TestRPCClient#main:通過RPCClient.findService("127.0.0.1" , 51234 , IHelloWorld.class); * 調用客戶端findService,獲取HelloWorld對象,接下來即可以像使用本地一樣使用遠程服務方法 * * PS:更多源碼請訪問:http://git.oschina.net/tantexian/wishRPC * * @author tantexian<tantexian@qq.com> * @since 2016年5月27日 上午9:44:46 */ public class RPCServer { private static final ExecutorService taskPool = Executors.newFixedThreadPool(50); /** * 服務接口對象庫 key:接口名 value:接口實現 */ private static final ConcurrentHashMap<String, Object> serviceTargets = new ConcurrentHashMap<String, Object>(); private static AtomicBoolean run = new AtomicBoolean(false); /** * 注冊服務 * * @param service */ public void registService(Object service) { Class<?>[] interfaces = service.getClass().getInterfaces(); if (interfaces == null) { throw new IllegalArgumentException("服務對象必須實現接口"); } Class<?> interfacez = interfaces[0]; String interfaceName = interfacez.getName(); serviceTargets.put(interfaceName, service); } /** * 啟動Server * * @param port */ public void startServer(final int port) { Runnable lifeThread = new Runnable() { @Override public void run() { ServerSocket lifeSocket = null; Socket client = null; ServiceTask serviceTask = null; try { lifeSocket = new ServerSocket(port); run.set(true); while (run.get()) { client = lifeSocket.accept(); serviceTask = new ServiceTask(client); serviceTask.accept(); } } catch (IOException e) { e.printStackTrace(); } } }; taskPool.execute(lifeThread); System.out.println("服務啟動成功..."); } public void stopServer() { run.set(false); taskPool.shutdown(); } public static final class ServiceTask implements Runnable { private Socket client; public ServiceTask(Socket client) { this.client = client; } public void accept() { taskPool.execute(this); } @Override public void run() { InputStream is = null; ObjectInput oi = null; OutputStream os = null; ObjectOutput oo = null; try { is = client.getInputStream(); os = client.getOutputStream(); oi = new ObjectInputStream(is); String serviceName = oi.readUTF(); String methodName = oi.readUTF(); Class<?>[] paramTypes = (Class[]) oi.readObject(); Object[] arguments = (Object[]) oi.readObject(); System.out.println("serviceName:" + serviceName + " methodName:" + methodName); Object targetService = serviceTargets.get(serviceName); if (targetService == null) { throw new ClassNotFoundException(serviceName + "服務未找到!"); } Method targetMethod = targetService.getClass().getMethod(methodName, paramTypes); Object result = targetMethod.invoke(targetService, arguments); oo = new ObjectOutputStream(os); oo.writeObject(result); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } finally { try { if (oo != null) { oo.close(); } if (os != null) { os.close(); } if (is != null) { is.close(); } if (oi != null) { oi.close(); } } catch (IOException e) { e.printStackTrace(); } } } } } package com.wish.RPC; import java.io.InputStream; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.Socket; public class RPCClient { /** * 根據接口類型得到代理的接口實現 * @param <T> * @param host RPC服務器IP * @param port RPC服務端口 * @param serviceInterface 接口類型 * @return 被代理的接口實現 */ @SuppressWarnings("unchecked") public static <T> T findService(final String host , final int port ,final Class<T> serviceInterface){ return (T) Proxy.newProxyInstance(serviceInterface.getClassLoader(), new Class[]{serviceInterface}, new InvocationHandler() { @SuppressWarnings("resource") @Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { Socket socket = null ; InputStream is = null ; OutputStream os = null ; ObjectInput oi = null ; ObjectOutput oo = null ; try { socket = new Socket(host, port) ; os = socket.getOutputStream() ; oo = new ObjectOutputStream(os); oo.writeUTF(serviceInterface.getName()) ; oo.writeUTF(method.getName()) ; oo.writeObject(method.getParameterTypes()) ; oo.writeObject(args); is = socket.getInputStream() ; oi = new ObjectInputStream(is) ; return oi.readObject() ; } catch (Exception e) { System.out.println("調用服務異常..."); return null ; }finally{ if(is != null){ is.close() ; } if(os != null){ is.close() ; } if(oi != null){ is.close() ; } if(oo != null){ is.close() ; } if(socket != null){ is.close() ; } } } }); } } package com.wish.RPC; public class HelloWorld implements IHelloWorld { @Override public String sayHello(String name) { return "Hello, " + name; } } package com.wish.RPC; public interface IHelloWorld { String sayHello(String name); } package com.wish.RPC; public class TestRPCServer { public static void main(String[] args) { RPCServer server = new RPCServer() ; server.registService(new HelloWorld()) ; server.startServer(51234) ; } } package com.wish.RPC; public class TestRPCClient { public static void main(String[] args) { IHelloWorld helloWorld = RPCClient.findService("127.0.0.1" , 51234 , IHelloWorld.class) ; String result = helloWorld.sayHello("tantexian, My blog address is: http://my.oschina.net/tantexian/"); System.out.println(result ); } }
關于Java中RPC的原理是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。