[java架构直通][Netty]#3_Netty打造RPC通信框架

# 客户端连接管理

package com.bfxy.rapid.rpc.client;

import java.net.SocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.bfxy.rapid.rpc.codec.RpcRequest;
import com.bfxy.rapid.rpc.codec.RpcResponse;

import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

/**
 * 	$RpcClientHandler 实际的业务处理器(Handler)
 * @author 17475
 *
 */
public class RpcClientHandler extends SimpleChannelInboundHandler<RpcResponse> {

	private Channel channel;
	
	private SocketAddress remotePeer;
	
	private Map<String /*requestId*/, RpcFuture> pendingRpcTable = new ConcurrentHashMap<String, RpcFuture>();
	
    public Channel getChannel() {
        return channel;
    }
    
	/**
	 * 通道激活的时候触发此方法
	 */
	public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
		super.channelRegistered(ctx);
		this.channel = ctx.channel();
	}
	
	/**
	 * 通道激活的时候触发此方法
	 */
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		super.channelActive(ctx);
		this.remotePeer = this.channel.remoteAddress();
	}
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, RpcResponse rpcResponse) throws Exception {
		String requestId = rpcResponse.getRequestId();
		RpcFuture rpcFuture = pendingRpcTable.get(requestId);
		if(rpcFuture != null) {
			pendingRpcTable.remove(requestId);
			rpcFuture.done(rpcResponse);
		}
	}

	public SocketAddress getRemotePeer() {
		return this.remotePeer;
	}

	/**
	 * Netty提供了一种主动关闭连接的方式.发送一个Unpooled.EMPTY_BUFFER 这样我们的ChannelFutureListener的close事件就会监听到并关闭通道
	 */
	public void close() {
		channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
	}
	
	
	/**
	 * 	异步发送请求方法
	 * @param request
	 * @return
	 */
	public RpcFuture sendRequest(RpcRequest request) {
		RpcFuture rpcFuture = new RpcFuture(request);
		pendingRpcTable.put(request.getRequestId(), rpcFuture);
		channel.writeAndFlush(request);
		return rpcFuture;
	}

}
-----------------------------------------------------------------------

@Slf4j
public class RpcConnectManager {

//	private static volatile RpcConnectManager  RPC_CONNECT_MANAGER = new RpcConnectManager();
	
    public RpcConnectManager() {
    }
	
	/*	一个连接的地址,对应一个实际的业务处理器(client)	*/
	private Map<InetSocketAddress, RpcClientHandler> connectedHandlerMap = new ConcurrentHashMap<InetSocketAddress, RpcClientHandler>();
	
	/*	所有连接成功的地址 所对应的 任务执行器列表 connectedHandlerList */
	private CopyOnWriteArrayList<RpcClientHandler> connectedHandlerList = new CopyOnWriteArrayList<RpcClientHandler>();
	
	/*	用于异步的提交连接请求的线程池	*/
	private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(16, 16, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(65536));
	
	private EventLoopGroup eventLoopGroup = new NioEventLoopGroup(4);
	
	private ReentrantLock connectedLock = new ReentrantLock();
	
	private Condition connectedCondition = connectedLock.newCondition();
	
	private long connectTimeoutMills = 6000;
	
	private volatile boolean isRunning = true;
	
	private volatile AtomicInteger handlerIdx = new AtomicInteger(0);
	
	//1. 异步连接 线程池 真正的发起连接,连接失败监听,连接成功监听
	//2. 对于连接进来的资源做一个缓存(做一个管理)updateConnectedServer
	/**
	 * 	$connect 发起连接方法
	 * @param serverAddress
	 */
	public void connect(final String serverAddress) {
		List<String> allServerAddress = Arrays.asList(serverAddress.split(","));
		updateConnectedServer(allServerAddress);
	}
	
	/** 
	 * 	add connect List<String> serverAddress
	 * @param serverAddress
	 */
    public void connect(List<String> serverAddress) {
        updateConnectedServer(serverAddress);
    }
	
