All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.dongliu.prettypb.rpc.RpcServer Maven / Gradle / Ivy

There is a newer version: 0.3.5
Show newest version
package net.dongliu.prettypb.rpc;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import net.dongliu.prettypb.rpc.config.ServerRegister;
import net.dongliu.prettypb.rpc.common.PeerInfo;
import net.dongliu.prettypb.rpc.server.RequestHandler;
import net.dongliu.prettypb.rpc.server.RpcServerChannelInitializer;
import net.dongliu.prettypb.rpc.server.RpcServerChannelRegistry;
import net.dongliu.prettypb.rpc.server.RpcServiceRegistry;
import net.dongliu.prettypb.rpc.utils.RenamingThreadFactoryProxy;
import net.dongliu.prettypb.runtime.ExtensionRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * proto rpc server.
 *
 * @author Dong Liu
 */
public class RpcServer {

    private PeerInfo serverPeer;

    private int minWorkerNum = 10;
    private int maxWorkerNum = 200;

    private RpcServiceRegistry rpcServiceRegistry;
    /**
     * extension registry for rpc service
     */
    private ExtensionRegistry extensionRegistry;
    private RpcServerChannelRegistry rpcServerChannelRegistry;
    private ThreadPoolExecutor rpcServiceExecutor;
    private ServerBootstrap bootstrap;

    /**
     * extension registry for wire payload
     */
    private ExtensionRegistry wpExtensionRegistry;

    private static Logger logger = LoggerFactory.getLogger(RpcServer.class);

    private ServerRegister serverRegister;

    /**
     * new server.
     *
     * @param ip   the ip listened on
     * @param port the port listened on
     */
    public RpcServer(String ip, int port) {
        this.serverPeer = new PeerInfo(ip, port);
        this.rpcServerChannelRegistry = new RpcServerChannelRegistry();
        this.rpcServiceRegistry = new RpcServiceRegistry();
    }

    /**
     * register service
     *
     * @param serviceImpl instance of rpc service impl class
     */
    public void registryService(Object serviceImpl) {
        rpcServiceRegistry.registerService(serviceImpl);
    }

    /**
     * start server, and block till stopped. this should be called when all parameters has been set
     */
    public void start() {
        rpcServiceExecutor = new ThreadPoolExecutor(minWorkerNum, maxWorkerNum,
                60, TimeUnit.SECONDS, new ArrayBlockingQueue(10_000),
                new ThreadPoolExecutor.AbortPolicy());

        NioEventLoopGroup parentGroup = new NioEventLoopGroup(0,
                new RenamingThreadFactoryProxy("boss", Executors.defaultThreadFactory()));
        NioEventLoopGroup childGroup = new NioEventLoopGroup(0,
                new RenamingThreadFactoryProxy("worker", Executors.defaultThreadFactory()));

        RequestHandler requestHandler = new RequestHandler(serverPeer, rpcServiceRegistry,
                extensionRegistry, rpcServiceExecutor, rpcServerChannelRegistry);
        RpcServerChannelInitializer childHandler = new RpcServerChannelInitializer(null,
                wpExtensionRegistry, requestHandler);
        bootstrap = new ServerBootstrap();
        bootstrap.group(parentGroup, childGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(childHandler)
                .localAddress(serverPeer.getPort());

        bootstrap.option(ChannelOption.SO_SNDBUF, 1_048_576)
                .option(ChannelOption.SO_RCVBUF, 1_048_576)
                .childOption(ChannelOption.SO_RCVBUF, 1_048_576)
                .childOption(ChannelOption.SO_SNDBUF, 1_048_576)
                .option(ChannelOption.TCP_NODELAY, true);

        // start
        ChannelFuture cf;
        try {
            cf = bootstrap.bind().sync();
        } catch (InterruptedException e) {
            logger.error("start server failed, interrupted.");
            Thread.currentThread().interrupt();
            return;
        }

        // register
        if (serverRegister != null) {
            try {
                serverRegister.register(serverPeer);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

    }

    /**
     * stop rpc server
     */
    public void stop() {
        logger.info("stop proto rpc server...");
        if (serverRegister != null) {
            try {
                serverRegister.close();
            } catch (Exception e) {
                logger.error("", e);
            }
        }
        try {
            bootstrap.group().shutdownGracefully().sync();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        try {
            bootstrap.childGroup().shutdownGracefully().sync();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        rpcServiceExecutor.shutdown();
        try {
            rpcServiceExecutor.awaitTermination(10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }


    /**
     * set min worker size. default is 10
     *
     * @param num must larger than 0
     */
    public RpcServer setMinWorkerNum(int num) {
        if (num <= 0) {
            throw new IllegalArgumentException("Worker num should be larger than 0");
        }
        this.minWorkerNum = num;
        return this;
    }

    /**
     * set max worker size. default is 200
     *
     * @param num must larger than 0
     */
    public RpcServer setMaxWorkerNum(int num) {
        if (num <= 0) {
            throw new IllegalArgumentException("Worker num should be larger than 0");
        }
        this.maxWorkerNum = num;
        return this;
    }

    /**
     * the rpc messages extension registry
     */
    public ExtensionRegistry getExtensionRegistry() {
        return extensionRegistry;
    }

    /**
     * set extension registry for rpc messages
     */
    public RpcServer setExtensionRegistry(ExtensionRegistry extensionRegistry) {
        this.extensionRegistry = extensionRegistry;
        return this;
    }

    /**
     * get wire payload extension registry
     */
    public ExtensionRegistry getWpExtensionRegistry() {
        return wpExtensionRegistry;
    }

    /**
     * set extension registry for wire payload
     */
    public RpcServer setWpExtensionRegistry(ExtensionRegistry wpExtensionRegistry) {
        this.wpExtensionRegistry = wpExtensionRegistry;
        return this;
    }

    public RpcServer setServerRegister(ServerRegister serverRegister) {
        this.serverRegister = serverRegister;
        return this;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy