mini-dubbo之服务发布

Provider目录结构

1.服务端的启动

/**
 
* Created by cheng.xi on 2017-04-1410:25.
 * 服务提供者端发布服务
 
* 可以使用API直接发布服务,也可以使用和Spring集成
 
* 这里是测试使用API发布服务
 
*/
public class TestApiProvider {
   
public static void main(String[] args) throws InterruptedException{
       
//要发布的服务
       
HelloWorldServicehelloWorldService = new HelloWorldServiceImpl();

       
//发布服务
       
DubboProvider dubboProvider = new DubboProvider();

       //注入端口,实现类,接口

        dubboProvider.setPort(3347);
       
dubboProvider.setRef(helloWorldService);
       
dubboProvider.setInterface(HelloWorldService.class);
       
//调用发布接口
       
dubboProvider.export();

   
}
}

2.服务的发布过程

进入到dubboProvider.export()方法内部看看里面都实现了什么

/**
 * 发布服务,每次只发布一个服务
 */
public synchronized void export() throws InterruptedException {
    //调用协议层,根据具体协议暴露服务
    Protocol protocol = MiniDubboProtocol.getMiniDubboProtocol();
    protocol.export(this.interfaceName,this.ref.getClass());
    //发布的服务缓存起来
}

再进去

protocol.export(this.interfaceName,this.ref.getClass());
public void export(String interfaceName, Class<?> impl) throws InterruptedException {
    //每个将每个接口的名字作为一个keykey用来作为对应实现的唯一键
    String key = interfaceName;
    exportedServices.put(key,impl);
    //打开服务其进行监听
    openServer();
    System.out.println("minidubboprotocol中:" + exportedServices.size());
}

进入到openServer();

private void openServer() throws InterruptedException {
    //服务器监听地址
    String address = "127.0.0.1";
    //端口号
    int port = 3347;
    //每个地址只打开一次
    String key = address + ":" + port;
    Server server = serverMap.get(key);
    if(null == server){
        //创建一个server
        serverMap.put(key,createServer(address,port));
    }
}

这里创建一个netty服务端,并绑定其提供者的实现

//创建server
private Server createServer(String address, int port) throws InterruptedException {
    ChannelHandler handler = new NettyServiceHandler(exportedServices);
    Server server = Transporters.bind(address,port,handler);
    System.out.println("minidubboprotocol创建完server后:" + exportedServices.size());
    return server;
}
 

Netty服务端Handler

可以看到请求的接口名,方法名,参数都被封装到了request类中,并通过网络传输到netty的服务端,然后使用反射执行调用的方法,把执行的结果返回给客户端(关于netty大家可以多看看《netty实战》)

public class NettyServiceHandler extends SimpleChannelInboundHandler implements ChannelHandler{

    private Map<String, Class<?>> exportedServices;

    public NettyServiceHandler(Map<String, Class<?>> exportedServices) {
        this.exportedServices = exportedServices;
    }

    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object object) throws Exception {
        System.out.println("handlerexportedServices" + exportedServices.size());
        Request request = (Request)object;
        String serviceName = request.getInterfaceName();
        String methodName = request.getMethodName();
        Class<?>[] parameterTypes = request.getParameterTypes();
        Object[] arguments = request.getArgs();
        Class serviceClass = exportedServices.get(serviceName);

        Method method = serviceClass.getMethod(methodName,parameterTypes);
        Object result = method.invoke(serviceClass.newInstance(),arguments);

        Response response = new Response();
        response.setResult(result);

        channelHandlerContext.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
}

至于netty服务的启动看代码Server server = Transporters.bind(address,port,handler);

//绑定,监听
public static Server bind(String address, int port, ChannelHandler handler) throws InterruptedException {
    Server server = new NettyServer(address,port,handler);
    return server;
}

 

public class NettyServer implements Server{

    private String address;
    private int port;
    private ChannelHandler handler;

    public NettyServer(String address, int port, ChannelHandler handler) throws InterruptedException {
        this.address = address;
        this.port= port;
        this.handler = handler;
        doOpen();
    }

    public void doOpen() throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try{
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup);
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    ChannelPipeline pipeline = socketChannel.pipeline();
                    pipeline.addLast(new ObjectDecoder(1024*1024, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));
                    pipeline.addLast(new ObjectEncoder());
                    pipeline.addLast((SimpleChannelInboundHandler)handler);
                }
            });
            serverBootstrap.option(ChannelOption.SO_BACKLOG,1024);
            serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE,true);
            ChannelFuture future = serverBootstrap.bind(address,port).sync();
            //future.channel().closeFuture().sync();
        }finally{
            //workerGroup.shutdownGracefully();
            //bossGroup.shutdownGracefully();
        }
    }

}

到这服务就启动起来了


猜你喜欢

转载自blog.csdn.net/rock93/article/details/79728849