Hadoop源码分析8: IPC流程(3)客户端的clients、connections、calls复用
来源:互联网 发布:java算法手册 编辑:程序博客网 时间:2024/05/10 10:31
1. RPCClientCache 中的 clients
private Map<SocketFactory,Client> clients = new HashMap<SocketFactory,Client>(); synchronizedClient getClient(Configuration conf, SocketFactory factory) { // Construct & cacheclient. The configuration is only used fortimeout, // and Clients haveconnection pools. So we can either (a) losesome // connection pooling andleak sockets, or (b) use the same timeout for all // configurations. Since the IPC is usually intended globally,not // per-job, we choose(a). Client client= clients.get(factory); if (client == null) { client =new Client(ObjectWritable.class, conf, factory); clients.put(factory,client); } else { client.incCount(); } return client; }
void stopClient(Clientclient) { synchronized (this) { client.decCount(); if(client.isZeroReference()) { clients.remove(client.getSocketFactory()); } } if (client.isZeroReference()){ client.stop(); } }
privateClientConnectionId remoteId; private Clientclient; private boolean isClosed= false;
public RPCInvoker(Class<? extendsVersionedProtocol> protocol, InetSocketAddress address, UserGroupInformationticket, Configuration conf, SocketFactory factory, int rpcTimeout) throws IOException { this.remoteId = ClientConnectionId.getConnectionId(address,protocol, ticket, rpcTimeout,conf); this.client = RPC.CLIENTS.getClient(conf, factory); }
synchronizedvoid close() { if(!isClosed) { isClosed = true; RPC.CLIENTS.stopClient(client); } }
public staticRPCClientCache CLIENTS=newRPCClientCache();
//for unit testing only staticClient getClient(Configuration conf){ return CLIENTS.getClient(conf); }
public staticObject[] call(Method method, Object[][]params, InetSocketAddress[]addrs, UserGroupInformation ticket,Configuration conf) throws IOException, InterruptedException {
RPCInvocation[] invocations = newRPCInvocation[params.length]; for (int i = 0; i < params.length; i++) invocations[i] = newRPCInvocation(method, params[i]); Client client= CLIENTS.getClient(conf); try { Writable[] wrappedValues= client.call(invocations,addrs, method.getDeclaringClass(), ticket, conf); if (method.getReturnType() == Void.TYPE) { return null; }
Object[] values = (Object[])Array.newInstance(method.getReturnType(),wrappedValues.length); for (int i = 0; i < values.length; i++) if (wrappedValues[i] !=null) values[i]= ((ObjectWritable)wrappedValues[i]).get(); return values; } finally { CLIENTS.stopClient(client); } }
public staticVersionedProtocol getProxy( Class<? extendsVersionedProtocol> protocol, long clientVersion,InetSocketAddress addr, UserGroupInformation ticket, Configuration conf,SocketFactory factory, int rpcTimeout) throws IOException {
if (UserGroupInformation.isSecurityEnabled()){ SaslRpcServer.init(conf); } VersionedProtocol proxy = (VersionedProtocol) Proxy.newProxyInstance( protocol.getClassLoader(),new Class[] { protocol }, newRPCInvoker (protocol, addr, ticket, conf, factory,rpcTimeout)); long serverVersion =proxy.getProtocolVersion(protocol.getName(), clientVersion); if (serverVersion == clientVersion) { return proxy; } else { throw newRPCVersionMismatch(protocol.getName(),clientVersion, serverVersion); } }
public Hashtable<ClientConnectionId, ClientConnection> connections =new Hashtable<ClientConnectionId, ClientConnection>();
public void stop() { .............. // wake up all connections synchronized (connections) { for (ClientConnection conn: connections.values()) { conn.interrupt(); } } // wait until all connections are closed while (!connections.isEmpty()) { try { Thread.sleep(100); } catch (InterruptedExceptione) { } } .................... }
//for unit testing only Set<ClientConnectionId> getConnectionIds(){ synchronized (connections) { return connections.keySet(); } }
privateClientConnection getConnection(ClientConnectionIdremoteId, ClientCall call) throws IOException,InterruptedException { if (!running.get()) { // the client isstopped throw new IOException("Theclient is stopped"); } ClientConnection connection; do { synchronized(connections) { connection= connections.get(remoteId); if(connection == null) { connection = newClientConnection(remoteId,this); connections.put(remoteId,connection); } } } while (!connection.addCall(call)); //we don't invoke the method below inside"synchronized (connections)" //block above. The reason for that is if theserver happens to be slow, //it will take longer to establish a connectionand that will slow the //entire system down. connection.setupIOstreams(); return connection; }
private synchronizedvoid close() { if(!shouldCloseConnection.get()) { return; }
// release theresources // first thing to do;take theconnection out of the connection list synchronized(client.connections) { if(client.connections.get(remoteId) == this){ client.connections.remove(remoteId); } } 。。。。。。 }
private Hashtable<Integer,ClientCall> calls = new Hashtable<Integer,ClientCall>(); public synchronizedboolean addCall(ClientCall call) { if(shouldCloseConnection.get()) returnfalse; calls.put(call.id,call); notify(); return true; } private synchronizedboolean waitForWork() { if (calls.isEmpty()&& !shouldCloseConnection.get() && client.running.get()) { longtimeout = maxIdleTime- (System.currentTimeMillis()-lastActivity.get()); if(timeout>0) { try { wait(timeout); } catch (InterruptedException e) {} } } if (!calls.isEmpty()&& !shouldCloseConnection.get() &&client.running.get()) { returntrue; } else if(shouldCloseConnection.get()) { returnfalse; } else if(calls.isEmpty()) { // idle connection closed orstopped markClosed(null); returnfalse; } else { // get stopped butthere are still pending requests markClosed((IOException)new IOException().initCause( newInterruptedException())); returnfalse; } }
privatevoid receiveResponse() { if(shouldCloseConnection.get()) { return; } touch(); try { int id =in.readInt(); // try to read an id
ClientCallcall = calls.get(id);
int state= in.readInt(); // read callstatus if (state== Status.SUCCESS.state) { Writable value =ReflectionUtils.newInstance(client.valueClass, client.conf); value.readFields(in); // read value call.setValue(value); calls.remove(id); } else if(state == Status.ERROR.state) { call.setException(newRemoteException(WritableUtils.readString(in), WritableUtils.readString(in))); calls.remove(id); } else if(state == Status.FATAL.state) { // Close the connection markClosed(newRemoteException(WritableUtils.readString(in), WritableUtils.readString(in))); } } catch (IOException e){ markClosed(e); } } private synchronizedvoid close() { if(!shouldCloseConnection.get()) { return; }
// release theresources // first thing to do;take theconnection out of the connection list synchronized(client.connections) { if(client.connections.get(remoteId) == this) { client.connections.remove(remoteId); } }
// close the streams andtherefore the socket IOUtils.closeStream(out); IOUtils.closeStream(in); disposeSasl();
// clean up all calls if (closeException == null){ if(!calls.isEmpty()) {
// clean up calls anyway closeException = new IOException("Unexpectedclosed connection"); cleanupCalls(); } } else { // log theinfo
// cleanupcalls cleanupCalls(); } }
privatevoid cleanupCalls() { Iterator<Entry<Integer,ClientCall>> itor= calls.entrySet().iterator() ; while (itor.hasNext()){ ClientCallc = itor.next().getValue(); c.setException(closeException); // local exception itor.remove(); } }
public static voidmain(String[] args) throws Exception {
final InetSocketAddress addr =new InetSocketAddress("localhost", final Query query = (Query)RPC.getProxy(Query.class, MyServer.IPC_VER,
new Thread() {
@Override public voidrun() { FileStatusfileStatus1 = query.getFileStatus("/tmp/testIPC"); System.out.println(fileStatus1);
FileStatusfileStatus2 = query.getFileStatus("/tmp/testIPC2"); System.out.println(fileStatus2);
}
}.start();
new Thread() {
@Override public voidrun() { CPUStatus cpuStatus1 =query.getCPUStatus("Intel"); System.out.println(cpuStatus1);
CPUStatus cpuStatus2 =query.getCPUStatus("AMD"); System.out.println(cpuStatus2); }
}.start();
new Thread() {
@Override public voidrun() {
try { Queryquery2 = (Query) RPC.getProxy(Query.class, MyServer.IPC_VER, addr, newConfiguration());
FileStatusfileStatus1 = query2.getFileStatus("/tmp/testIPC"); System.out.println(fileStatus1);
FileStatusfileStatus2 = query2.getFileStatus("/tmp/testIPC2"); System.out.println(fileStatus2); RPC.stopProxy(query2); } catch(IOException e) { e.printStackTrace(); }
}
}.start();
RPC.stopProxy(query); }
publicclass RPCClientCache {
}
以上方法在下列代码中调用:
publicclass RPCInvoker implements InvocationHandler{
}
publicclass RPC {
}
2. Client 的connections
publicclass Client {
}
publicclass ClientConnection extends Thread {
}
3. ClientConnection 的calls
publicclass ClientConnection extends Thread {
}
4.并发执行以下代码
public class MyClient {
MyServer.IPC_PORT);
addr, new Configuration());
}
以上三个线程可以共用同一个 Client对象、ClientConnection线程 、ClientConnectionId对象,将ClientCall放在同一个calls中
0 0
- Hadoop源码分析8: IPC流程(3)客户端的clients、connections、calls复用
- Hadoop源码分析15:IPC流程(10)ClientConnection 复用
- Hadoop源码分析13: IPC流程(8) Server的wait、notify
- Hadoop源码分析7: IPC流程(2) 流程
- Hadoop源码分析16: IPC流程(11) 整体流程
- Hadoop源码分析7: IPC流程(1) 主要类
- Hadoop源码分析10: IPC流程(5) Atomic
- Hadoop源码分析11: IPC流程(6)volatile
- Hadoop源码分析12: IPC流程(7)容器
- Hadoop源码分析14: IPC流程(9) SelectionKey
- Hadoop 中 IPC 的源码分析
- hadoop-1.2.0的IPC源码分析
- Hadoop源码分析9:IPC流程(4) Client 的 wait() 和 notify()
- Hadoop源码分析之IPC机制
- Hadoop源码分析17:IPC中的ThreadLocal
- Hadoop RPC通信Client客户端的流程分析
- hadoop源码解析之hdfs写数据全流程分析---客户端处理
- Hadoop源码分析33 Child的主要流程
- Hadoop源码分析6: RPC基本线程
- Hadoop源码分析6: Buffer 细节
- 联通让“打110”,我该怎么办?
- Hadoop源码分析7: IPC流程(1) 主要类
- Hadoop源码分析7: IPC流程(2) 流程
- Hadoop源码分析8: IPC流程(3)客户端的clients、connections、calls复用
- Hadoop源码分析9:IPC流程(4) Client 的 wait() 和 notify()
- Hadoop源码分析10: IPC流程(5) Atomic
- Hadoop源码分析11: IPC流程(6)volatile
- Hadoop源码分析12: IPC流程(7)容器
- Hadoop源码分析13: IPC流程(8) Server的wait、notify
- Hadoop源码分析14: IPC流程(9) SelectionKey
- Hadoop源码分析15:IPC流程(10)ClientConnection 复用
- Hadoop源码分析16: IPC流程(11) 整体流程