mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-10-13 08:16:04 +00:00
perf[orm]: 优化FileChannelHeap
This commit is contained in:
1 parent
bad0a3f88c
commit
939a43ff91
11 files changed
+177
-30
No files matched your search
@@ -14,9 +14,9 @@
|
||||
package com.zfoo.net.core.http;
|
||||
|
||||
import com.zfoo.net.core.AbstractServer;
|
||||
import com.zfoo.net.handler.ServerDispatcherHandler;
|
||||
import com.zfoo.net.handler.HttpDispatcherHandler;
|
||||
import com.zfoo.net.handler.codec.http.HttpCodecHandler;
|
||||
import com.zfoo.protocol.IPacket;
|
||||
import com.zfoo.net.packet.model.DecodedPacketInfo;
|
||||
import com.zfoo.util.net.HostAndPort;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
@@ -36,9 +36,9 @@ public class HttpServer extends AbstractServer {
|
||||
/**
|
||||
* http的地址解析器
|
||||
*/
|
||||
private Function<FullHttpRequest, IPacket> uriResolver;
|
||||
private Function<FullHttpRequest, DecodedPacketInfo> uriResolver;
|
||||
|
||||
public HttpServer(HostAndPort host, Function<FullHttpRequest, IPacket> uriResolver) {
|
||||
public HttpServer(HostAndPort host, Function<FullHttpRequest, DecodedPacketInfo> uriResolver) {
|
||||
super(host);
|
||||
this.uriResolver = uriResolver;
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class HttpServer extends AbstractServer {
|
||||
channel.pipeline().addLast(new ChunkedWriteHandler());
|
||||
channel.pipeline().addLast(new HttpObjectAggregator(64 * 1024));
|
||||
channel.pipeline().addLast(new HttpCodecHandler(uriResolver));
|
||||
channel.pipeline().addLast(new ServerDispatcherHandler());
|
||||
channel.pipeline().addLast(new HttpDispatcherHandler());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.net.handler;
|
||||
|
||||
import com.zfoo.net.NetContext;
|
||||
import com.zfoo.net.packet.model.DecodedPacketInfo;
|
||||
import com.zfoo.net.packet.model.HttpPacketAttachment;
|
||||
import com.zfoo.net.util.SessionUtils;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
@ChannelHandler.Sharable
|
||||
public class HttpDispatcherHandler extends ServerDispatcherHandler {
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
var session = SessionUtils.getSession(ctx);
|
||||
if (session == null) {
|
||||
return;
|
||||
}
|
||||
DecodedPacketInfo decodedPacketInfo = (DecodedPacketInfo) msg;
|
||||
|
||||
var httpPacketAttachment = (HttpPacketAttachment) decodedPacketInfo.getPacketAttachment();
|
||||
if (httpPacketAttachment.getUid() <= 0) {
|
||||
httpPacketAttachment.useExecutorConsistentHash(session.getSid());
|
||||
}
|
||||
|
||||
NetContext.getDispatcher().receive(session, decodedPacketInfo.getPacket(), decodedPacketInfo.getPacketAttachment());
|
||||
}
|
||||
}
|
||||
@@ -23,13 +23,15 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageCodec;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpHeaderValues;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
@@ -38,9 +40,9 @@ public class HttpCodecHandler extends MessageToMessageCodec<FullHttpRequest, Enc
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(HttpCodecHandler.class);
|
||||
|
||||
private Function<FullHttpRequest, IPacket> uriResolver;
|
||||
private Function<FullHttpRequest, DecodedPacketInfo> uriResolver;
|
||||
|
||||
public HttpCodecHandler(Function<FullHttpRequest, IPacket> uriResolver) {
|
||||
public HttpCodecHandler(Function<FullHttpRequest, DecodedPacketInfo> uriResolver) {
|
||||
super();
|
||||
this.uriResolver = uriResolver;
|
||||
}
|
||||
@@ -48,9 +50,7 @@ public class HttpCodecHandler extends MessageToMessageCodec<FullHttpRequest, Enc
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest, List<Object> list) {
|
||||
try {
|
||||
var packet = uriResolver.apply(fullHttpRequest);
|
||||
var attachment = HttpPacketAttachment.valueOf(fullHttpRequest, HttpResponseStatus.OK);
|
||||
var decodedPacketInfo = DecodedPacketInfo.valueOf(packet, attachment);
|
||||
var decodedPacketInfo = uriResolver.apply(fullHttpRequest);
|
||||
list.add(decodedPacketInfo);
|
||||
} catch (Exception e) {
|
||||
logger.error("exception异常", e);
|
||||
@@ -63,7 +63,6 @@ public class HttpCodecHandler extends MessageToMessageCodec<FullHttpRequest, Enc
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext channelHandlerContext, EncodedPacketInfo out, List<Object> list) {
|
||||
|
||||
try {
|
||||
var packet = (IPacket) out.getPacket();
|
||||
var attachment = (HttpPacketAttachment) out.getPacketAttachment();
|
||||
@@ -71,13 +70,31 @@ public class HttpCodecHandler extends MessageToMessageCodec<FullHttpRequest, Enc
|
||||
var protocolVersion = attachment.getFullHttpRequest().protocolVersion();
|
||||
var httpResponseStatus = attachment.getHttpResponseStatus();
|
||||
if (packet.protocolId() == Message.PROTOCOL_ID) {
|
||||
var fullHttpResponse = new DefaultFullHttpResponse(protocolVersion, httpResponseStatus);
|
||||
list.add(fullHttpResponse);
|
||||
var message = (Message) packet;
|
||||
if (StringUtils.isEmpty(message.getMessage())) {
|
||||
var fullHttpResponse = new DefaultFullHttpResponse(protocolVersion, httpResponseStatus);
|
||||
fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN);
|
||||
fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, 0);
|
||||
list.add(fullHttpResponse);
|
||||
} else {
|
||||
var byteBuf = channelHandlerContext.alloc().ioBuffer();
|
||||
byteBuf.writeCharSequence(message.getMessage(), StringUtils.DEFAULT_CHARSET);
|
||||
var fullHttpResponse = new DefaultFullHttpResponse(protocolVersion, httpResponseStatus, byteBuf);
|
||||
|
||||
fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN);
|
||||
fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, byteBuf.readableBytes());
|
||||
|
||||
list.add(fullHttpResponse);
|
||||
}
|
||||
} else {
|
||||
var byteBuf = channelHandlerContext.alloc().ioBuffer();
|
||||
var jsonStr = JsonUtils.object2StringTurbo(packet);
|
||||
var jsonStr = JsonUtils.object2String(packet);
|
||||
byteBuf.writeBytes(StringUtils.bytes(jsonStr));
|
||||
var fullHttpResponse = new DefaultFullHttpResponse(protocolVersion, httpResponseStatus, byteBuf);
|
||||
|
||||
fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON);
|
||||
fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, byteBuf.readableBytes());
|
||||
|
||||
list.add(fullHttpResponse);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -49,6 +49,12 @@ public class Message implements IPacket {
|
||||
return Message.valueOf(packet, code, null);
|
||||
}
|
||||
|
||||
public static Message valueOf(String message) {
|
||||
var mess = new Message();
|
||||
mess.message = message;
|
||||
return mess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short protocolId() {
|
||||
return PROTOCOL_ID;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
package com.zfoo.net.packet.model;
|
||||
|
||||
import com.zfoo.util.math.RandomUtils;
|
||||
import com.zfoo.util.math.HashUtils;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
@@ -25,6 +25,12 @@ public class HttpPacketAttachment implements IPacketAttachment {
|
||||
|
||||
public static final transient short PROTOCOL_ID = 3;
|
||||
|
||||
private long uid;
|
||||
|
||||
private boolean useExecutorConsistentHash;
|
||||
|
||||
private int executorConsistentHash;
|
||||
|
||||
private transient FullHttpRequest fullHttpRequest;
|
||||
|
||||
private transient HttpResponseStatus httpResponseStatus;
|
||||
@@ -43,7 +49,11 @@ public class HttpPacketAttachment implements IPacketAttachment {
|
||||
|
||||
@Override
|
||||
public int executorConsistentHash() {
|
||||
return RandomUtils.randomInt();
|
||||
if (useExecutorConsistentHash) {
|
||||
return executorConsistentHash;
|
||||
} else {
|
||||
return HashUtils.fnvHash(uid);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,6 +61,35 @@ public class HttpPacketAttachment implements IPacketAttachment {
|
||||
return PROTOCOL_ID;
|
||||
}
|
||||
|
||||
public void useExecutorConsistentHash(Object argument) {
|
||||
this.useExecutorConsistentHash = true;
|
||||
this.executorConsistentHash = HashUtils.fnvHash(argument);
|
||||
}
|
||||
|
||||
public long getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setUid(long uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public boolean isUseExecutorConsistentHash() {
|
||||
return useExecutorConsistentHash;
|
||||
}
|
||||
|
||||
public void setUseExecutorConsistentHash(boolean useExecutorConsistentHash) {
|
||||
this.useExecutorConsistentHash = useExecutorConsistentHash;
|
||||
}
|
||||
|
||||
public int getExecutorConsistentHash() {
|
||||
return executorConsistentHash;
|
||||
}
|
||||
|
||||
public void setExecutorConsistentHash(int executorConsistentHash) {
|
||||
this.executorConsistentHash = executorConsistentHash;
|
||||
}
|
||||
|
||||
public FullHttpRequest getFullHttpRequest() {
|
||||
return fullHttpRequest;
|
||||
}
|
||||
|
||||
@@ -52,4 +52,9 @@ public class ConcurrentHeapMap<V extends IPacket> implements LpMap<V> {
|
||||
checkKey(key);
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxIndex() {
|
||||
return maxIndexAtomic.get();
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ package com.zfoo.orm.lpmap;
|
||||
|
||||
import com.zfoo.protocol.IPacket;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
@@ -55,6 +57,11 @@ public class FileChannelHeapMap<V extends IPacket> implements LpMap<V> {
|
||||
return heapMap.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxIndex() {
|
||||
return heapMap.getMaxIndex();
|
||||
}
|
||||
|
||||
private void load() {
|
||||
var maxIndex = fileChannelMap.getMaxIndex();
|
||||
if (maxIndex <= 0) {
|
||||
@@ -68,7 +75,10 @@ public class FileChannelHeapMap<V extends IPacket> implements LpMap<V> {
|
||||
}
|
||||
heapMap.put(key, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<Long, V> biConsumer) {
|
||||
heapMap.forEach(biConsumer);
|
||||
}
|
||||
}
|
||||
@@ -145,6 +145,19 @@ public class FileChannelMap<V extends IPacket> implements LpMap<V>, Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxIndex() {
|
||||
try {
|
||||
clearByteBuf();
|
||||
indexBuffer.writeBytes(indexFileChannel, 0, 8);
|
||||
return indexBuffer.readLong();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
clearByteBuf();
|
||||
}
|
||||
}
|
||||
|
||||
protected void setKeyValue(long key, V value) {
|
||||
try {
|
||||
clearByteBuf();
|
||||
@@ -194,18 +207,6 @@ public class FileChannelMap<V extends IPacket> implements LpMap<V>, Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
protected long getMaxIndex() {
|
||||
try {
|
||||
clearByteBuf();
|
||||
indexBuffer.writeBytes(indexFileChannel, 0, 8);
|
||||
return indexBuffer.readLong();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
clearByteBuf();
|
||||
}
|
||||
}
|
||||
|
||||
protected void clearByteBuf() {
|
||||
indexBuffer.clear();
|
||||
dbBuffer.clear();
|
||||
|
||||
@@ -77,6 +77,11 @@ public class FileHeapMap<V extends IPacket> implements LpMap<V> {
|
||||
return heapMap.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxIndex() {
|
||||
return heapMap.getMaxIndex();
|
||||
}
|
||||
|
||||
private void load() {
|
||||
FileInputStream fileInputStream = null;
|
||||
FileChannel fileChannel = null;
|
||||
|
||||
@@ -17,6 +17,7 @@ import io.netty.util.collection.LongObjectHashMap;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
@@ -81,4 +82,14 @@ public class HeapMap<V extends IPacket> implements LpMap<V> {
|
||||
checkKey(key);
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxIndex() {
|
||||
return maxIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<Long, V> biConsumer) {
|
||||
map.forEach(biConsumer);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ package com.zfoo.orm.lpmap;
|
||||
import com.zfoo.protocol.IPacket;
|
||||
import com.zfoo.protocol.exception.RunException;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* 类型固定的map,key为long,value为IPacket
|
||||
* 其中long必须大于0,value可以为null
|
||||
@@ -41,10 +43,16 @@ public interface LpMap<V extends IPacket> {
|
||||
|
||||
V get(long key);
|
||||
|
||||
long getMaxIndex();
|
||||
|
||||
default void checkKey(long key) {
|
||||
if (key <= 0) {
|
||||
throw new RunException("key[{}]不能为负数", key);
|
||||
}
|
||||
}
|
||||
|
||||
default void forEach(BiConsumer<Long, V> biConsumer) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user