	/**
	 * 	$更新缓存信息 并 异步发起连接
	 * 	192.168.11.111:8765,192.168.11.112:8765
	 * @param allServerAddress
	 */
	public void updateConnectedServer(List<String> allServerAddress) {
		if(CollectionUtils.isNotEmpty(allServerAddress)) {
			
			//	1.解析allServerAddress地址 并且临时存储到我们的newAllServerNodeSet HashSet集合中
			HashSet<InetSocketAddress> newAllServerNodeSet = new HashSet<InetSocketAddress>();
			for(int i =0; i < allServerAddress.size(); i++) {
				String[] array = allServerAddress.get(i).split(":");
				if(array.length == 2) {
					String host = array[0];
					int port = Integer.parseInt(array[1]);
					final InetSocketAddress remotePeer = new InetSocketAddress(host, port);
					newAllServerNodeSet.add(remotePeer);
				}
			}
			
			//	2.调用建立连接方法 发起远程连接操作
			for(InetSocketAddress serverNodeAddress : newAllServerNodeSet) {
				if(!connectedHandlerMap.keySet().contains(serverNodeAddress)) {
					connectAsync(serverNodeAddress);
				}
			}
			
			//	3. 如果allServerAddress列表里不存在的连接地址,那么我需要从缓存中进行移除
			for(int i = 0; i< connectedHandlerList.size(); i++) {
				RpcClientHandler rpcClientHandler = connectedHandlerList.get(i);
				SocketAddress remotePeer = rpcClientHandler.getRemotePeer();
				if(!newAllServerNodeSet.contains(remotePeer)) {
					log.info(" remove invalid server node " + remotePeer);
					RpcClientHandler handler = connectedHandlerMap.get(remotePeer);
					if(handler != null) {
						handler.close();
						connectedHandlerMap.remove(remotePeer);
					}
					connectedHandlerList.remove(rpcClientHandler);
				}
			}
			
		} else {
			// 添加告警
			log.error(" no available server address! ");
			// 清除所有的缓存信息
			clearConnected();
		}
	}

	/**
	 * 	$connectAsync 异步发起连接的方法
	 * @param serverNodeAddress
	 */
	private void connectAsync(InetSocketAddress remotePeer) {
		threadPoolExecutor.submit(new Runnable() {
			@Override
			public void run() {
				Bootstrap b = new Bootstrap();
				b
				.group(eventLoopGroup)
				.channel(NioSocketChannel.class)
				.option(ChannelOption.TCP_NODELAY, true)
				.handler(new RpcClientInitializer());
				connect(b, remotePeer);
			}
		});
	}
	
	private void connect(final Bootstrap b, InetSocketAddress remotePeer) {
		
		//	1.真正的建立连接
		final ChannelFuture channelFuture = b.connect(remotePeer);
		
		//	2.连接失败的时候添加监听 清除资源后进行发起重连操作
		channelFuture.channel().closeFuture().addListener(new ChannelFutureListener() {
			
			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				log.info("channelFuture.channel close operationComplete, remote peer =" + remotePeer);
				future.channel().eventLoop().schedule(new Runnable() {
					
					@Override
					public void run() {
						log.warn(" connect fail, to reconnect! ");
						clearConnected();
						connect(b, remotePeer);
					}
		
				}, 3, TimeUnit.SECONDS);
			}
		});
		
