RPCプロトコル
10172 ワード
一、RPC協議とは何ですか?
深く浅くRPCを出す
三、RPC簡単判例参考
JSON**データ転送**に基づくRPCフレームを採用することができます。BIOの代わりにNettyを使って、NIOを使っても良いです。Hadoop AvroとGoogle protobufなどのオープンソースのプログレッシブメカニズムを使用します。サービス登録はZookeeperで管理できます。アプリケーションをより安定させることができます。
RPC, Remote Procedure Call, , 。
。 。
RMI( )、Hessian、Http invoker 。
,RPC 。
二、RPC構造分解深く浅くRPCを出す
三、RPC簡単判例参考
public class HelloServiceImpl implements HelloService {
@Override
public String sayHi(String name) {
return "Hi, " + name;
}
}
public class ServiceCenter implements Server {
private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private static final HashMap serviceRegistry = new HashMap();
private static boolean isRunning = false;
private static int port;
public ServiceCenter(int port) {
this.port = port;
}
public void stop() {
isRunning = false;
executor.shutdown();
}
public void start() throws IOException {
ServerSocket server = new ServerSocket();
server.bind(new InetSocketAddress(port));
System.out.println("start server");
try {
while (true) {
// 1. TCP , TCP task,
executor.execute(new ServiceTask(server.accept()));
}
} finally {
server.close();
}
}
public void register(Class serviceInterface, Class impl) {
serviceRegistry.put(serviceInterface.getName(), impl);
}
public boolean isRunning() {
return isRunning;
}
public int getPort() {
return port;
private static class ServiceTask implements Runnable {
Socket clent = null;
public ServiceTask(Socket client) {
this.clent = client;
}
public void run() {
ObjectInputStream input = null;
ObjectOutputStream output = null;
try {
// 2. , ,
input = new ObjectInputStream(clent.getInputStream());
String serviceName = input.readUTF();
String methodName = input.readUTF();
Class>[] parameterTypes = (Class>[]) input.readObject();
Object[] arguments = (Object[]) input.readObject();
Class serviceClass = serviceRegistry.get(serviceName);
if (serviceClass == null) {
throw new ClassNotFoundException(serviceName + " not found");
}
Method method = serviceClass.getMethod(methodName, parameterTypes);
Object result = method.invoke(serviceClass.newInstance(), arguments);
// 3. , socket
output = new ObjectOutputStream(clent.getOutputStream());
output.writeObject(result);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (clent != null) {
try {
clent.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public class RPCClient {
@SuppressWarnings("unchecked")
public static T getRemoteProxyObj(final Class> serviceInterface, final InetSocketAddress addr) {
// 1. JDK ,
return (T) Proxy.newProxyInstance(serviceInterface.getClassLoader(), new Class>[]{serviceInterface},
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket socket = null;
ObjectOutputStream output = null;
ObjectInputStream input = null;
try {
// 2. Socket ,
socket = new Socket();
socket.connect(addr);
// 3. 、 、
output = new ObjectOutputStream(socket.getOutputStream());
output.writeUTF(serviceInterface.getName());
output.writeUTF(method.getName());
output.writeObject(method.getParameterTypes());
output.writeObject(args);
// 4. ,
input = new ObjectInputStream(socket.getInputStream());
return input.readObject();
} finally {
if (socket != null) socket.close();
if (output != null) output.close();
if (input != null) input.close();
}
}
});
}
}
public class RPCTest {
@Test
public void product() throws IOException{
Server serviceServer = new ServiceCenter(8088);
serviceServer.register(HelloService.class, HelloServiceImpl.class);
serviceServer.start();
}
@Test
public void consume(){
HelloService service = RPCClient.getRemoteProxyObj(HelloService.class, new InetSocketAddress("localhost", 8088));
System.out.println(service.sayHi("test"));
}
}
実例まとめ:ここで実現される簡単なRPCのフレームワークはJava言語を使って開発され、Java言語と高度に結合され、そして通信方式に採用されているSocketはBIOに基づいて実現されたもので、IOの効率は高くない。次のいくつかの方法から改善することが考えられます。JSON**データ転送**に基づくRPCフレームを採用することができます。BIOの代わりにNettyを使って、NIOを使っても良いです。Hadoop AvroとGoogle protobufなどのオープンソースのプログレッシブメカニズムを使用します。サービス登録はZookeeperで管理できます。アプリケーションをより安定させることができます。