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

rpc.turbo.server.TurboServer Maven / Gradle / Ivy

The newest version!
package rpc.turbo.server;

import java.io.Closeable;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import io.netty.channel.EventLoopGroup;
import rpc.turbo.common.EventLoopGroupHolder;
import rpc.turbo.config.HostPort;
import rpc.turbo.config.server.Protocol;
import rpc.turbo.config.server.ServerConfig;
import rpc.turbo.filter.RestServerFilter;
import rpc.turbo.filter.RpcServerFilter;
import rpc.turbo.invoke.ServerInvokerFactory;
import rpc.turbo.param.MethodParamClassResolver;
import rpc.turbo.serialization.Serializer;
import rpc.turbo.serialization.SerializerFactory;
import rpc.turbo.transport.server.rest.NettyRestServer;
import rpc.turbo.transport.server.rpc.NettyRpcServer;

public final class TurboServer implements Closeable {
	private static final Log logger = LogFactory.getLog(TurboServer.class);

	// 线程数量用配置的方式更合理一些,但需要用户深入理解这个逻辑,暂时先这样吧
	private static final ForkJoinPool serverForkJoinPool = new ForkJoinPool(64);

	private Map serverMap = new HashMap<>();
	private Set portSet = new HashSet<>();

	private boolean classIdRegistered = false;

	private final Serializer serializer;
	private final ServerInvokerFactory invokerFactory;
	private final EventLoopGroup eventLoopGroup;
	private final ServerConfig serverConfig;
	private final CopyOnWriteArrayList rpcFilters = new CopyOnWriteArrayList<>();
	private final CopyOnWriteArrayList restFilters = new CopyOnWriteArrayList<>();

	private volatile boolean isClosed = false;

	static {
		// 自动资源清理
		Runtime.getRuntime().addShutdownHook(
				new Thread(() -> serverForkJoinPool.shutdownNow(), "serverForkJoinPool-shutdown-thread"));
	}

	/**
	 * 需要执行 {@link #startAndRegisterServer()}
	 * 
	 * @param serverConfig
	 */
	public TurboServer(ServerConfig serverConfig, ServerInvokerFactory invokerFactory) {
		Objects.requireNonNull(serverConfig, "serverConfig");
		Objects.requireNonNull(invokerFactory, "invokerFactory");
		this.serverConfig = serverConfig;
		this.invokerFactory = invokerFactory;
		this.eventLoopGroup = EventLoopGroupHolder.get();

		this.serializer = SerializerFactory.createSerializer(serverConfig.getSerializer());

		MethodParamClassResolver classResolver = new MethodParamClassResolver(invokerFactory);
		this.serializer.setClassResolver(classResolver);
	}

	/**
	 * 需要手工startServer
	 * 
	 * @param group
	 * @param app
	 */
	public TurboServer(String group, String app) {
		this(new ServerConfig(group, app), new ServerInvokerFactory(group, app));
	}

	public void addFirst(RpcServerFilter filter) {
		rpcFilters.add(0, filter);
	}

	public void addLast(RpcServerFilter filter) {
		rpcFilters.add(filter);
	}

	public void addFirst(RestServerFilter filter) {
		restFilters.add(0, filter);
	}

	public void addLast(RestServerFilter filter) {
		restFilters.add(filter);
	}

