功能介绍
第一个版本,使用netty完成一个RPC调用,使得在开发时通过调用本地方法即可完成远程调用。主要设计内容netty、自定义协议、反射等。
功能架构图
- 启动nettyserver。
- 客户端调用本地UserService的方法。
- 客户端通过反射实现netty远程调用,调用server的实现类。
- 客户端请求成功,获得响应之后打印结果。
功能预览
项目结构图
±–dubbo-client springboot服务,client端
±–dubbo-common 公共模块,放rpc的编解码内容
±–dubbo-server netty服务模块
±–dubbo-server-service 接口信息
主要说明
此为第一个版本,使用很牵强的方式,完成了RPC调用,稍后会逐步优化,稍后会逐步分完善,添加自动扫描加载,负载均衡等RPC框架中必要的功能。
核心代码
Server端
public class NettyServer {
public static void startServer(String hostName, int port) {
startServer0(hostName,port);
}
//编写一个方法,完成对NettyServer的初始化和启动
private static void startServer0(String hostname, int port) {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new DubboDecoder ());
pipeline.addLast(new DubboEncoder ());
pipeline.addLast(new NettyServerHandler ()); //业务处理器
}
}
);
ChannelFuture channelFuture = serverBootstrap.bind(hostname, port).sync();
System.out.println("服务提供方开始提供服务~~");
channelFuture.channel().closeFuture().sync();
}catch (Exception e) {
e.printStackTrace();
}
finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
Client端
public static void main (String[] args)
{
RpcProxy rpcProxy = new RpcProxy();
UserService bean = rpcProxy.getBean (UserService.class);
//调用本地方法,实际是进行了远程调用。
String userNameById = bean.getUserNameById (12l);
System.out.println ("userName:"+userNameById);
}
public class RpcProxy
{
//编写方法使用代理模式,获取一个代理对象
public <T> T getBean(final Class<T> serivceClass) {
return (T) Proxy.newProxyInstance(serivceClass.getClassLoader(),
new Class<?>[]{serivceClass}, new InvocationHandler() {
//这里实际上是封装RpcRequest请求对象,然后通过Netty发给服务端
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//封装RpcRequest对象---->
NettyClientHandler client = new NettyClientHandler();
//创建EventLoopGroup
NioEventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(
new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new DubboDecoder ());
pipeline.addLast(new DubboEncoder ());
pipeline.addLast(client);
}
}
);
try {
ChannelFuture future = bootstrap.connect ("127.0.0.1", 7777).sync ();
String s = serivceClass.getSimpleName () + "#" + method.getName () + "#" + args[0];
DubboProtocol dubboProtocol = new DubboProtocol (s);
future.channel ().writeAndFlush (dubboProtocol);
} catch (Exception e) {
e.printStackTrace();
}
//等待其返回
Thread.sleep (1000L);
return client.getResult ();
}
});
}
}
源码地址:git源码地址