欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Springboot+Netty實現(xiàn)rpc的方法 附demo

 更新時間:2022年02月28日 11:42:46   作者:北_塵  
這篇文章主要介紹了基于Springboot+Netty實現(xiàn)rpc功能,在父項目中引入相關(guān)依賴結(jié)合實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

今天翻看了一下Netty相關(guān)的知識點,正好練練手,簡單搗鼓了這個demo;這里簡單梳理一下;

前提知識點:

Springboot、 Netty、動態(tài)代理(反射)、反射

項目整體結(jié)構(gòu)如下:

 1.在父項目中引入相關(guān)依賴;

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.48.Final</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.58</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>2.0.0-alpha1</version>
        </dependency>

2.服務(wù)提供模塊整體結(jié)構(gòu)如下:

 這里重點關(guān)注一下 RequestModel  ResponseModel 兩個消息體類,

@Data
@AllArgsConstructor
public class RequestModel {
 
    private String requestId;
    private String serviceName;
    private String methodName;
    private Class[] paramTypes;
    private Object[] paramValues;
 
}
@Data
@AllArgsConstructor
public class ResponseModel {
    private String responseId;
    private String serviceName;
    private String methodName;
    private String code;
    private String data;
}

用于服務(wù)端和客戶端的數(shù)據(jù)傳輸;再者就是關(guān)注 ServerChannelInboundHandler 中的 channelRead0() 報文解碼處理;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        StringBuilder sb = null;
        RequestModel result = null;
        try {
            // 報文解析處理
            sb = new StringBuilder();
            result = JSON.parseObject(msg, RequestModel.class);
 
            requestId = result.getRequestId();
            String serviceName = result.getServiceName();
            String methodName = result.getMethodName();
            Class[] paramType = result.getParamTypes();
            Object[] paramValue = result.getParamValues();
            System.out.println(serviceName + "  " + methodName);
            String substring = serviceName.substring(serviceName.lastIndexOf(".") + 1);
            String s = substring.substring(0, 1).toLowerCase() + substring.substring(1);
            Object serviceObject = applicationContext.getBean(s);
            Method method = Class.forName(serviceName).getMethod(methodName, paramType);
            Object returnValue = method.invoke(serviceObject, paramValue);
            ResponseModel responseModel = new ResponseModel(requestId,serviceName,methodName,"200",JSON.toJSONString(returnValue));
            sb.append(JSON.toJSONString(responseModel));
            sb.append("\n");
            System.out.println(sb.toString());
            ctx.writeAndFlush(sb);
        } catch (Exception e) {
            ResponseModel responseModel = new ResponseModel(requestId,"","","500",e.getMessage());
            String errorCode = JSON.toJSONString(responseModel)+"\n";
            log.error(errorCode);
            ctx.writeAndFlush(errorCode);
            log.error("報文解析失敗: " + e.getMessage());
        }
    }

客戶端的模塊代碼如下; 

這里重點關(guān)注的是 ClientHandler 類中 channelRead0() 方法的處理

 @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        System.out.println("收到服務(wù)端消息: " + msg);
 
        ResponseModel responseModel = JSON.parseObject(msg,ResponseModel.class);
        String responseId = responseModel.getResponseId();
        Promise promise = LocalPromise.promiseMap.remove(responseId);
        if(promise != null){
            String code = responseModel.getCode();
            if(code.equals("200")){
                promise.setSuccess(responseModel.getData());
            }else{
                promise.setFailure(new RuntimeException(responseModel.getData()));
            }
        }
    }

AppStart 類中獲取獲取服務(wù)的處理;

private <T> T getProxyService(Class<T> serviceClass) {
        Object service = Proxy.newProxyInstance(serviceClass.getClassLoader(), new Class[]{serviceClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Channel channel = NettyClient.getChannel(host, port);
                RequestModel requestModel = new RequestModel("100001", method.getDeclaringClass().getName(), method.getName(), method.getParameterTypes(), args);
                channel.writeAndFlush(JSON.toJSONString(requestModel) + "\n");
                Promise promise = new DefaultPromise(channel.eventLoop());
                LocalPromise.promiseMap.put(requestModel.getRequestId(), promise);
 
                System.out.println(LocalPromise.promiseMap+">>>>>>>>>>>>");
                promise.await();
                if (promise.isSuccess()) {
                    Class<?> returnType = method.getReturnType();
                    return JSON.toJavaObject(JSON.parseObject(promise.getNow()+""),returnType);
                } else {
                    System.out.println(promise.cause());
                    return promise.cause();
                }
            }
        });
        return (T) service;
    }

 測試結(jié)果:

