成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 從零開始手寫 RPC—Reflect 反射實現通用調用之服務端

開發 后端
前面我們的例子是一個固定的出參和入參,固定的方法實現。本節將實現通用的調用,讓框架具有更廣泛的實用性。

[[430216]]

前面我們的例子是一個固定的出參和入參,固定的方法實現。

本節將實現通用的調用,讓框架具有更廣泛的實用性。

基本思路

所有的方法調用,基于反射進行相關處理實現。

[[430217]]

服務端

核心類

  • RpcServer

調整如下:

  1. serverBootstrap.group(workerGroup, bossGroup) 
  2.     .channel(NioServerSocketChannel.class) 
  3.     // 打印日志 
  4.     .handler(new LoggingHandler(LogLevel.INFO)) 
  5.     .childHandler(new ChannelInitializer<Channel>() { 
  6.         @Override 
  7.         protected void initChannel(Channel ch) throws Exception { 
  8.             ch.pipeline() 
  9.             // 解碼 bytes=>resp 
  10.             .addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null))) 
  11.              // request=>bytes 
  12.              .addLast(new ObjectEncoder()) 
  13.              .addLast(new RpcServerHandler()); 
  14.         } 
  15.     }) 
  16.     // 這個參數影響的是還沒有被accept 取出的連接 
  17.     .option(ChannelOption.SO_BACKLOG, 128) 
  18.     // 這個參數只是過一段時間內客戶端沒有響應,服務端會發送一個 ack 包,以判斷客戶端是否還活著。 
  19.     .childOption(ChannelOption.SO_KEEPALIVE, true); 

其中 ObjectDecoder 和 ObjectEncoder 都是 netty 內置的實現。

RpcServerHandler

  1. package com.github.houbb.rpc.server.handler; 
  2.  
  3.  
  4. import com.github.houbb.log.integration.core.Log; 
  5. import com.github.houbb.log.integration.core.LogFactory; 
  6. import com.github.houbb.rpc.common.rpc.domain.RpcRequest; 
  7. import com.github.houbb.rpc.common.rpc.domain.impl.DefaultRpcResponse; 
  8. import com.github.houbb.rpc.server.service.impl.DefaultServiceFactory; 
  9. import io.netty.channel.ChannelHandlerContext; 
  10. import io.netty.channel.SimpleChannelInboundHandler; 
  11.  
  12.  
  13. /** 
  14.  * @author binbin.hou 
  15.  * @since 0.0.1 
  16.  */ 
  17. public class RpcServerHandler extends SimpleChannelInboundHandler { 
  18.  
  19.  
  20.     private static final Log log = LogFactory.getLog(RpcServerHandler.class); 
  21.  
  22.  
  23.     @Override 
  24.     public void channelActive(ChannelHandlerContext ctx) throws Exception { 
  25.         final String id = ctx.channel().id().asLongText(); 
  26.         log.info("[Server] channel {} connected " + id); 
  27.     } 
  28.  
  29.  
  30.     @Override 
  31.     protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { 
  32.         final String id = ctx.channel().id().asLongText(); 
  33.         log.info("[Server] channel read start: {}", id); 
  34.  
  35.  
  36.         // 接受客戶端請求 
  37.         RpcRequest rpcRequest = (RpcRequest)msg; 
  38.         log.info("[Server] receive channel {} request: {}", id, rpcRequest); 
  39.  
  40.  
  41.         // 回寫到 client 端 
  42.         DefaultRpcResponse rpcResponse = handleRpcRequest(rpcRequest); 
  43.         ctx.writeAndFlush(rpcResponse); 
  44.         log.info("[Server] channel {} response {}", id, rpcResponse); 
  45.     } 
  46.  
  47.  
  48.     @Override 
  49.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 
  50.         cause.printStackTrace(); 
  51.         ctx.close(); 
  52.     } 
  53.  
  54.  
  55.     /** 
  56.      * 處理請求信息 
  57.      * @param rpcRequest 請求信息 
  58.      * @return 結果信息 
  59.      * @since 0.0.6 
  60.      */ 
  61.     private DefaultRpcResponse handleRpcRequest(final RpcRequest rpcRequest) { 
  62.         DefaultRpcResponse rpcResponse = new DefaultRpcResponse(); 
  63.         rpcResponse.seqId(rpcRequest.seqId()); 
  64.  
  65.  
  66.         try { 
  67.             // 獲取對應的 service 實現類 
  68.             // rpcRequest=>invocationRequest 
  69.             // 執行 invoke 
  70.             Object result = DefaultServiceFactory.getInstance() 
  71.                     .invoke(rpcRequest.serviceId(), 
  72.                             rpcRequest.methodName(), 
  73.                             rpcRequest.paramTypeNames(), 
  74.                             rpcRequest.paramValues()); 
  75.             rpcResponse.result(result); 
  76.         } catch (Exception e) { 
  77.             rpcResponse.error(e); 
  78.             log.error("[Server] execute meet ex for request", rpcRequest, e); 
  79.         } 
  80.  
  81.  
  82.         // 構建結果值 
  83.         return rpcResponse; 
  84.     } 
  85.  
  86.  