	/**
	 * 根据config自动启动并注册服务器
	 * 
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public void startAndRegisterServer() throws InterruptedException, ExecutionException {
		if (serverConfig.getRegisters() == null || serverConfig.getRegisters().isEmpty()) {
			return;
		}

		serverForkJoinPool.submit(() -> {
			serverConfig.getRegisters().parallelStream().forEach(registerConfig -> {
				try {
					if (!serverMap.containsKey(registerConfig.getServerAddress())) {
						Closeable server = startServer(registerConfig.getProtocol(), registerConfig.getServerAddress());

						portSet.add(registerConfig.getServerAddress().port);
						serverMap.put(registerConfig.getServerAddress(), server);
					}

					if (registerConfig.getRegister() != null) {
						registerConfig.getRegister().register(//
								serverConfig.getGroup(), //
								serverConfig.getApp(), //
								registerConfig.getProtocol(), //
								registerConfig.getServerAddress(), //
								registerConfig.getServerWeight());
					}

				} catch (Exception e) {
					if (logger.isErrorEnabled()) {
						logger.error("启动失败," + registerConfig);
						return;
					}
				}
			});
		}).get();
	}

	public Closeable startServer(Protocol protocol, HostPort hostPort) throws InterruptedException {

		switch (protocol) {
		case RPC:
			return startRpcServer(hostPort);

		case REST:
			return startRestServer(hostPort);

		default:
			throw new UnsupportedOperationException();
		}
	}

	public NettyRpcServer startRpcServer(HostPort hostPort) throws InterruptedException {
		if (!classIdRegistered && serializer.isSupportedClassId()) {
			classIdRegistered = true;

			Map classIdMap = invokerFactory.getClassIdMap();
			Map, Integer> classIds = new HashMap<>();

			classIdMap.forEach((className, id) -> {
				try {
					classIds.put(Class.forName(className), id);
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			});

			serializer.setClassIds(classIds);

			logger.info("register Serializer.classIds: " + classIdMap);
		}

		NettyRpcServer nettyRpcServer = new NettyRpcServer(eventLoopGroup, invokerFactory, serializer, rpcFilters,
				hostPort);
		nettyRpcServer.start();

		return nettyRpcServer;
	}

	public NettyRestServer startRestServer(HostPort hostPort) throws InterruptedException {
		NettyRestServer nettyRestServer = new NettyRestServer(eventLoopGroup, invokerFactory,
				serverConfig.getJsonMapper(), restFilters, hostPort);
		nettyRestServer.start();
		return nettyRestServer;
	}

	public void waitUntilShutdown() {
		while (!eventLoopGroup.isShutdown() && !eventLoopGroup.isShuttingDown()) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				try {
					close();
				} catch (IOException e1) {
				}

				break;
			}
		}
	}

	/**
	 * 手动注册一个服务
	 * 
	 * @param map
	 */
	public void registerService(Map, Object> map) {
		invokerFactory.register(map);
	}

	private void unRegisterServer() throws InterruptedException, ExecutionException {
		if (serverConfig.getRegisters() == null || serverConfig.getRegisters().isEmpty()) {
			return;
		}

		serverForkJoinPool.submit(() -> {
			serverConfig.getRegisters().parallelStream().forEach(registerConfig -> {
				try {
					if (registerConfig.getRegister() != null) {
						registerConfig.getRegister().unregister(//
								serverConfig.getGroup(), //
								serverConfig.getApp(), //
								registerConfig.getProtocol(), //
								registerConfig.getServerAddress());
					}
				} catch (Exception e) {
					if (logger.isErrorEnabled()) {
						logger.error("注销失败," + registerConfig);
						return;
					}
				}
			});

			serverConfig.getRegisters().parallelStream().forEach(registerConfig -> {
				try {
					if (registerConfig.getRegister() != null) {
						registerConfig.getRegister().close();
					}
				} catch (Exception e) {
					if (logger.isErrorEnabled()) {
						logger.error("关闭失败," + registerConfig);
						return;
					}
				}
			});
		}).get();
	}

	@Override
	public void close() throws IOException {
		if (isClosed) {
			return;
		}

		isClosed = true;

		try {
			unRegisterServer();
		} catch (Exception e) {
			// 不会出错的
		}

		serverMap.forEach((hostPort, server) -> {
			try {
				server.close();

				if (logger.isInfoEnabled()) {
					logger.info("成功关闭服务器: " + server.getClass().getName() + " " + hostPort);
				}
			} catch (Exception e) {
				if (logger.isWarnEnabled()) {
					logger.warn("关闭服务器出错: " + hostPort, e);
				}
			}
		});

		EventLoopGroupHolder.release(eventLoopGroup);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy