手写一个简单的网关-Netty服务端搭建

在开撸之前先介绍一下该项目的一个整体架构,该项目以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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值