		//	3.连接成功的时候添加监听 把我们的新连接放入缓存中
		channelFuture.addListener(new ChannelFutureListener() {
			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				if(future.isSuccess()) {
					log.info("successfully connect to remote server, remote peer = " + remotePeer);
					RpcClientHandler handler = future.channel().pipeline().get(RpcClientHandler.class);
					addHandler(handler);
				}
			}
		});
	}
	
	/**
	 * 	$clearConnected
	 * 	连接失败时,及时的释放资源,清空缓存
	 * 	先删除所有的connectedHandlerMap中的数据
	 * 	然后再清空connectedHandlerList中的数据
	 */
	private void clearConnected() {
		for(final RpcClientHandler rpcClientHandler : connectedHandlerList) {
			// 通过RpcClientHandler 找到具体的remotePeer, 从connectedHandlerMap进行移除指定的 RpcClientHandler
			SocketAddress remotePeer = rpcClientHandler.getRemotePeer();
			RpcClientHandler handler = connectedHandlerMap.get(remotePeer);
			if(handler != null) {
				handler.close();
				connectedHandlerMap.remove(remotePeer);
			}
		}
		connectedHandlerList.clear();
	}
	
	
	/**
	 * 	$addHandler 添加RpcClientHandler到指定的缓存中
	 * 	connectedHandlerMap & connectedHandlerList
	 * 	
	 * @param handler
	 */
	private void addHandler(RpcClientHandler handler) {
		connectedHandlerList.add(handler);
		InetSocketAddress remoteAddress = //(InetSocketAddress) handler.getRemotePeer();
				(InetSocketAddress) handler.getChannel().remoteAddress();

		connectedHandlerMap.put(remoteAddress, handler);
		//signalAvailableHandler 唤醒可用的业务执行器
		signalAvailableHandler();
	}

	/**
	 * 	唤醒另外一端的线程(阻塞的状态中) 告知有新连接接入
	 */
	private void signalAvailableHandler() {
		connectedLock.lock();
		try {
			connectedCondition.signalAll();
		} finally {
			connectedLock.unlock();
		}
	}
	
	/**
	 * 	$waitingForAvailableHandler 等待新连接接入通知方法
	 * @return
	 * @throws InterruptedException
	 */
	private boolean waitingForAvailableHandler() throws InterruptedException {
		connectedLock.lock();
		try {
			return connectedCondition.await(this.connectTimeoutMills, TimeUnit.MICROSECONDS);
		} finally {
			connectedLock.unlock();
		}
	}
	
	
	/**
	 * $chooseHandler 选择一个实际的业务处理器
	 * @return RpcClientHandler
	 */
	public RpcClientHandler chooseHandler() {
		CopyOnWriteArrayList<RpcClientHandler> handlers = (CopyOnWriteArrayList<RpcClientHandler>)this.connectedHandlerList.clone();
		
		int size = handlers.size();
		
		while(isRunning && size <= 0) {
			try {
				boolean available = waitingForAvailableHandler();
				if(available) {
					handlers = (CopyOnWriteArrayList<RpcClientHandler>)this.connectedHandlerList.clone();
					size = handlers.size();
				}
			} catch (InterruptedException e) {
				log.error(" wating for available node is interrupted !");
				throw new RuntimeException("no connect any servers!", e);
			}
		}
		if(!isRunning) {
			return null;
		}
		// 	最终使用取模方式取得其中一个业务处理器进行实际的业务处理
		return handlers.get(((handlerIdx.getAndAdd(1) + size) % size));
	}
	
	/**
	 * 	$stop 关闭的方法
	 */
	public void stop() {
		isRunning = false;
		for(int i = 0; i< connectedHandlerList.size(); i++) {
			RpcClientHandler rpcClientHandler = connectedHandlerList.get(i);
			rpcClientHandler.close();
		}
		// 在这里要调用一下唤醒操作
		signalAvailableHandler();
		threadPoolExecutor.shutdown();
		eventLoopGroup.shutdownGracefully();
	}
	
	/**
	 * $reconnect 发起重连方法 需要把对应的资源进行释放
	 * @param handler
	 * @param remotePeer
	 */
	public void reconnect(final RpcClientHandler handler , final SocketAddress remotePeer) {
		if(handler != null) {
			handler.close();
			connectedHandlerList.remove(handler);
			connectedHandlerMap.remove(remotePeer);
		}
		connectAsync((InetSocketAddress) remotePeer);
	}
	
}


-----------------------------------------------------------------------
public class RpcClientInitializer extends ChannelInitializer<SocketChannel>{

