为什么80%的码农都做不了架构师?>>>   

先上一张图

使用netty 5.* 实现类似dubbo的服务调用

公共类

api

实际开发时 提供者需要实现该包下面所有接口, 而服务调用者则是通过该包内提供的接口调用方法

package apis;/*** Created by xuchonggao on 2017/6/26.*/
public interface UserService {public String findUser(String userName);String findUserList(int pageNum, int pageSize);
}

请求POJO

注意: 这个类必须是可序列化的,包括里面的属性

package dub;import java.io.Serializable;
import java.util.Arrays;/*** 调用请求类* Created by xuchonggao on 2017/6/27.*/
public class DubReq implements Serializable {private static final long serialVersionUID = 422805234202183587L;private Class interfaceClass;private String methonName;private Class[] paramTypes;private Object[] args;public DubReq() {}public Class getInterfaceClass() {return interfaceClass;}public DubReq setInterfaceClass(Class interfaceClass) {this.interfaceClass = interfaceClass;return this;}public String getMethonName() {return methonName;}public DubReq setMethonName(String methonName) {this.methonName = methonName;return this;}public Class[] getParamTypes() {return paramTypes;}public DubReq setParamTypes(Class[] paramTypes) {this.paramTypes = paramTypes;return this;}public Object[] getArgs() {return args;}public DubReq setArgs(Object[] args) {this.args = args;return this;}public DubReq(Class interfaceClass, String methonName, Class[] paramTypes, Object[] args) {this.interfaceClass = interfaceClass;this.methonName = methonName;this.paramTypes = paramTypes;this.args = args;}@Overridepublic String toString() {return "DubReq{" +"interfaceClass=" + interfaceClass +", methonName='" + methonName + '\'' +", paramTypes=" + Arrays.toString(paramTypes) +", args=" + Arrays.toString(args) +'}';}
}

服务端

package dub.server;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;/*** Created by xuchonggao on 2017/6/26.*/
public class DubServer {private int port;public DubServer(int port) {this.port = port;}public void run() throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap(); // (2)b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) // (3).childHandler(new ChannelInitializer<SocketChannel>() { // (4)@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new ObjectDecoder(1024*1024, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));ch.pipeline().addLast(new ObjectEncoder());ch.pipeline().addLast(new DuBHandler());}}).option(ChannelOption.SO_BACKLOG, 128)          // (5).childOption(ChannelOption.SO_KEEPALIVE, true); // (6)// Bind and start to accept incoming connections.ChannelFuture f = b.bind(port).sync(); // (7)// Wait until the dub.server socket is closed.// In this example, this does not happen, but you can do that to gracefully// shut down your dub.server.f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}public static void main(String[] args) throws Exception {new DubServer(8080).run();}}
package dub.server;import apis.UserService;
import dub.DubReq;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import provider.UserServiceImpl;import java.lang.reflect.Method;/*** Created by xuchonggao on 2017/6/26.*/
public class DuBHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("服务端收到消息:   " + msg);DubReq req = (DubReq) msg;// 1. 根据类名返回对象Object target = this.getInstenceByInterfaceClass(req.getInterfaceClass());// 2. 获取方法名String methodName = req.getMethonName();// 3. 获取方法参数类型// 4. 获取方法Method method = target.getClass().getMethod(methodName, req.getParamTypes());// 5. 获取参数值//调用方法 获取返回值Object res = method.invoke(new UserServiceImpl(), req.getArgs());// 写回给调用端ctx.writeAndFlush(res);}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {ctx.flush();}private Object getInstenceByInterfaceClass(Class clazz) {//根据接口返回对应的实例if (UserService.class.equals(clazz)) {return new UserServiceImpl();}return null;}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {super.exceptionCaught(ctx, cause);}
}

调用方

package dub.client;import apis.UserService;/*** Created by xuchonggao on 2017/6/26.*/
public class DubClient {public static void main(String[] args) throws Exception {// 实际上返回的是一个代理类  通过代理类发送网络请求调用服务提供者UserService userService  = (UserService) DubServiceProxy.remote(UserService.class);System.out.println(userService.findUser("aaa"));System.out.println(userService.findUser("0001"));System.out.println(userService.findUserList(1,10));}
}
package dub.client;import dub.DubReq;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;/*** 消费者handler* Created by xuchonggao on 2017/6/26.*/
public class DubConsumeHandler implements InvocationHandler {private Object res;public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {//配置客户端线程组EventLoopGroup group = new NioEventLoopGroup();try {//配置客户端启动辅助类Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new ObjectDecoder(1024, ClassResolvers.cacheDisabled(this.getClass().getClassLoader())));ch.pipeline().addLast(new ObjectEncoder());ch.pipeline().addLast(new ConsumeHandler(proxy, method, args));}});//从注册中心获取ip和端口ChannelFuture f = b.connect("127.0.0.1", 8080).sync();f.channel().closeFuture().sync();} finally {group.shutdownGracefully();}return res;}private class ConsumeHandler extends ChannelInboundHandlerAdapter {private Object proxy;private Method method;private Object[] args;public ConsumeHandler(Object proxy, Method method, Object[] args) {this.proxy = proxy;this.method = method;this.args = args;}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {// 传输的对象必须实现序列化接口 包括其中的属性DubReq req = new DubReq(proxy.getClass().getInterfaces()[0], method.getName(), method.getParameterTypes(), args);ctx.write(req);ctx.flush();}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("调用成功");res = msg;ctx.flush();//收到响应后断开连接ctx.close();}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {ctx.flush();}}}
package dub.client;import java.lang.reflect.Proxy;/*** 生成接口代理类* Created by xuchonggao on 2017/6/26.*/
public class DubServiceProxy {public static Object remote(Class clazz) {return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new DubConsumeHandler());}
}

结果显示

Connected to the target VM, address: '127.0.0.1:64393', transport: 'socket'
调用成功
userName:aaa
调用成功
userName:0001
调用成功
查询第1页,10条数据
Disconnected from the target VM, address: '127.0.0.1:64393', transport: 'socket'Process finished with exit code 0

码云地址

点我

转载于:https://my.oschina.net/razox/blog/1036892

使用netty模仿dubbo服务相关推荐