和以前類似,不過 handleRpcRequest 要稍微麻煩一點。

這里需要根據發射,調用對應的方法。

pojo

其中使用的出參、入參實現如下:

RpcRequest

  1. package com.github.houbb.rpc.common.rpc.domain; 
  2.  
  3.  
  4. import java.util.List; 
  5.  
  6.  
  7. /** 
  8.  * 序列化相關處理 
  9.  * (1)調用創建時間-createTime 
  10.  * (2)調用方式 callType 
  11.  * (3)超時時間 timeOut 
  12.  * 
  13.  * 額外信息: 
  14.  * (1)上下文信息 
  15.  * 
  16.  * @author binbin.hou 
  17.  * @since 0.0.6 
  18.  */ 
  19. public interface RpcRequest extends BaseRpc { 
  20.  
  21.  
  22.     /** 
  23.      * 創建時間 
  24.      * @return 創建時間 
  25.      * @since 0.0.6 
  26.      */ 
  27.     long createTime(); 
  28.  
  29.  
  30.     /** 
  31.      * 服務唯一標識 
  32.      * @return 服務唯一標識 
  33.      * @since 0.0.6 
  34.      */ 
  35.     String serviceId(); 
  36.  
  37.  
  38.     /** 
  39.      * 方法名稱 
  40.      * @return 方法名稱 
  41.      * @since 0.0.6 
  42.      */ 
  43.     String methodName(); 
  44.  
  45.  
  46.     /** 
  47.      * 方法類型名稱列表 
  48.      * @return 名稱列表 
  49.      * @since 0.0.6 
  50.      */ 
  51.     List<String> paramTypeNames(); 
  52.  
  53.  
  54.     // 調用參數信息列表 
  55.  
  56.  
  57.     /** 
  58.      * 調用參數值 
  59.      * @return 參數值數組 
  60.      * @since 0.0.6 
  61.      */ 
  62.     Object[] paramValues(); 
  63.  
  64.  

RpcResponse

  1. package com.github.houbb.rpc.common.rpc.domain; 
  2.  
  3.  
  4. /** 
  5.  * 序列化相關處理 
  6.  * @author binbin.hou 
  7.  * @since 0.0.6 
  8.  */ 
  9. public interface RpcResponse extends BaseRpc { 
  10.  
  11.  
  12.     /** 
  13.      * 異常信息 
  14.      * @return 異常信息 
  15.      * @since 0.0.6 
  16.      */ 
  17.     Throwable error(); 
  18.  
  19.  
  20.     /** 
  21.      * 請求結果 
  22.      * @return 請求結果 
  23.      * @since 0.0.6 
  24.      */ 
  25.     Object result(); 
  26.  
  27.  

BaseRpc

  1. package com.github.houbb.rpc.common.rpc.domain; 
  2.  
  3.  
  4. import java.io.Serializable
  5.  
  6.  
  7. /** 
  8.  * 序列化相關處理 
  9.  * @author binbin.hou 
  10.  * @since 0.0.6 
  11.  */ 
  12. public interface BaseRpc extends Serializable { 
  13.  
  14.  
  15.     /** 
  16.      * 獲取唯一標識號 
  17.      * (1)用來唯一標識一次調用,便于獲取該調用對應的響應信息。 
  18.      * @return 唯一標識號 
  19.      */ 
  20.     String seqId(); 
  21.  
  22.  
  23.     /** 
  24.      * 設置唯一標識號 
  25.      * @param traceId 唯一標識號 
  26.      * @return this 
  27.      */ 
  28.     BaseRpc seqId(final String traceId); 
  29.  
  30.  

ServiceFactory-服務工廠

為了便于對所有的 service 實現類統一管理,這里定義 service 工廠類。

ServiceFactory

  1. package com.github.houbb.rpc.server.service; 
  2.  
  3.  
  4. import com.github.houbb.rpc.server.config.service.ServiceConfig; 
  5. import com.github.houbb.rpc.server.registry.ServiceRegistry; 
  6.  
  7.  
  8. import java.util.List; 
  9.  
  10.  
  11. /** 
  12.  * 服務方法類倉庫管理類-接口 
  13.  * 
  14.  * 
  15.  * (1)對外暴露的方法,應該盡可能的少。 
  16.  * (2)對于外部的調用,后期比如 telnet 治理,可以使用比如有哪些服務列表? 
  17.  * 單個服務有哪些方法名稱? 
  18.  * 
  19.  * 等等基礎信息的查詢,本期暫時全部隱藏掉。 
  20.  * 
  21.  * (3)前期盡可能的少暴露方法。 
  22.  * @author binbin.hou 
  23.  * @since 0.0.6 
  24.  * @see ServiceRegistry 服務注冊,將服務信息放在這個類中,進行統一的管理。 
  25.  * @see ServiceMethod 方法信息 
  26.  */ 
  27. public interface ServiceFactory { 
  28.  
  29.  
  30.     /** 
  31.      * 注冊服務列表信息 
  32.      * @param serviceConfigList 服務配置列表 
  33.      * @return this 
  34.      * @since 0.0.6 
  35.      */ 
  36.     ServiceFactory registerServices(final List<ServiceConfig> serviceConfigList); 
  37.  
  38.  
  39.     /** 
  40.      * 直接反射調用 
  41.      * (1)此處對于方法反射,為了提升性能,所有的 class.getFullName() 進行拼接然后放進 key 中。 
  42.      * 
  43.      * @param serviceId 服務名稱 
  44.      * @param methodName 方法名稱 
  45.      * @param paramTypeNames 參數類型名稱列表 
  46.      * @param paramValues 參數值 
  47.      * @return 方法調用返回值 
  48.      * @since 0.0.6 
  49.      */ 
  50.     Object invoke(final String serviceId, final String methodName, 
  51.                   List<String> paramTypeNames, final Object[] paramValues); 
  52.  
  53.  

DefaultServiceFactory

作為默認實現,如下:

  1. package com.github.houbb.rpc.server.service.impl; 
  2.  
  3.  
  4. import com.github.houbb.heaven.constant.PunctuationConst; 
  5. import com.github.houbb.heaven.util.common.ArgUtil; 
  6. import com.github.houbb.heaven.util.lang.reflect.ReflectMethodUtil; 
  7. import com.github.houbb.heaven.util.util.CollectionUtil; 
  8. import com.github.houbb.rpc.common.exception.RpcRuntimeException; 
  9. import com.github.houbb.rpc.server.config.service.ServiceConfig; 
  10. import com.github.houbb.rpc.server.service.ServiceFactory; 
  11.  
  12.  
  13. import java.lang.reflect.InvocationTargetException; 
  14. import java.lang.reflect.Method; 
  15. import java.util.HashMap; 
  16. import java.util.List; 
  17. import java.util.Map; 
  18.  
  19.  
  20. /** 
  21.  * 默認服務倉庫實現 
  22.  * @author binbin.hou 
  23.  * @since 0.0.6 
  24.  */ 
  25. public class DefaultServiceFactory implements ServiceFactory { 
  26.  
  27.  
  28.     /** 
  29.      * 服務 map 
  30.      * @since 0.0.6 
  31.      */ 
  32.     private Map<String, Object> serviceMap; 
  33.  
  34.  
  35.     /** 
  36.      * 直接獲取對應的 method 信息 
  37.      * (1)key: serviceId:methodName:param1@param2@param3 
  38.      * (2)value: 對應的 method 信息 
  39.      */ 
  40.     private Map<String, Method> methodMap; 
  41.  
  42.  
  43.     private static final DefaultServiceFactory INSTANCE = new DefaultServiceFactory(); 
  44.  
  45.  
  46.     private DefaultServiceFactory(){} 
  47.  
  48.  
  49.     public static DefaultServiceFactory getInstance() { 
  50.         return INSTANCE; 
  51.     } 
  52.  
  53.  
  54.     /** 
  55.      * 服務注冊一般在項目啟動的時候,進行處理。 
  56.      * 屬于比較重的操作,而且一個服務按理說只應該初始化一次。 
  57.      * 此處加鎖為了保證線程安全。 
  58.      * @param serviceConfigList 服務配置列表 
  59.      * @return this 
  60.      */ 
  61.     @Override 
  62.     public synchronized ServiceFactory registerServices(List<ServiceConfig> serviceConfigList) { 
  63.         ArgUtil.notEmpty(serviceConfigList, "serviceConfigList"); 
  64.  
  65.  
  66.         // 集合初始化 
  67.         serviceMap = new HashMap<>(serviceConfigList.size()); 
  68.         // 這里只是預估,一般為2個服務。 
  69.         methodMap = new HashMap<>(serviceConfigList.size()*2); 
  70.  
  71.  
  72.         for(ServiceConfig serviceConfig : serviceConfigList) { 
  73.             serviceMap.put(serviceConfig.id(), serviceConfig.reference()); 
  74.         } 
  75.  
  76.  
  77.         // 存放方法名稱 
  78.         for(Map.Entry<String, Object> entry : serviceMap.entrySet()) { 
  79.             String serviceId = entry.getKey(); 
  80.             Object reference = entry.getValue(); 
  81.  
  82.  
  83.             //獲取所有方法列表 
  84.             Method[] methods = reference.getClass().getMethods(); 
  85.             for(Method method : methods) { 
  86.                 String methodName = method.getName(); 
  87.                 if(ReflectMethodUtil.isIgnoreMethod(methodName)) { 
  88.                     continue
  89.                 } 
  90.  
  91.  
  92.                 List<String> paramTypeNames = ReflectMethodUtil.getParamTypeNames(method); 
  93.                 String key = buildMethodKey(serviceId, methodName, paramTypeNames); 
  94.                 methodMap.put(key, method); 
  95.             } 
  96.         } 
  97.  
  98.  
  99.         return this; 
  100.     } 
  101.  
  102.  
  103.  
  104.  
  105.     @Override 
  106.     public Object invoke(String serviceId, String methodName, List<String> paramTypeNames, Object[] paramValues) { 
  107.         //參數校驗 
  108.         ArgUtil.notEmpty(serviceId, "serviceId"); 
  109.         ArgUtil.notEmpty(methodName, "methodName"); 
  110.  
  111.  
  112.         // 提供 cache,可以根據前三個值快速定位對應的 method 
  113.         // 根據 method 進行反射處理。 
  114.         // 對于 paramTypes 進行 string 連接處理。 
  115.         final Object reference = serviceMap.get(serviceId); 
  116.         final String methodKey = buildMethodKey(serviceId, methodName, paramTypeNames); 
  117.         final Method method = methodMap.get(methodKey); 
  118.  
  119.  
  120.         try { 
  121.             return method.invoke(reference, paramValues); 
  122.         } catch (IllegalAccessException | InvocationTargetException e) { 
  123.             throw new RpcRuntimeException(e); 
  124.         } 
  125.     } 
  126.  
  127.  
  128.     /** 
  129.      * (1)多個之間才用 : 分隔 
  130.      * (2)參數之間采用 @ 分隔 
  131.      * @param serviceId 服務標識 
  132.      * @param methodName 方法名稱 
  133.      * @param paramTypeNames 參數類型名稱 
  134.      * @return 構建完整的 key 
  135.      * @since 0.0.6 
  136.      */ 
  137.     private String buildMethodKey(String serviceId, String methodName, List<String> paramTypeNames) { 
  138.         String param = CollectionUtil.join(paramTypeNames, PunctuationConst.AT); 
  139.         return serviceId+PunctuationConst.COLON+methodName+PunctuationConst.COLON 
  140.                 +param; 
  141.     } 
  142.  
  143.  

ServiceRegistry-服務注冊類

接口

  1. package com.github.houbb.rpc.server.registry; 
  2.  
  3.  
  4. /** 
  5.  * 服務注冊類 
  6.  * (1)每個應用唯一 
  7.  * (2)每個服務的暴露協議應該保持一致 
  8.  * 暫時不提供單個服務的特殊處理,后期可以考慮添加 
  9.  * 
  10.  * @author binbin.hou 
  11.  * @since 0.0.6 
  12.  */ 
  13. public interface ServiceRegistry { 
  14.  
  15.  
  16.     /** 
  17.      * 暴露的 rpc 服務端口信息 
  18.      * @param port 端口信息 
  19.      * @return this 
  20.      * @since 0.0.6 
  21.      */ 
  22.     ServiceRegistry port(final int port); 
  23.  
  24.  
  25.     /** 
  26.      * 注冊服務實現 
  27.      * @param serviceId 服務標識 
  28.      * @param serviceImpl 服務實現 
  29.      * @return this 
  30.      * @since 0.0.6 
  31.      */ 
  32.     ServiceRegistry register(final String serviceId, final Object serviceImpl); 
  33.  
  34.  
  35.     /** 
  36.      * 暴露所有服務信息 
  37.      * (1)啟動服務端 
  38.      * @return this 
  39.      * @since 0.0.6 
  40.      */ 
  41.     ServiceRegistry expose(); 
  42.  
  43.  

實現

  1. package com.github.houbb.rpc.server.registry.impl; 
  2.  
  3.  
  4. import com.github.houbb.heaven.util.common.ArgUtil; 
  5. import com.github.houbb.rpc.common.config.protocol.ProtocolConfig; 
  6. import com.github.houbb.rpc.server.config.service.DefaultServiceConfig; 
  7. import com.github.houbb.rpc.server.config.service.ServiceConfig; 
  8. import com.github.houbb.rpc.server.core.RpcServer; 
  9. import com.github.houbb.rpc.server.registry.ServiceRegistry; 
  10. import com.github.houbb.rpc.server.service.impl.DefaultServiceFactory; 
  11.  
  12.  
  13. import java.util.ArrayList; 
  14. import java.util.List; 
  15.  
  16.  
  17. /** 
  18.  * 默認服務端注冊類 
  19.  * @author binbin.hou 
  20.  * @since 0.0.6 
  21.  */ 
  22. public class DefaultServiceRegistry implements ServiceRegistry { 
  23.  
  24.  
  25.     /** 
  26.      * 單例信息 
  27.      * @since 0.0.6 
  28.      */ 
  29.     private static final DefaultServiceRegistry INSTANCE = new DefaultServiceRegistry(); 
  30.  
  31.  
  32.     /** 
  33.      * rpc 服務端端口號 
  34.      * @since 0.0.6 
  35.      */ 
  36.     private int rpcPort; 
  37.  
  38.  
  39.     /** 
  40.      * 協議配置 
  41.      * (1)默認只實現 tcp 
  42.      * (2)后期可以拓展實現 web-service/http/https 等等。 
  43.      * @since 0.0.6 
  44.      */ 
  45.     private ProtocolConfig protocolConfig; 
  46.  
  47.  
  48.     /** 
  49.      * 服務配置列表 
  50.      * @since 0.0.6 
  51.      */ 
  52.     private List<ServiceConfig> serviceConfigList; 
  53.  
  54.  
  55.     private DefaultServiceRegistry(){ 
  56.         // 初始化默認參數 
  57.         this.serviceConfigList = new ArrayList<>(); 
  58.         this.rpcPort = 9527; 
  59.     } 
  60.  
  61.  
  62.     public static DefaultServiceRegistry getInstance() { 
  63.         return INSTANCE; 
  64.     } 
  65.  
  66.  
  67.     @Override 
  68.     public ServiceRegistry port(int port) { 
  69.         ArgUtil.positive(port, "port"); 
  70.  
  71.  
  72.         this.rpcPort = port; 
  73.         return this; 
  74.     } 
  75.  
  76.  
  77.     /** 
  78.      * 注冊服務實現 
  79.      * (1)主要用于后期服務調用 
  80.      * (2)如何根據 id 獲取實現?非常簡單,id 是唯一的。 
  81.      * 有就是有,沒有就拋出異常,直接返回。 
  82.      * (3)如果根據 {@link com.github.houbb.rpc.common.rpc.domain.RpcRequest} 獲取對應的方法。 
  83.      * 
  84.      * 3.1 根據 serviceId 獲取唯一的實現 
  85.      * 3.2 根據 {@link Class#getMethod(String, Class[])} 方法名稱+參數類型唯一獲取方法 
  86.      * 3.3 根據 {@link java.lang.reflect.Method#invoke(Object, Object...)} 執行方法 
  87.      * 
  88.      * @param serviceId 服務標識 
  89.      * @param serviceImpl 服務實現 
  90.      * @return this 
  91.      * @since 0.0.6 
  92.      */ 
  93.     @Override 
  94.     @SuppressWarnings("unchecked"
  95.     public synchronized DefaultServiceRegistry register(final String serviceId, final Object serviceImpl) { 
  96.         ArgUtil.notEmpty(serviceId, "serviceId"); 
  97.         ArgUtil.notNull(serviceImpl, "serviceImpl"); 
  98.  
  99.  
  100.         // 構建對應的其他信息 
  101.         ServiceConfig serviceConfig = new DefaultServiceConfig(); 
  102.         serviceConfig.id(serviceId).reference(serviceImpl); 
  103.         serviceConfigList.add(serviceConfig); 
  104.  
  105.  
  106.         return this; 
  107.     } 
  108.  
  109.  
  110.     @Override 
  111.     public ServiceRegistry expose() { 
  112.         // 注冊所有服務信息 
  113.         DefaultServiceFactory.getInstance() 
  114.                 .registerServices(serviceConfigList); 
  115.  
  116.  
  117.         // 暴露 netty server 信息 
  118.         new RpcServer(rpcPort).start(); 
  119.         return this; 
  120.     } 
  121.  
  122.  

ServiceConfig 是一些服務的配置信息,接口定義如下:

  1. package com.github.houbb.rpc.server.config.service; 
  2.  
  3.  
  4. /** 
  5.  * 單個服務配置類 
  6.  * 
  7.  * 簡化用戶使用: 
  8.  * 在用戶使用的時候,這個類應該是不可見的。 
  9.  * 直接提供對應的服務注冊類即可。 
  10.  * 
  11.  * 后續拓展 
  12.  * (1)版本信息 
  13.  * (2)服務端超時時間 
  14.  * 
  15.  * @author binbin.hou 
  16.  * @since 0.0.6 
  17.  * @param <T> 實現類泛型 
  18.  */ 
  19. public interface ServiceConfig<T> { 
  20.  
  21.  
  22.     /** 
  23.      * 獲取唯一標識 
  24.      * @return 獲取唯一標識 
  25.      * @since 0.0.6 
  26.      */ 
  27.     String id(); 
  28.  
  29.  
  30.     /** 
  31.      * 設置唯一標識 
  32.      * @param id 標識信息 
  33.      * @return this 
  34.      * @since 0.0.6 
  35.      */ 
  36.     ServiceConfig<T> id(String id); 
  37.  
  38.  
  39.     /** 
  40.      * 獲取引用實體實現 
  41.      * @return 實體實現 
  42.      * @since 0.0.6 
  43.      */ 
  44.     T reference(); 
  45.  
  46.  
  47.     /** 
  48.      * 設置引用實體實現 
  49.      * @param reference 引用實現 
  50.      * @return this 
  51.      * @since 0.0.6 
  52.      */ 
  53.     ServiceConfig<T> reference(T reference); 
  54.  
  55.  

測試

maven 引入

引入服務端的對應 maven 包:

  1. <dependency> 
  2.     <groupId>com.github.houbb</groupId> 
  3.     <artifactId>rpc-server</artifactId> 
  4.     <version>0.0.6</version> 
  5. </dependency> 

服務端啟動

  1. // 啟動服務 
  2. DefaultServiceRegistry.getInstance() 
  3.         .register(ServiceIdConst.CALC, new CalculatorServiceImpl()) 
  4.         .expose(); 

這里注冊了一個計算服務,并且設置對應的實現。

和以前實現類似,此處不再贅述。

啟動日志:

  1. [DEBUG] [2021-10-05 13:39:42.638] [main] [c.g.h.l.i.c.LogFactory.setImplementation] - Logging initialized using 'class com.github.houbb.log.integration.adaptors.stdout.StdOutExImpl' adapter. 
  2. [INFO] [2021-10-05 13:39:42.645] [Thread-0] [c.g.h.r.s.c.RpcServer.run] - RPC 服務開始啟動服務端 
  3. 十月 05, 2021 1:39:43 下午 io.netty.handler.logging.LoggingHandler channelRegistered 
  4. 信息: [id: 0xec4dc74f] REGISTERED 
  5. 十月 05, 2021 1:39:43 下午 io.netty.handler.logging.LoggingHandler bind 
  6. 信息: [id: 0xec4dc74f] BIND: 0.0.0.0/0.0.0.0:9527 
  7. 十月 05, 2021 1:39:43 下午 io.netty.handler.logging.LoggingHandler channelActive 
  8. 信息: [id: 0xec4dc74f, L:/0:0:0:0:0:0:0:0:9527] ACTIVE 
  9. [INFO] [2021-10-05 13:39:43.893] [Thread-0] [c.g.h.r.s.c.RpcServer.run] - RPC 服務端啟動完成,監聽【9527】端口 

ps: 寫到這里忽然發現忘記添加對應的 register 日志了,這里可以添加對應的 registerListener 拓展。

 

責任編輯:姜華 來源: 今日頭條
相關推薦

2021-10-27 08:10:15

Java 客戶端 Java 基礎

2021-10-19 08:58:48

Java 語言 Java 基礎

2021-10-14 08:39:17

Java Netty Java 基礎

2021-10-13 08:21:52

Java websocket Java 基礎

2021-10-20 08:05:18

Java 序列化 Java 基礎

2021-10-29 08:07:30

Java timeout Java 基礎

2019-09-23 19:30:27

reduxreact.js前端

2015-11-17 16:11:07

Code Review

2019-01-18 12:39:45

云計算PaaS公有云

2018-04-18 07:01:59

Docker容器虛擬機

2024-12-06 17:02:26

2020-07-02 15:32:23

Kubernetes容器架構

2010-05-26 17:35:08

配置Xcode SVN

2018-09-14 17:16:22

云計算軟件計算機網絡

2024-05-15 14:29:45

2024-01-02 12:17:44

Go傳統遠程

2023-02-20 09:55:00

微服務框架單體架構

2017-09-13 14:01:51

數據庫MongoDB數據庫即服務

2021-03-16 11:30:33

2015-05-06 09:36:05

Java語言從零開始學習
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 自拍视频国产 | 欧美色综合一区二区三区 | 亚洲一区 中文字幕 | 91视频国产区 | 黄色免费av| 午夜爽爽爽男女免费观看影院 | 欧美亚洲国产精品 | 国产专区在线 | 日韩成人免费 | 欧美日韩在线一区二区三区 | 毛片毛片毛片毛片毛片 | 国产一区久久久 | 网色 | 免费毛片网 | 日韩免费一区二区 | 91久久久久 | 国产精品久久久久久久免费观看 | 国产一区视频在线 | 97在线观视频免费观看 | 成人免费视频久久 | 蜜桃在线一区二区三区 | 成人av网站在线观看 | 久久不卡 | 国产一区二区在线播放 | 精品视频在线一区 | 希岛爱理在线 | 欧美狠狠操| 精品国产31久久久久久 | 午夜视频免费在线观看 | 毛片黄| 亚洲欧美日韩电影 | 中文字幕精品视频在线观看 | 亚洲一区中文字幕 | 手机av在线 | 亚洲欧美日韩一区二区 | 视频1区2区 | 久久精品亚洲精品国产欧美 | 久久欧美高清二区三区 | 精品一二三| 欧美成人a∨高清免费观看 欧美日韩中 | 日本特黄a级高清免费大片 特黄色一级毛片 |