在开撸之前先介绍一下该项目的一个整体架构,该项目以netty作为服务端接收请求,对请求通过一步步的过滤处理最后调用后端真实服务。参考美团的Shepherd架构。该网关主要实现的功能鉴权、限流、防刷、自定义请求路由、灰度发布和配置热更新。
在处理http请求方面选用netty框架,netty是一款高性能网络框架,基于零拷贝技术和高效的池化技术比如可以有woker线程处理任务,boss线程处理连接等等,同时参考美团的网关框架Sherdperd和springclod阿里巴巴gateway在处理hhtp请求是采用的就是netty。
首先第一步,搭建一个netty服务端。
初始化一个maven项目并导入netty依赖

写一个nettyStart
package server;
import handler.NettyServerHandlerInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NettyStarter {
private EventLoopGroup workerGroup=new NioEventLoopGroup();
private EventLoopGroup bossGroup=new NioEventLoopGroup();
private Channel channel;
private static final Logger logger = LoggerFactory.getLogger(NettyStarter.class);
public void start(int port) throws InterruptedException {
ServerBootstrap serverBootstrap=new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.localAddress(port)
.option(ChannelOption.SO_BACKLOG, 1024) // 服务端 accept 队列的大小
.childOption(ChannelOption.SO_KEEPALIVE, true) // TCP Keepalive 机制,实现 TCP 层级的心跳保活功能
.childOption(ChannelOption.TCP_NODELAY, true)// 允许较小的数据包的发送,降低延迟
.childHandler(new NettyServerHandlerInitializer());
ChannelFuture future = serverBootstrap.bind().sync();
if(future.isSuccess()){
channel= future.channel();
logger.info("server start success 端口:"+port);
channel.closeFuture().sync();
}
}
}
package handler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.timeout.ReadTimeoutHandler;
import java.util.concurrent.TimeUnit;
// Netty 服务器端 Handler 初始化类
public class NettyServerHandlerInitializer extends ChannelInitializer<Channel> {
// 设置连接读取超时时间,单位为秒
private Integer READTIME_OUT = 60 * 3; // 设置为3分钟
@Override
protected void initChannel(Channel channel) throws Exception {
// 初始化 Channel 的管道(Pipeline)
channel.pipeline()
// 添加一个超时处理器,用于检测连接的空闲时间,如果在设定的时间内没有接收到数据,则会触发超时事件
.addLast(new ReadTimeoutHandler(READTIME_OUT, TimeUnit.SECONDS)) // 设置空闲超时时间为 3 分钟
// 添加 HTTP 编解码器(HttpServerCodec),用于处理 HTTP 请求和响应的编解码
.addLast(new HttpServerCodec())
// 添加 HTTP 消息聚合器(HttpObjectAggregator),将多个 HTTP 消息合并为一个完整的 HTTP 请求或响应
.addLast(new HttpObjectAggregator(1024 * 1024)) // 设置消息的最大长度为 1MB
// 添加自定义请求处理器(HttpRequestHandler),用于处理 HTTP 请求的业务逻辑
.addLast(new HttpRequestHandler())
// 添加异常处理器(ExceptionHandler),用于捕获并处理管道中的异常
.addLast(new ExceptionHandler());
}
}
异常处理器
package handler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ExceptionHandler extends ChannelInboundHandlerAdapter {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
// 处理异常
System.err.println("Exception caught: " + cause.getMessage());
ctx.close(); // 关闭连接
}
}
HttpRequestHandler主要用于接收请求并对请求进行过滤,后面会进行实现。好了netty服务端初始化完成,下一步实现过滤器。
项目github地址GitHub - Minerva04/EasyGateway
772

被折叠的 条评论
为什么被折叠?