  1. dubbo服务发布一之服务暴露

    整体流程以调试 om.alibaba.dubbo.demo.provider.DemoProvider来演示dubbo服务的发布流程. 1.启动Spring容器 参照dubbo容器的启动, https ...

  2. Dubbo服务引用过程

    Dubbo服务引用 大致流程 Provider将服务暴露出来并且注册到注册中心,而Consumer通过注册中心获取Provider的信息,之后将自己封装成一个调用类去与Provider进行交互. 首先 ...

  3. Dubbo服务发布调用实现

    服务发布调用实现 系统需求 根据商品id,查询商品信息 Dao 单表查询,不需要写代码 使用Mybatis逆向工程生成的代码 Interface 在taotao-manager-interface工程 ...

  4. dubbo服务接口如何mock_2019年Dubbo你掌握的如何?快看看这30道高频面试题!

    前言 Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式 ...

  5. 使用Maven构建Dubbo服务的可运行jar包

    本文为<基于Dubbo的分布式系统架构视频教程>的课程系列文档,更多课程信息,请关注:http://www.roncoo.com Dubbo视频教程--基础篇--第07节--使用Maven ...

  6. Dubbo服务暴露的流程

    在Dubbo服务暴露中,需要被暴露的服务的接口类首先会通过proxyFactory代理工厂获得代理的对象invoker,而暴露之后的服务被调用,也将都会通过这个invoker来调用相关的类. 在dub ...

  7. Dubbo服务导出原理

    文章目录 1. 服务导出的入口方法 2. 服务导出原理 2.1 刷新配置参数 2.1 确定协议,生成URL 2.3 启动对应协议的服务器 2.4 向注册中心注册服务 2.6 监听动态配置修改 1. 服 ...

  8. (转)淘淘商城系列——引用dubbo服务

    http://blog.csdn.net/yerenyuan_pku/article/details/72758663 上文我们一起学习了如何发布一个dubbo服务,本文我就来教大家如何在web工程中 ...

  9. (转)淘淘商城系列——发布dubbo服务

    http://blog.csdn.net/yerenyuan_pku/article/details/72758639 Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入, ...

最新文章

  1. 使用Python+OpenCV+dlib为人脸生成口罩
  2. python算法题_Python算法题
  3. BAT 批处理命令 - 获取时间并进行自定义年月日、时分秒格式实例演示
  4. SAP 动态设置 GUI STATUS 灰色不可用 或者隐藏
  5. 用500行纯前端代码在浏览器中构建一个Tableau
  6. why new AET extension field creation will lead to session restart
  7. $(document).ready() 和 window.onload 方法比较
  8. java jni调用dll_浅谈JNI的使用--java调用dll(原创)
  9. 南京大学计算机专业考研难吗,计算机专业考研,除了南大和中山,还有哪些大学难度大性价比高...
  10. IXI MEGA声卡M4 6 8 PIUS M2 M-NU2 NU4安装调试教程
  11. 基于YOLOv5的银行卡卡号识别(一)
  12. 微软卷土重来 只收购雅虎搜索业务
  13. ecu根据什么信号对点火提前角_【科普】汽车ECU现状及发展趋势
  14. 文献检索(学术搜索)
  15. 如何设置显示网络计算机,如何在台式计算机上设置无线局域网络
  16. 阿里云VPC网络内网实例通过SNAT连接外网
  17. 我的梦想就是不工作,有什么错?
  18. 电网调度计算机系统目前有三种,电网调度厂站端调试员高级工技能鉴定试题整理(包括图).doc...
  19. [Power Query] 添加列
  20. redis系列七LUR清除算法

热门文章

  1. 【数据库】SQLite和MySQL之间的对比和选择
  2. c语言1变A,c语言那些细节之a+1和a+1的区别
  3. hadoop 2 java hdfs_Hadoop2.6.0学习笔记(二)HDFS访问
  4. Java学习总结:49(字符缓冲流:BufferedReader)
  5. Java项目:零食商城系统(java+SSM+jsp+MySQL+EasyUI)
  6. 多重集表示合json数据_计数DP(划分数,多重集组合数)
  7. VUE input唤起键盘 底部固定的标签被顶上去解决办法
  8. iOS 11 导致tableview 刷新之后漂移问题
  9. UIBezierPath和CAShapeLayer创建不规则View(Swift 3.0)
  10. 构建基于Chromium的应用程序(Winform程序加载Html页面)