	@Override
	protected void initChannel(SocketChannel ch) throws Exception {
		
		ChannelPipeline cp = ch.pipeline();
		//	编解码的handler
		cp.addLast(new RpcEncoder(RpcRequest.class));
//	     * @param lengthFieldOffset
//	     *        the offset of the length field
//	     * @param lengthFieldLength
//	     *        the length of the length field
		cp.addLast(new LengthFieldBasedFrameDecoder(65536, 0, 4, 0, 0));
		cp.addLast(new RpcDecoder(RpcResponse.class));
		//	实际的业务处理器RpcClientHandler
		cp.addLast(new RpcClientHandler());
		
		
	}

}
public class RpcClient {

    private final Map<Class<?>, Object> syncProxyInstanceMap = new ConcurrentHashMap<Class<?>, Object>();

    private final Map<Class<?>, Object> asyncProxyInstanceMap = new ConcurrentHashMap<Class<?>, Object>();

    private String serverAddress;
    
    private List<String> serverAddressList;
    
    private long timeout;
    
    private RpcConnectManager rpcConnectManager;
    
    public void initClient(String serverAddress, long timeout) {
        this.serverAddress = serverAddress;
        this.timeout = timeout;
        this.rpcConnectManager = new RpcConnectManager();
        connect();
    }
    
    private void connect() {
        this.rpcConnectManager.connect(this.serverAddress);
    }
    
    /**
     * 	initClient: 直接返回对应的代理对象,把RpcConnectManager透传到代理对象中
     * @param <T>
     * @param serverAddress
     * @param timeout
     * @param interfaceClass
     * @return RpcProxyImpl
     */
    @SuppressWarnings("unchecked")
	public <T> T initClient(List<String> serverAddress, long timeout, Class<T> interfaceClass) {
        this.serverAddressList = serverAddress;
        this.timeout = timeout;
        this.rpcConnectManager = new RpcConnectManager();
        this.rpcConnectManager.connect(this.serverAddressList);
        return (T) Proxy.newProxyInstance(
                interfaceClass.getClassLoader(),
                new Class<?>[]{interfaceClass},
                new RpcProxyImpl<>(rpcConnectManager, interfaceClass, timeout)
        );
    }
    
	public void updateConnectedServer(List<String> serverAddress) {
        this.serverAddressList = serverAddress;
        this.rpcConnectManager.updateConnectedServer(serverAddress);
    }
    
    /**
     * <B>方法名称:</B>invokeSync<BR>
     * <B>概要说明:</B>同步调用<BR>
     * @author hezhuo.bai-JiFeng
     * @since 2019年10月17日 下午4:10:04
     * @param <T>
     * @param interfaceClass
     * @return
     */
    @SuppressWarnings("unchecked")
	public <T> T invokeSync(Class<T> interfaceClass) {
        if (syncProxyInstanceMap.containsKey(interfaceClass)) {
            return (T) syncProxyInstanceMap.get(interfaceClass);
        } else {
            Object proxy = Proxy.newProxyInstance(
                    interfaceClass.getClassLoader(),
                    new Class<?>[]{interfaceClass},
                    new RpcProxyImpl<>(rpcConnectManager, interfaceClass, timeout)
            );
            syncProxyInstanceMap.put(interfaceClass, proxy);
            return (T) proxy;
        }
    }
    
    /**
     * <B>方法名称:</B>InvokeAsync<BR>
     * <B>概要说明:</B>异步调用<BR>
     * @author hezhuo.bai-JiFeng
     * @since 2019年10月17日 下午4:12:14
     * @param <T>
     * @param interfaceClass
     * @return
     */
    @SuppressWarnings("unchecked")
	public <T> RpcAsyncProxy invokeAsync(Class<T> interfaceClass) {
        if (asyncProxyInstanceMap.containsKey(interfaceClass)) {
            return ((RpcProxyImpl<T>) asyncProxyInstanceMap.get(interfaceClass));
        } else {
        	RpcProxyImpl<T> rpcProxyImpl = new RpcProxyImpl<T>(rpcConnectManager, interfaceClass, timeout);
        	asyncProxyInstanceMap.put(interfaceClass, rpcProxyImpl);
            return rpcProxyImpl;
        }
    }
    