總結(jié): 這個demo相對比較簡單,但對于理解rpc 遠程調(diào)用有一定幫助,最后分享一下這個代碼地址:

nettydemo: netty springboot rpc遠程調(diào)用demo

到此這篇關(guān)于基于Springboot+Netty實現(xiàn)rpc功能的文章就介紹到這了,更多相關(guān)Springboot Nett實現(xiàn)rpc內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java定時器Timer與TimerTask的使用詳解

    Java定時器Timer與TimerTask的使用詳解

    這篇文章主要介紹了Java定時器Timer與TimerTask的使用詳解,在JDK類庫中Timer主要負責(zé)計劃任務(wù)的功能,也就是在指定時間執(zhí)行某一任務(wù),執(zhí)行時候會在主線程之外起一個單獨的線程執(zhí)行指定的任務(wù),該類主要是設(shè)置任務(wù)計劃,但封裝的類是TimerTask類,需要的朋友可以參考下
    2023-10-10
  • springboot 在linux后臺運行的方法

    springboot 在linux后臺運行的方法

    這篇文章主要介紹了springboot 在linux后臺運行的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • 一文教會你用mybatis查詢數(shù)據(jù)庫數(shù)據(jù)

    一文教會你用mybatis查詢數(shù)據(jù)庫數(shù)據(jù)

    MyBatis本身是一個數(shù)據(jù)庫連接框架,可以認為是JDBC的升級版,下面這篇文章主要給大家介紹了關(guān)于mybatis查詢數(shù)據(jù)庫數(shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • 學(xué)會Java字節(jié)碼指令,成為技術(shù)大佬

    學(xué)會Java字節(jié)碼指令,成為技術(shù)大佬

    Java 字節(jié)碼指令是 JVM 體系中非常難啃的一塊硬骨頭,我估計有些讀者會有這樣的疑惑,“Java 字節(jié)碼難學(xué)嗎?我能不能學(xué)會???”本文帶領(lǐng)大家一探究竟,幫助大家搞懂java底層代碼如何執(zhí)行
    2021-08-08
  • Java通過Lambda函數(shù)的方式獲取屬性名稱

    Java通過Lambda函數(shù)的方式獲取屬性名稱

    這篇文章主要介紹了通過Lambda函數(shù)的方式獲取屬性名稱,實現(xiàn)步驟是通過定義一個函數(shù)式接口, 用來接收lambda方法引用,本文結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2023-10-10
  • JavaWeb Struts文件上傳功能實現(xiàn)詳解

    JavaWeb Struts文件上傳功能實現(xiàn)詳解

    這篇文章主要為大家詳細介紹了JavaWeb Struts文件上傳功能實現(xiàn)過程,思路清晰,供大家參考,感興趣的小伙伴們可以參考一下
    2016-06-06
  • SpringBoot集成drools的實現(xiàn)示例

    SpringBoot集成drools的實現(xiàn)示例

    本文主要介紹了SpringBoot集成drools的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • java中l(wèi)ist的用法和實例講解

    java中l(wèi)ist的用法和實例講解

    這篇文章主要介紹了java中l(wèi)ist的用法和實例講解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 淺析Java中String與StringBuffer拼接的區(qū)別

    淺析Java中String與StringBuffer拼接的區(qū)別

    String拼接會創(chuàng)建一個新的String對象,存儲拼接后的字符串,StringBuffer拼接是直接在本身拼接,會即時刷新。下面通過本文給大家介紹Java中String與StringBuffer拼接的區(qū)別,感興趣的朋友一起看看吧
    2017-06-06
  • 如何利用postman完成JSON串的發(fā)送功能(springboot)

    如何利用postman完成JSON串的發(fā)送功能(springboot)

    這篇文章主要介紹了如何利用postman完成JSON串的發(fā)送功能(springboot),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07

最新評論