中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中RPC的原理是什么

發布時間:2021-08-09 14:10:53 來源:億速云 閱讀:110 作者:Leah 欄目:云計算

這篇文章將為大家詳細講解有關Java中RPC的原理是什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

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的原理是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

佳木斯市| 清丰县| 桑植县| 修武县| 体育| 镇坪县| 温宿县| 西乌珠穆沁旗| 天祝| 蒙城县| 广宁县| 盐边县| 望谟县| 勐海县| 澄江县| 手游| 抚州市| 西乡县| 瑞安市| 襄樊市| 株洲县| 阳东县| 百色市| 凤山县| 泾源县| 阜新| 集贤县| 修文县| 阿鲁科尔沁旗| 金平| 桓仁| 娄底市| 西乌珠穆沁旗| 永川市| 百色市| 濉溪县| 游戏| 嵊州市| 岚皋县| 和硕县| 乌拉特中旗|