    public void stop() {
    	this.rpcConnectManager.stop();
    }
}

 # RPC编解码

 

@Data
public class RpcRequest implements Serializable {

	private static final long serialVersionUID = 3424024710707513070L;
	
	private String requestId;
	
	private String className;
	
	private String methodName;
	
	private Class<?>[] paramterTypes;
	
	private Object[] paramters;

}

@Data
public class RpcResponse implements Serializable {

	private static final long serialVersionUID = -7989400623370901861L;

	private String requestId;
	
	private Object result;
	
	private Throwable throwable;
	
}
package com.bfxy.rapid.rpc.codec;

import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

/**
 * 	$RpcDecoder
 * @author 17475
 *
 */
public class RpcDecoder extends ByteToMessageDecoder {

	private Class<?> genericClass;

	public RpcDecoder(Class<?> genericClass) {
		this.genericClass = genericClass;
	}	
	
	
	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
		//	如果请求数据包 不足4个字节 直接返回, 如果大于等于4个字节 那么程序继续执行
		if(in.readableBytes() < 4) {
			return;
		}
		
		//	首先记录一下当前的位置
		in.markReaderIndex();
		//	当前请求数据包的大小读取出来
		int dataLength = in.readInt();
		if(in.readableBytes() < dataLength) {
			in.resetReaderIndex();
			return;
		}
		
		//	真正读取需要长度的数据包内容
		byte[] data = new byte[dataLength];
		in.readBytes(data);
		
		// 	解码操作 返回指定的对象
		Object obj = Serialization.deserialize(data, genericClass);
		
		//	填充到buffer中,传播给下游handler做实际的处理
		out.add(obj);
	}

}



public class RpcEncoder extends MessageToByteEncoder<Object> {
	
	private Class<?> genericClass;

	public RpcEncoder(Class<?> genericClass) {
		this.genericClass = genericClass;
	}	
	
	/**
	 * 	编码器要做的事情
	 * 	1. 把对应的java对象进行编码
	 * 	2. 之后把内容填充到buffer中去
	 * 	3. 写出到Server端
	 */
	@Override
	protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
		if(genericClass.isInstance(msg)) {
			byte[] data = Serialization.serialize(msg);
			// 消息分为:1.包头 (数据包长度)  2.包体(数据包内容)
			out.writeInt(data.length);
			out.writeBytes(data);
		}
	}

}

# 服务端处理器

package com.bfxy.rapid.rpc.server;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.bfxy.rapid.rpc.codec.RpcDecoder;
import com.bfxy.rapid.rpc.codec.RpcEncoder;
import com.bfxy.rapid.rpc.codec.RpcRequest;
import com.bfxy.rapid.rpc.codec.RpcResponse;
import com.bfxy.rapid.rpc.config.provider.ProviderConfig;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 */
@Slf4j
public class RpcServer {

	private String serverAddress;
	
	private EventLoopGroup bossGroup = new NioEventLoopGroup();
	
	private EventLoopGroup workerGroup = new NioEventLoopGroup();
	
	private volatile Map<String /* interface name */, Object> handlerMap = new HashMap<String, Object>();
	
	
	public RpcServer(String serverAddress) throws InterruptedException {
		this.serverAddress = serverAddress;
		this.start();
	}

