rpc netty,netty在springboot中的使用

  rpc netty,netty在springboot中的使用

  今天翻看了一下妮蒂相关的知识点,正好练练手,简单捣鼓了这个演示;这里简单梳理一下;

  前提知识点:

  

Springboot、Netty、动态代理(反射)、反射

项目整体结构如下:

 

  

1.在父项目中引入相关依赖;

依赖关系groupIdorg.springframework.boot/groupId artifactId spring-boot-starter-web/artifactId version2.3.2.RELEASE/version/依赖关系groupId io。netty/groupId artifactId netty-all/artifactId version4.1.48.Final/version/依赖关系groupIdcom.alibaba/groupId artifact id fastjson/artifact id版本1。2 .58/版本/依赖关系依赖关系groupId组织。slf4j/groupId artifactId slf4j-log4j 12/artifactId版本2。0 .0-alpha 1/版本/依赖性

2.服务提供模块整体结构如下:

 

  这里重点关注一下RequestModel ResponseModel 两个消息体类,

  @Data@AllArgsConstructorpublic类请求模型{私有字符串请求id;私有字符串服务名私有字符串方法名私有类[]参数类型;私有对象[]参数值;} @ Data @ AllArgsConstructorpublic类响应模型{私有字符串响应id;私有字符串服务名私有字符串方法名私有字符串代码;私有字符串数据;}用于服务端和客户端的数据传输;再者就是关注ServerChannelInboundHandler 中的channelRead0()报文解码处理;

  @ Override protected void channel read 0(ChannelHandlerContext CTX,String msg){ StringBuilder sb=null;请求模型结果=空尝试{ //报文解析处理sb=new StringBuilder();result=JSON.parseObject(msg,请求模型。类);请求id=结果。get request id();字符串服务名=结果。获取服务名();圣

  ring 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()); } }客户端的模块代码如下;

  

 

  这里重点关注的是 ClientHandler 类中 channelRead0() 方法的处理

  

 @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) { System.out.println("收到服务端消息: " + 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 类中获取获取服务的处理;

 

  

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; }

测试结果:

 

  

 

  

 

  总结: 这个demo相对比较简单,但对于理解rpc 远程调用有一定帮助,最后分享一下这个代码地址:

  nettydemo: netty springboot rpc远程调用demo

  到此这篇关于基于Springboot+Netty实现rpc功能的文章就介绍到这了,更多相关Springboot Nett实现rpc内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: