(五) Nepxion分布式RPC框架 - 通信协议框架

Nepxion Thunder(QQ 1394997)发布在淘宝代码基地 http://code.taobao.org/p/Thunder/

 

(五) Nepxion分布式RPC框架 - 通信协议框架_第1张图片
  •  1 ServerExecutor.java - 服务端运行器接口
           interfaze :接口名(例如com.nepxion.thunder.test.service.UserService)
           applicationEntity包含四个参数:application(应用名),group(组名),host(服务地址),port(端口)。应用名和组名的作用,一是为了管理方便,二是防止同名接口的出现
          
    ServerExecutor.java作用是根据接口名+应用名+组名+服务地址+端口发布一个服务
    public interface ServerExecutor extends ThunderDelegate {
        // 服务端启动
        void start(String interfaze, ApplicationEntity applicationEntity) throws Exception;
        
        // 服务端是否启动
        boolean started(String interfaze, ApplicationEntity applicationEntity) throws Exception;
    }
  • 2 AbstractServerExecutor.java - ServerExecutor.java的抽象实现,具体逻辑到各个通信中间件的去实现
  • 3 ServerHandlerAdapter.java - 服务端处理逻辑的封装适配,分为三部分:处理结果(安全访问的拦截),处理异常,处理监控。服务端的处理是异步多线程
    public class ServerHandlerAdapter extends ThunderDelegateImpl {
        private static final Logger LOG = LoggerFactory.getLogger(ServerHandlerAdapter.class);
    
        public void handle(ProtocolRequest request, ProtocolResponse response) throws Exception {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Request={}", JsonUtil.toJson(request));
            }
    
            try {
                handleResult(request, response);
            } catch (Exception e) {
                handleException(e, response);
                throw e;
            } finally {
                handleMonitor(request);
            }
        }
    
        private void handleResult(ProtocolRequest request, ProtocolResponse response) throws Exception {
            boolean heartbeat = request.isHeartbeat();
            if (heartbeat) {
                LOG.info("Receive heart beat request...");
    
                return;
            }
    
            String messageId = request.getMessageId();
            String interfaze = request.getInterface();
            boolean async = request.isAsync();
            long timeout = request.getTimeout();
            boolean broadcast = request.isBroadcast();
            MethodKey methodKey = request.createMethodKey();
    
            response.setMessageId(messageId);
            response.setInterface(interfaze);
            response.setAsync(async);
            response.setTimeout(timeout);
            response.setBroadcast(broadcast);
            response.setHeartbeat(heartbeat);
            response.setMethodKey(methodKey);
    
            SecurityExecutor securityExecutor = executorContainer.getSecurityExecutor();
            if (securityExecutor != null) {
                boolean authorized = securityExecutor.process(request, response);
                if (!authorized) {
                    return;
                }
            }
    
            Map<String, ServiceEntity> serviceEntityMap = cacheContainer.getServiceEntityMap();
            ServiceEntity serviceEntity = serviceEntityMap.get(interfaze);
    
            String methodName = request.getMethod();
            Class<?>[] parameterTypes = request.getParameterTypes();
            Object[] parameters = request.getParameters();
    
            Object service = serviceEntity.getService();
            Class<?> clazz = service.getClass();
            Method method = clazz.getMethod(methodName, parameterTypes);
            Object result = method.invoke(service, parameters);
            response.setResult(result);
        }
    
        private void handleException(Exception e, ProtocolResponse response) {
            response.setException(e);
        }
        
        private void handleMonitor(ProtocolRequest request) throws Exception {
            boolean heartbeat = request.isHeartbeat();
            if (!heartbeat) {
                MonitorExecutor monitorExecutor = executorContainer.getMonitorExecutor();
                if (monitorExecutor != null) {
                    monitorExecutor.process(request);
                }
            }
        }
    }
  • 4 ClientExecutor.java - 调用端运行器接口
          ClientExecutor.java作用是根据接口名+应用名+组名+服务地址+端口获取一个服务,对服务上下线后的回调
    public interface ClientExecutor extends ThunderDelegate {
    
        // 客户端启动连接
        void start(String interfaze, ApplicationEntity applicationEntity) throws Exception;
        
        // 客户端是否启动
        boolean started(String interfaze, ApplicationEntity applicationEntity) throws Exception;
        
        // 客户端上线
        void online(String interfaze, ApplicationEntity applicationEntity, Object handler) throws Exception;
        
        // 客户端下线
        void offline(String interfaze, ApplicationEntity applicationEntity) throws Exception;
    }
  • 5 AbstractClientExecutor.java - ClientExecutor.java的抽象实现,具体逻辑到各个通信中间件的去实现
  • 6 ClientHandlerAdapter.java - 调用端处理逻辑的封装适配,分为四部分:处理同步/异步返回结果(异步心跳和广播忽略),处理异常,处理监控。同步模式下,用CyclicBarrier做异步模拟同步等待
    public class ClientHandlerAdapter extends ThunderDelegateImpl {
        private static final Logger LOG = LoggerFactory.getLogger(ClientHandlerAdapter.class);
    
        public void handle(ProtocolResponse response) throws Exception {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Response={}", JsonUtil.toJson(response));
            }
    
            try {
                if (response.isAsync()) {
                    handleAsync(response);
                } else {
                    handleSync(response);
                }
            } catch (Exception e) {
                handleException(e, response);
                throw e;
            } finally {
                handleMonitor(response);   
            }
        }
    
        @SuppressWarnings("all")
        protected void handleAsync(ProtocolResponse response) throws Exception {
            boolean heartbeat = response.isHeartbeat();
            boolean broadcast = response.isBroadcast();
            if (heartbeat || broadcast) {
                return;
            }
    
            String interfaze = response.getInterface();
            MethodKey methodKey = response.getMethodKey();
    
            Map<String, ReferenceEntity> referenceEntityMap = cacheContainer.getReferenceEntityMap();
            ReferenceEntity referenceEntity = referenceEntityMap.get(interfaze);
            MethodEntity methodEntity = referenceEntity.getMethodEntity(methodKey);
    
            ThunderCallback callback = methodEntity.getCallback();
            if (callback != null) {
                Object result = response.getResult();
                Exception exception = response.getException();
                callback.call(result, exception);
            }
        }
    
        private void handleSync(ProtocolResponse response) throws Exception {
            String messageId = response.getMessageId();
            Map<String, ResponseEntity> responseEntityMap = cacheContainer.getResponseEntityMap();
            try {
                ResponseEntity responseEntity = responseEntityMap.get(messageId);
                if (responseEntity != null) {
                    responseEntity.setResult(response.getResult());
                    responseEntity.setException(response.getException());
    
                    CyclicBarrier barrier = responseEntity.getBarrier();
                    barrier.await();
                } else {
                    LOG.info("Timeout sync response for messageId={}", messageId);
                }
            } finally {
                if (responseEntityMap.get(messageId) != null) {
                    responseEntityMap.remove(messageId);
                }
            }
        }
    
        private void handleException(Exception e, ProtocolResponse response) {
            e.printStackTrace();
        }
        
        private void handleMonitor(ProtocolResponse response) throws Exception {
            boolean heartbeat = response.isHeartbeat();
            if (!heartbeat) {
                MonitorExecutor monitorExecutor = executorContainer.getMonitorExecutor();
                if (monitorExecutor != null) {
                    monitorExecutor.process(response);
                }
            }
        }
    }
  • 7 ClientInterceptor.java - 调用端代理拦截器
         
    ClientInterceptor.java作用是提供异步调用,同步调用,广播调用三种方式接口
    public interface ClientInterceptor extends ThunderDelegate, MethodInterceptor {
        // 设置要调用的接口
        void setInterface(String interfaze);
        
        // 异步调用
        void invokeAsync(ProtocolRequest request) throws Exception;
    
        // 同步调用
        Object invokeSync(ProtocolRequest request) throws Exception;
    
        // 广播调用
        void invokeBroadcast(ProtocolRequest request) throws Exception;
    }
  • 8 AbstractClientInterceptor.java - 调用端代理拦截器的抽象实现,具体逻辑到各个通信中间件的去实现
    public abstract class AbstractClientInterceptor extends ThunderDelegateImpl implements ClientInterceptor {    
        protected String interfaze;
    
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {       
            String methodName = invocation.getMethod().getName();
            Class<?>[] parameterTypes = invocation.getMethod().getParameterTypes();
            Object[] arguments = invocation.getArguments();
            Class<?> returnType = invocation.getMethod().getReturnType();
    
            MethodKey methodKey = MethodKey.create(methodName, parameterTypes);
            Map<String, ReferenceEntity> referenceEntityMap = cacheContainer.getReferenceEntityMap();
            ReferenceEntity referenceEntity = referenceEntityMap.get(interfaze);
            MethodEntity methodEntity = referenceEntity.getMethodEntity(methodKey);
            
            boolean async = methodEntity.isAsync();
            long timeout = methodEntity.getTimeout();
            boolean broadcast = methodEntity.isBroadcast();
            boolean heartbeat = false;
            boolean feedback = !(broadcast || heartbeat || (async && methodEntity.getCallback() == null));
            
            ProtocolRequest request = new ProtocolRequest();
            request.setInterface(interfaze);
            request.setMethod(methodName);
            request.setParameterTypes(parameterTypes);
            request.setParameters(arguments);
            request.setAsync(async);
            request.setTimeout(timeout);
            request.setBroadcast(broadcast);
            request.setHeartbeat(heartbeat);
            request.setFeedback(feedback);
            
            Map<String, ReferenceConfig> referenceConfigMap = cacheContainer.getReferenceConfigMap();
            ReferenceConfig referenceConfig = referenceConfigMap.get(interfaze);
            request.setReferenceConfig(referenceConfig);
    
            if (request.isAsync()) {
                if (request.isBroadcast()) {
                    invokeBroadcast(request);
                } else {
                    invokeAsync(request);
                }
                
                return null;
            } else {
                return invokeSync(request);
            }
        }
    
        @Override
        public void setInterface(String interfaze) {
            this.interfaze = interfaze;
        }
    }
  • 9 ClientInterceptorAdapter.java - 调用端代理拦截器的处理逻辑封装适应。主要是同步的处理逻辑,异步不同通信中间件方式不一样,不做封装
    public class ClientInterceptorAdapter extends ThunderDelegateImpl {
        private static final Logger LOG = LoggerFactory.getLogger(ClientInterceptorAdapter.class);
        
        public Object invokeSync(ClientInterceptor clientInterceptor, ProtocolRequest request) throws Exception {        
            ResponseEntity responseEntity = new ResponseEntity();
            CyclicBarrier barrier = new CyclicBarrier(2);
            responseEntity.setBarrier(barrier);
    
            String messageId = request.getMessageId();
            long timeout = request.getTimeout();
            Map<String, ResponseEntity> responseEntityMap = cacheContainer.getResponseEntityMap();
            responseEntityMap.put(messageId, responseEntity);
    
            clientInterceptor.invokeAsync(request);
    
            try {
                // 同步等待返回结果
                try {
                    responseEntity.getBarrier().await(timeout, TimeUnit.MILLISECONDS);
                } catch (Exception e) {
                    LOG.error("Sync method timeout", e);
                    responseEntity.setResult(null);
                    responseEntity.setException(null);
                }
                
                if (responseEntity.getException() != null) {
                    throw responseEntity.getException();
                }
    
                return responseEntity.getResult();
            } finally {
                if (responseEntityMap.get(messageId) != null) {
                    responseEntityMap.remove(messageId);
                }
            }
        }
    }
  • 10 ProtocolMessage.java - 序列化类
        private String messageId;      // UUID.randomUUID()的随机字符串,作为消息的唯一ID
        private String interfaze;      // 接口名
        private boolean async;         // 异步或者同步请求
        private long timeout;          // 超时时间(只用于同步方法)
        private boolean broadcast;     // 广播模式(广播模式前提必须是异步请求)
        private boolean heartbeat;     // 心跳模式
        private boolean feedback;      // 是否需要服务端反馈结果(只用于异步方法,有一种调用方式,客户端只把请求发送出去,不需要服务端返回)
        private long timestamp;        // 消息创建时间
        private Object requestSource;  // 请求Source(一般是IP:Port格式的字符串)
        private Object responseSource; // 响应Source(一般是(IP:Port格式的字符串)
  • 11 ProtocolRequest.java - 调用端发送到服务端的请求类,继承于ProtocolMessage.java,序列化类
        private String method;                   // 方法名
        private Class<?>[] parameterTypes;       // 方法参数的类型
        private Object[] parameters;             // 方法参数的值
        private ReferenceConfig referenceConfig; // 包含secretKey(密钥),version(版本)
  • 12 ProtocolResponse.java - 服务端返回到调用端的响应类,继承于ProtocolMessage.java,序列化类
        private MethodKey methodKey; // 封装方法的相关信息
        private Object result;       // 调用的结果
        private Exception exception; // 调用的异常

你可能感兴趣的:(redis,hessian,kafka,activemq,netty)