	/**
	 * 	$start
	 * @throws InterruptedException
	 */
	private void start() throws InterruptedException {
		
		ServerBootstrap serverBootstrap = new ServerBootstrap();
		serverBootstrap.group(bossGroup, workerGroup)
		.channel(NioServerSocketChannel.class)
		//	tpc = sync + accept  = backlog
		.option(ChannelOption.SO_BACKLOG, 1024)
		.childHandler(new ChannelInitializer<SocketChannel>() {
			@Override
			protected void initChannel(SocketChannel ch) throws Exception {
				ChannelPipeline cp = ch.pipeline();
				cp.addLast(new LengthFieldBasedFrameDecoder(65536, 0, 4, 0, 0));
				cp.addLast(new RpcDecoder(RpcRequest.class));
				cp.addLast(new RpcEncoder(RpcResponse.class));
				cp.addLast(new RpcSeverHandler(handlerMap));
			}
		});
		
		
		String[] array = serverAddress.split(":");
		String host = array[0];
		int port = Integer.parseInt(array[1]);
		
		ChannelFuture channelFuture = serverBootstrap.bind(host, port).sync();
		channelFuture.addListener(new ChannelFutureListener() {
			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				if(future.isSuccess()) {
					log.info("server success bing to " + serverAddress);
				} else {
					log.info("server fail bing to " + serverAddress);
					throw new Exception("server start fail, cause: " + future.cause());
				}
			}
		});
		
		try {
			channelFuture.await(5000, TimeUnit.MILLISECONDS);	
			if(channelFuture.isSuccess()) {
				log.info("start rapid rpc success! ");
			}
		} catch (InterruptedException e) {
			log.error("start rapid rpc occur Interrupted, ex: " + e);
		}
		
	}
	
	/**
	 * 	$registerProcessor 程序注册器
	 */
	public void registerProcessor(ProviderConfig providerConfig) {
		//key : providerConfig.insterface (userService接口权限命名)
		//value : providerConfig.ref (userService接口下的具体实现类 userServiceImpl实例对象)
		handlerMap.put(providerConfig.getInterface(), providerConfig.getRef());
	}
	
	/**
	 * 	$close
	 */
	public void close() {
		bossGroup.shutdownGracefully();
		workerGroup.shutdownGracefully();
	}
	

}



@Slf4j
public class RpcSeverHandler extends SimpleChannelInboundHandler<RpcRequest> {
	
	private Map<String, Object> handlerMap;
	
	private ThreadPoolExecutor executor = new ThreadPoolExecutor(16, 16, 600L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(65536));
	

	public RpcSeverHandler(Map<String, Object> handlerMap) {
		this.handlerMap = handlerMap;
	}
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, RpcRequest rpcRequest) throws Exception {
		executor.submit(new Runnable() {
			@Override
			public void run() {
				RpcResponse response = new RpcResponse();
				response.setRequestId(rpcRequest.getRequestId());
				try {
					Object result = handle(rpcRequest);
					response.setResult(result);
				} catch (Throwable t) {
					response.setThrowable(t);
					log.error("rpc service handle request Throwable: " + t);
				}
				
				ctx.writeAndFlush(response).addListener(new ChannelFutureListener() {
					@Override
					public void operationComplete(ChannelFuture future) throws Exception {
						if(future.isSuccess()) {
							// afterRpcHook
						}
					}
				});
				
			}
		});
	}

	/**
	 * 	$handle 解析request请求并且去通过反射获取具体的本地服务实例后执行具体的方法
	 * @param request
	 * @return
	 * @throws InvocationTargetException
	 */
	private Object handle(RpcRequest request) throws InvocationTargetException {
		String className = request.getClassName();
		Object serviceRef = handlerMap.get(className);
		Class<?> serviceClass = serviceRef.getClass();
		String methodName = request.getMethodName();
		Class<?>[] paramterTypes = request.getParamterTypes();
		Object[] paramters = request.getParamters();
		
		// JDK relect
		
		// Cglib
		FastClass serviceFastClass = FastClass.create(serviceClass);
		FastMethod servicFastMethod = serviceFastClass.getMethod(methodName, paramterTypes);
		return servicFastMethod.invoke(serviceRef, paramters);
	}

	/**
	 * 	$exceptionCaught 异常处理关闭连接
	 */
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		log.error("server caught Throwable: " + cause);
		ctx.close();
	}
	
}

# 异步代理

package com.bfxy.rapid.rpc.client.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import com.bfxy.rapid.rpc.client.RpcClientHandler;
import com.bfxy.rapid.rpc.client.RpcConnectManager;
import com.bfxy.rapid.rpc.client.RpcFuture;
import com.bfxy.rapid.rpc.codec.RpcRequest;

