This commit is contained in:
parent
9e966decb8
commit
251a21ef97
@ -1,5 +1,11 @@
|
|||||||
# did
|
# did
|
||||||
|
|
||||||
|
[![license](https://badgen.net/badge/license/MIT/blue)](./LICENSE)
|
||||||
|
[![](https://badgen.net/github/commits/ehlxr/did)](https://github.com/ehlxr/did/commits/)
|
||||||
|
[![](https://badgen.net/github/last-commit/ehlxr/did)]((https://github.com/ehlxr/did/commits/))
|
||||||
|
[![](https://badgen.net/github/releases/ehlxr/did)](https://github.com/ehlxr/did/releases)
|
||||||
|
[![Build Status](https://ci.ehlxr.me/api/badges/ehlxr/did/status.svg)](https://ci.ehlxr.me/ehlxr/did)
|
||||||
|
|
||||||
基于 SnowFlake 算法实现的分布式 ID 生成服务
|
基于 SnowFlake 算法实现的分布式 ID 生成服务
|
||||||
|
|
||||||
## did-server
|
## did-server
|
||||||
|
@ -29,16 +29,14 @@ public class ServerStarter {
|
|||||||
machineId = "".equals(Constants.getEnv("MACHINES_ID")) ? machineId : Long.parseLong(Constants.getEnv("MACHINES_ID"));
|
machineId = "".equals(Constants.getEnv("MACHINES_ID")) ? machineId : Long.parseLong(Constants.getEnv("MACHINES_ID"));
|
||||||
logger.info("SnowFlake datacenterId is: {}, machineId is: {}", datacenterId, machineId);
|
logger.info("SnowFlake datacenterId is: {}, machineId is: {}", datacenterId, machineId);
|
||||||
|
|
||||||
final SnowFlake snowFlake = new SnowFlake(datacenterId, machineId);
|
final SnowFlake snowFlake = SnowFlake.newBuilder().datacenterId(datacenterId).machineId(machineId).build();
|
||||||
|
|
||||||
// 启动 Http 服务器
|
// 启动 Http 服务器
|
||||||
final HttpServer httpServer = new HttpServer(snowFlake);
|
final Server httpServer = HttpServer.newBuilder().snowFlake(snowFlake).build();
|
||||||
httpServer.init();
|
|
||||||
httpServer.start();
|
httpServer.start();
|
||||||
|
|
||||||
// 启动 Sdk 服务器
|
// 启动 Sdk 服务器
|
||||||
final SdkServer sdkServer = new SdkServer(snowFlake);
|
final Server sdkServer = SdkServer.newBuilder().snowFlake(snowFlake).build();
|
||||||
sdkServer.init();
|
|
||||||
sdkServer.start();
|
sdkServer.start();
|
||||||
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(() ->
|
Runtime.getRuntime().addShutdownHook(new Thread(() ->
|
||||||
|
@ -139,4 +139,30 @@ public class SnowFlake {
|
|||||||
long end = System.currentTimeMillis();
|
long end = System.currentTimeMillis();
|
||||||
System.out.println(end - start);
|
System.out.println(end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SnowFlakeBuilder newBuilder() {
|
||||||
|
return new SnowFlakeBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class SnowFlakeBuilder {
|
||||||
|
private long datacenterId;
|
||||||
|
private long machineId;
|
||||||
|
|
||||||
|
private SnowFlakeBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SnowFlakeBuilder datacenterId(long datacenterId) {
|
||||||
|
this.datacenterId = datacenterId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SnowFlakeBuilder machineId(long machineId) {
|
||||||
|
this.machineId = machineId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SnowFlake build() {
|
||||||
|
return new SnowFlake(datacenterId, machineId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,10 @@ package io.github.ehlxr.did.server;
|
|||||||
import io.github.ehlxr.did.core.SnowFlake;
|
import io.github.ehlxr.did.core.SnowFlake;
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.DefaultEventLoopGroup;
|
import io.netty.channel.DefaultEventLoopGroup;
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -22,10 +24,9 @@ public abstract class BaseServer implements Server {
|
|||||||
protected NioEventLoopGroup workGroup;
|
protected NioEventLoopGroup workGroup;
|
||||||
protected ChannelFuture channelFuture;
|
protected ChannelFuture channelFuture;
|
||||||
protected ServerBootstrap serverBootstrap;
|
protected ServerBootstrap serverBootstrap;
|
||||||
protected int port;
|
|
||||||
protected SnowFlake snowFlake;
|
protected SnowFlake snowFlake;
|
||||||
|
|
||||||
public void init() {
|
protected void init() {
|
||||||
defLoopGroup = new DefaultEventLoopGroup(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
|
defLoopGroup = new DefaultEventLoopGroup(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
|
||||||
private final AtomicInteger index = new AtomicInteger(0);
|
private final AtomicInteger index = new AtomicInteger(0);
|
||||||
|
|
||||||
@ -52,6 +53,13 @@ public abstract class BaseServer implements Server {
|
|||||||
});
|
});
|
||||||
|
|
||||||
serverBootstrap = new ServerBootstrap();
|
serverBootstrap = new ServerBootstrap();
|
||||||
|
|
||||||
|
serverBootstrap.group(bossGroup, workGroup)
|
||||||
|
.channel(NioServerSocketChannel.class)
|
||||||
|
// .option(ChannelOption.SO_KEEPALIVE, true)
|
||||||
|
// .option(ChannelOption.TCP_NODELAY, true)
|
||||||
|
// .localAddress(new InetSocketAddress(port))
|
||||||
|
.option(ChannelOption.SO_BACKLOG, 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4,15 +4,15 @@ import io.github.ehlxr.did.common.Constants;
|
|||||||
import io.github.ehlxr.did.core.SnowFlake;
|
import io.github.ehlxr.did.core.SnowFlake;
|
||||||
import io.github.ehlxr.did.server.BaseServer;
|
import io.github.ehlxr.did.server.BaseServer;
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.channel.ChannelOption;
|
|
||||||
import io.netty.channel.socket.SocketChannel;
|
import io.netty.channel.socket.SocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|
||||||
import io.netty.handler.codec.http.HttpObjectAggregator;
|
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||||
import io.netty.handler.codec.http.HttpRequestDecoder;
|
import io.netty.handler.codec.http.HttpRequestDecoder;
|
||||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Http 服务器,使用 Netty 中的 Http 协议栈,
|
* Http 服务器,使用 Netty 中的 Http 协议栈,
|
||||||
*
|
*
|
||||||
@ -20,50 +20,23 @@ import org.slf4j.LoggerFactory;
|
|||||||
*/
|
*/
|
||||||
public class HttpServer extends BaseServer {
|
public class HttpServer extends BaseServer {
|
||||||
protected Logger logger = LoggerFactory.getLogger(HttpServer.class);
|
protected Logger logger = LoggerFactory.getLogger(HttpServer.class);
|
||||||
|
private int port = "".equals(Constants.getEnv("HTTP_PORT")) ? Constants.HTTP_PORT : Integer.parseInt(Constants.getEnv("HTTP_PORT"));
|
||||||
|
|
||||||
public HttpServer(SnowFlake snowFlake, int port) {
|
public HttpServer(SnowFlake snowFlake, int port) {
|
||||||
|
Objects.requireNonNull(snowFlake, "snowflake instance not allow null");
|
||||||
|
|
||||||
this.snowFlake = snowFlake;
|
this.snowFlake = snowFlake;
|
||||||
this.port = port;
|
this.port = port == 0 ? this.port : port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpServer(SnowFlake snowFlake) {
|
public HttpServer(SnowFlake snowFlake) {
|
||||||
this.snowFlake = snowFlake;
|
this(snowFlake, 0);
|
||||||
this.port = "".equals(Constants.getEnv("HTTP_PORT")) ?
|
|
||||||
Constants.HTTP_PORT :
|
|
||||||
Integer.parseInt(Constants.getEnv("HTTP_PORT"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static HttpServerBuilder newBuilder() {
|
||||||
public void init() {
|
return new HttpServerBuilder();
|
||||||
super.init();
|
|
||||||
serverBootstrap.group(bossGroup, workGroup)
|
|
||||||
.channel(NioServerSocketChannel.class)
|
|
||||||
// .option(ChannelOption.SO_KEEPALIVE, false)
|
|
||||||
// .option(ChannelOption.TCP_NODELAY, true)
|
|
||||||
.option(ChannelOption.SO_BACKLOG, 1024)
|
|
||||||
// .localAddress(new InetSocketAddress(port))
|
|
||||||
.childHandler(new ChannelInitializer<SocketChannel>() {
|
|
||||||
@Override
|
|
||||||
protected void initChannel(SocketChannel ch) {
|
|
||||||
ch.pipeline().addLast(defLoopGroup,
|
|
||||||
new HttpRequestDecoder(),
|
|
||||||
new HttpObjectAggregator(65536),
|
|
||||||
new HttpResponseEncoder(),
|
|
||||||
new HttpServerHandler(snowFlake)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start() {
|
|
||||||
try {
|
|
||||||
channelFuture = serverBootstrap.bind(port).sync();
|
|
||||||
logger.info("HttpServer start success, port is:{}", port);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("HttpServer start fail,", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
@ -71,4 +44,54 @@ public class HttpServer extends BaseServer {
|
|||||||
super.shutdown();
|
super.shutdown();
|
||||||
logger.info("HttpServer shutdown finish!");
|
logger.info("HttpServer shutdown finish!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
|
||||||
|
serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(SocketChannel ch) {
|
||||||
|
ch.pipeline().addLast(defLoopGroup,
|
||||||
|
new HttpRequestDecoder(),
|
||||||
|
new HttpObjectAggregator(65536),
|
||||||
|
new HttpResponseEncoder(),
|
||||||
|
new HttpServerHandler(snowFlake)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
channelFuture = serverBootstrap.bind(port).sync();
|
||||||
|
logger.info("HttpServer start success, port is:{}", port);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error("HttpServer start fail,", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class HttpServerBuilder {
|
||||||
|
protected SnowFlake snowFlake;
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
private HttpServerBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HttpServerBuilder aHttpServer() {
|
||||||
|
return new HttpServerBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpServerBuilder snowFlake(SnowFlake snowFlake) {
|
||||||
|
this.snowFlake = snowFlake;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpServerBuilder port(int port) {
|
||||||
|
this.port = port;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpServer build() {
|
||||||
|
return new HttpServer(snowFlake, port);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,7 @@ public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpReque
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
|
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
|
||||||
String uri = getUriNoSprit(request);
|
|
||||||
logger.info("request uri is: {}", uri);
|
|
||||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
|
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
|
||||||
// if (Constants.HTTP_REQUEST.equals(uri)) {
|
|
||||||
if (semaphore.tryAcquire(Constants.ACQUIRE_TIMEOUTMILLIS, TimeUnit.MILLISECONDS)) {
|
if (semaphore.tryAcquire(Constants.ACQUIRE_TIMEOUTMILLIS, TimeUnit.MILLISECONDS)) {
|
||||||
try {
|
try {
|
||||||
long id = snowFlake.nextId();
|
long id = snowFlake.nextId();
|
||||||
@ -50,9 +47,6 @@ public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpReque
|
|||||||
logger.warn(info);
|
logger.warn(info);
|
||||||
throw new Exception(info);
|
throw new Exception(info);
|
||||||
}
|
}
|
||||||
// } else {
|
|
||||||
// response.content().writeBytes(("Unsupported uri: " + uri).getBytes());
|
|
||||||
// }
|
|
||||||
|
|
||||||
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
|
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
|
||||||
}
|
}
|
||||||
@ -63,13 +57,4 @@ public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpReque
|
|||||||
logger.error("HttpServerHandler channel [{}] error and will be closed", NettyUtil.parseRemoteAddr(channel), cause);
|
logger.error("HttpServerHandler channel [{}] error and will be closed", NettyUtil.parseRemoteAddr(channel), cause);
|
||||||
NettyUtil.closeChannel(channel);
|
NettyUtil.closeChannel(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String getUriNoSprit(FullHttpRequest request) {
|
|
||||||
String uri = request.uri();
|
|
||||||
if (uri.startsWith("/")) {
|
|
||||||
uri = uri.substring(1);
|
|
||||||
}
|
|
||||||
return uri;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,59 +4,32 @@ import io.github.ehlxr.did.common.Constants;
|
|||||||
import io.github.ehlxr.did.core.SnowFlake;
|
import io.github.ehlxr.did.core.SnowFlake;
|
||||||
import io.github.ehlxr.did.server.BaseServer;
|
import io.github.ehlxr.did.server.BaseServer;
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.channel.ChannelOption;
|
|
||||||
import io.netty.channel.socket.SocketChannel;
|
import io.netty.channel.socket.SocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ehlxr
|
* @author ehlxr
|
||||||
*/
|
*/
|
||||||
public class SdkServer extends BaseServer {
|
public class SdkServer extends BaseServer {
|
||||||
protected Logger logger = LoggerFactory.getLogger(SdkServer.class);
|
protected Logger logger = LoggerFactory.getLogger(SdkServer.class);
|
||||||
|
private int port = "".equals(Constants.getEnv("SDK_PORT")) ? Constants.HTTP_PORT : Integer.parseInt(Constants.getEnv("SDK_PORT"));
|
||||||
|
|
||||||
public SdkServer(SnowFlake snowFlake) {
|
public SdkServer(SnowFlake snowFlake) {
|
||||||
this.snowFlake = snowFlake;
|
this(snowFlake, 0);
|
||||||
this.port = "".equals(Constants.getEnv("SDK_PORT")) ?
|
|
||||||
Constants.SDK_PORT :
|
|
||||||
Integer.parseInt(Constants.getEnv("SDK_PORT"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SdkServer(SnowFlake snowFlake, int port) {
|
public SdkServer(SnowFlake snowFlake, int port) {
|
||||||
|
Objects.requireNonNull(snowFlake, "snowflake instance not allow null");
|
||||||
|
|
||||||
this.snowFlake = snowFlake;
|
this.snowFlake = snowFlake;
|
||||||
this.port = port;
|
this.port = port == 0 ? this.port : port;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static SdkServerBuilder newBuilder() {
|
||||||
public void init() {
|
return new SdkServerBuilder();
|
||||||
super.init();
|
|
||||||
serverBootstrap.group(bossGroup, workGroup)
|
|
||||||
.channel(NioServerSocketChannel.class)
|
|
||||||
// .option(ChannelOption.SO_KEEPALIVE, true)
|
|
||||||
// .option(ChannelOption.TCP_NODELAY, true)
|
|
||||||
.option(ChannelOption.SO_BACKLOG, 1024)
|
|
||||||
// .localAddress(new InetSocketAddress(port))
|
|
||||||
.childHandler(new ChannelInitializer<SocketChannel>() {
|
|
||||||
@Override
|
|
||||||
protected void initChannel(SocketChannel ch) {
|
|
||||||
ch.pipeline().addLast(defLoopGroup,
|
|
||||||
new SdkServerDecoder(12),
|
|
||||||
new SdkServerEncoder(),
|
|
||||||
new SdkServerHandler(snowFlake)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start() {
|
|
||||||
try {
|
|
||||||
channelFuture = serverBootstrap.bind(port).sync();
|
|
||||||
logger.info("SdkServer start success, port is:{}", port);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("SdkServer start fail,", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -65,4 +38,49 @@ public class SdkServer extends BaseServer {
|
|||||||
super.shutdown();
|
super.shutdown();
|
||||||
logger.info("SdkServer shutdown finish!");
|
logger.info("SdkServer shutdown finish!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
|
||||||
|
serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(SocketChannel ch) {
|
||||||
|
ch.pipeline().addLast(defLoopGroup,
|
||||||
|
new SdkServerDecoder(12),
|
||||||
|
new SdkServerEncoder(),
|
||||||
|
new SdkServerHandler(snowFlake)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
channelFuture = serverBootstrap.bind(port).sync();
|
||||||
|
logger.info("SdkServer start success, port is:{}", port);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error("SdkServer start fail,", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class SdkServerBuilder {
|
||||||
|
protected SnowFlake snowFlake;
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
private SdkServerBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SdkServerBuilder snowFlake(SnowFlake snowFlake) {
|
||||||
|
this.snowFlake = snowFlake;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SdkServerBuilder port(int port) {
|
||||||
|
this.port = port;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SdkServer build() {
|
||||||
|
return new SdkServer(snowFlake, port);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user