public class RpcProxyImpl<T> implements InvocationHandler, RpcAsyncProxy {

	private Class<T> clazz;
	
	private long timeout;
	
    private RpcConnectManager rpcConnectManager;
    
	public RpcProxyImpl(RpcConnectManager rpcConnectManager, Class<T> clazz, long timeout) {
		this.clazz = clazz;
		this.timeout = timeout;
		this.rpcConnectManager = rpcConnectManager;
	}
	
	/**
	 * 	invoke代理接口调用方式
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//1.设置请求对象
		RpcRequest request = new RpcRequest();
		request.setRequestId(UUID.randomUUID().toString());
		request.setClassName(method.getDeclaringClass().getName());
		request.setMethodName(method.getName());
		request.setParamterTypes(method.getParameterTypes());
		request.setParamters(args);
		
		//2.选择一个合适的Client任务处理器
//		RpcClientHandler handler = RpcConnectManager.getInstance().chooseHandler();
		RpcClientHandler handler = this.rpcConnectManager.chooseHandler();

		//3. 发送真正的客户端请求 返回结果
		RpcFuture future = handler.sendRequest(request);
		return future.get(timeout, TimeUnit.SECONDS);
	}

	/**
	 * 	$call 异步的代理接口实现, 真正的抱出去RpcFuture 给业务方做实际的回调等待处理
	 */
	@Override
	public RpcFuture call(String funcName, Object... args) {

		//1.设置请求对象
		RpcRequest request = new RpcRequest();
		request.setRequestId(UUID.randomUUID().toString());
		request.setClassName(this.clazz.getName());
		request.setMethodName(funcName);
		request.setParamters(args);
		//	TODO: 对应的方法参数类型应该通过 类类型 + 方法名称 通过反射得到parameterTypes
		Class<?>[] parameterTypes = new Class[args.length];
		for(int i = 0; i < args.length; i++) {
			parameterTypes[i] = getClassType(args[i]);
		}
		request.setParamterTypes(parameterTypes);
		
		//2.选择一个合适的Client任务处理器
//		RpcClientHandler handler = RpcConnectManager.getInstance().chooseHandler();
		RpcClientHandler handler = this.rpcConnectManager.chooseHandler();
		RpcFuture future = handler.sendRequest(request);
		return future;
	}
	
    private Class<?> getClassType(Object obj) {
        Class<?> classType = obj.getClass();
        String typeName = classType.getName();
        if (typeName.equals("java.lang.Integer")) {
            return Integer.TYPE;
        } else if (typeName.equals("java.lang.Long")) {
            return Long.TYPE;
        } else if (typeName.equals("java.lang.Float")) {
            return Float.TYPE;
        } else if (typeName.equals("java.lang.Double")) {
            return Double.TYPE;
        } else if (typeName.equals("java.lang.Character")) {
            return Character.TYPE;
        } else if (typeName.equals("java.lang.Boolean")) {
            return Boolean.TYPE;
        } else if (typeName.equals("java.lang.Short")) {
            return Short.TYPE;
        } else if (typeName.equals("java.lang.Byte")) {
            return Byte.TYPE;
        }
        return classType;
    }
}
@Slf4j
public class RpcServer {

	private String serverAddress;
	
	private EventLoopGroup bossGroup = new NioEventLoopGroup();
	
	private EventLoopGroup workerGroup = new NioEventLoopGroup();
	
	private volatile Map<String /* interface name */, Object> handlerMap = new HashMap<String, Object>();
	
	
	public RpcServer(String serverAddress) throws InterruptedException {
		this.serverAddress = serverAddress;
		this.start();
	}

	/**
	 * 	$start
	 * @throws InterruptedException
	 */
	private void start() throws InterruptedException {
		
		ServerBootstrap serverBootstrap = new ServerBootstrap();
		serverBootstrap.group(bossGroup, workerGroup)
		.channel(NioServerSocketChannel.class)
		//	tpc = sync + accept  = backlog
		.option(ChannelOption.SO_BACKLOG, 1024)
		.childHandler(new ChannelInitializer<SocketChannel>() {
			@Override
			protected void initChannel(SocketChannel ch) throws Exception {
				ChannelPipeline cp = ch.pipeline();
				cp.addLast(new LengthFieldBasedFrameDecoder(65536, 0, 4, 0, 0));
				cp.addLast(new RpcDecoder(RpcRequest.class));
				cp.addLast(new RpcEncoder(RpcResponse.class));
				cp.addLast(new RpcSeverHandler(handlerMap));
			}
		});
		
		
		String[] array = serverAddress.split(":");
		String host = array[0];
		int port = Integer.parseInt(array[1]);
		
		ChannelFuture channelFuture = serverBootstrap.bind(host, port).sync();
		channelFuture.addListener(new ChannelFutureListener() {
			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				if(future.isSuccess()) {
					log.info("server success bing to " + serverAddress);
				} else {
					log.info("server fail bing to " + serverAddress);
					throw new Exception("server start fail, cause: " + future.cause());
				}
			}
		});
		
		try {
			channelFuture.await(5000, TimeUnit.MILLISECONDS);	
			if(channelFuture.isSuccess()) {
				log.info("start rapid rpc success! ");
			}
		} catch (InterruptedException e) {
			log.error("start rapid rpc occur Interrupted, ex: " + e);
		}
		
	}
	
	/**
	 * 	$registerProcessor 程序注册器
	 */
	public void registerProcessor(ProviderConfig providerConfig) {
		//key : providerConfig.insterface (userService接口权限命名)
		//value : providerConfig.ref (userService接口下的具体实现类 userServiceImpl实例对象)
		handlerMap.put(providerConfig.getInterface(), providerConfig.getRef());
	}
	
	/**
	 * 	$close
	 */
	public void close() {
		bossGroup.shutdownGracefully();
		workerGroup.shutdownGracefully();
	}
	

}
@Slf4j
public class RpcSeverHandler extends SimpleChannelInboundHandler<RpcRequest> {
	
	private Map<String, Object> handlerMap;
	
	private ThreadPoolExecutor executor = new ThreadPoolExecutor(16, 16, 600L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(65536));
	

	public RpcSeverHandler(Map<String, Object> handlerMap) {
		this.handlerMap = handlerMap;
	}
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, RpcRequest rpcRequest) throws Exception {
		executor.submit(new Runnable() {
			@Override
			public void run() {
				RpcResponse response = new RpcResponse();
				response.setRequestId(rpcRequest.getRequestId());
				try {
					Object result = handle(rpcRequest);
					response.setResult(result);
				} catch (Throwable t) {
					response.setThrowable(t);
					log.error("rpc service handle request Throwable: " + t);
				}
				
				ctx.writeAndFlush(response).addListener(new ChannelFutureListener() {
					@Override
					public void operationComplete(ChannelFuture future) throws Exception {
						if(future.isSuccess()) {
							// afterRpcHook
						}
					}
				});
				
			}
		});
	}

	/**
	 * 	$handle 解析request请求并且去通过反射获取具体的本地服务实例后执行具体的方法
	 * @param request
	 * @return
	 * @throws InvocationTargetException
	 */
	private Object handle(RpcRequest request) throws InvocationTargetException {
		String className = request.getClassName();
		Object serviceRef = handlerMap.get(className);
		Class<?> serviceClass = serviceRef.getClass();
		String methodName = request.getMethodName();
		Class<?>[] paramterTypes = request.getParamterTypes();
		Object[] paramters = request.getParamters();
		
		// JDK relect
		
		// Cglib
		FastClass serviceFastClass = FastClass.create(serviceClass);
		FastMethod servicFastMethod = serviceFastClass.getMethod(methodName, paramterTypes);
		return servicFastMethod.invoke(serviceRef, paramters);
	}

	/**
	 * 	$exceptionCaught 异常处理关闭连接
	 */
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		log.error("server caught Throwable: " + cause);
		ctx.close();
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值