Springboot+Netty

目录

一、netty入门

二、启动方式

三、netty服务启动类

四、handler链

五、具体业务

六、 线程或者非spring管理的bean中获取spring管理的bean

七、效果


一、netty入门

                   Netty-导学_哔哩哔哩_bilibili

                   入门视频量比较大,最主要是了解netty的架构

netty官网:

    Netty.docs: User guide for 4.x

对springboot有入门级别会启动项目设置bean基本就可以完成了

maven依赖

    
        org.springframework.boot
        spring-boot-starter-parent
        2.6.7
        
        

        8
        8
        UTF-8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            io.netty
            netty-all
            4.1.95.Final
        
        
            mysql
            mysql-connector-java
        
        
            org.projectlombok
            lombok
            provided
        
        
            com.google.code.gson
            gson
            2.10.1
        
        
            com.baomidou
            mybatis-plus-boot-starter
        
        
            com.baomidou
            mybatis-plus-generator
            3.5.1
        
        
            com.baomidou
            mybatis-plus-extension
            3.5.3.1
        
        
            org.freemarker
            freemarker
            2.3.31
        
        
            commons-io
            commons-io
            2.11.0
        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            com.github.ben-manes.caffeine
            caffeine
        
        
            org.apache.commons
            commons-pool2
        
        
            commons-codec
            commons-codec
            1.15
        
        
            org.apache.commons
            commons-lang3
            3.12.0
        
        
            org.apache.commons
            commons-collections4
            4.4
        
    

二、启动方式

   以web方式启动,tomcat占用80端口    netty占用9002端口

import com.xnetty.config.NettyServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

/**
 * description: 以web的方式进行项目启动
 */
@SpringBootApplication
@Slf4j
public class XNettyApplication {
    public static void main(String[] args) throws Exception {
        ApplicationContext context = SpringApplication.run(XNettyApplication.class, args);
        NettyServer nettyServer = context.getBean(NettyServer.class);
        nettyServer.start();
        log.info("XNettyApplication finish start....");
    }
}

属性配置文件application.properties中配置

server.port=80
netty.server.port=9002

三、netty服务启动类

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

/**
 * description:
 */
@Component
@Slf4j
public class NettyServer {


    public void start() throws Exception {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(8);
        executor.setMaxPoolSize(200);
        executor.setQueueCapacity(10000);
        executor.setKeepAliveSeconds(60);
        executor.setRejectedExecutionHandler((r, executor1) -> {
            try {
                executor1.getQueue().put(r);
                log.info("执行了拒绝策略.....");
            } catch (InterruptedException e) {
                log.error("加入队列异常:{}", e.getMessage());
            }
        });
        executor.setThreadGroupName("netty_request");
        executor.initialize();

        NioEventLoopGroup bossGroup = new NioEventLoopGroup(16);
        NioEventLoopGroup workGroup = new NioEventLoopGroup(16);

        try {
            ChannelFuture channelFuture = new ServerBootstrap().group(bossGroup, workGroup)
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .option(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT)
                    .childHandler(new ServerInit(executor))
                    .bind("0.0.0.0", port)
                    .sync();
            Channel channel = channelFuture.channel();
            channel.closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }
    }

    @Value("${netty.server.port}")
    private int port;

}

四、handler链

import com.xnetty.service.ReadRequestHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * description:
 */
@Service
public class ServerInit extends ChannelInitializer {
    private ThreadPoolTaskExecutor executor;

    public ServerInit(ThreadPoolTaskExecutor executor) {
        this.executor = executor;
    }

    @Override
    protected void initChannel(NioSocketChannel ch) throws Exception {
        ch.pipeline()
                .addLast(new IdleStateHandler(0, 0, 30 * 3, TimeUnit.SECONDS))
                .addLast(new HttpServerCodec())
                .addLast(new HttpObjectAggregator(5 * 1024 * 1024)) //大小为10M
                .addLast(new MpHandler(executor));

    }
}

五、具体业务

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * description:
 */
public class MpHandler extends SimpleChannelInboundHandler {

    ThreadPoolTaskExecutor executor;

    public MpHandler(ThreadPoolTaskExecutor executor) {
        this.executor = executor;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
        String uri = request.uri();
        if (uri.equals("/hello")) {
            executor.execute(()->{
                FullHttpResponse response = new DefaultFullHttpResponse(request.protocolVersion(), HttpResponseStatus.OK, Unpooled.copiedBuffer("hello word", CharsetUtil.UTF_8));   //  Unpooled.wrappedBuffer(responseJson)
                response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json;charset=UTF-8");       // HttpHeaderValues.TEXT_PLAIN.toString()
                response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
                if (HttpUtil.isKeepAlive(request)) {
                    response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
                }
                ctx.writeAndFlush(response);
            });

        } else {
            executor.execute(() -> {
                FullHttpResponse response = new DefaultFullHttpResponse(request.protocolVersion(), HttpResponseStatus.OK, Unpooled.copiedBuffer("请求成功....", CharsetUtil.UTF_8));   //  Unpooled.wrappedBuffer(responseJson)
                response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json;charset=UTF-8");       // HttpHeaderValues.TEXT_PLAIN.toString()
                response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
                if (HttpUtil.isKeepAlive(request)) {
                    response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
                }
                ctx.writeAndFlush(response);
            });

        }
    }
}

六、 线程或者非spring管理的bean中获取spring管理的bean

至于如何在非spring管理的bean中获取spring管理的对象或者在线程中获取spring管理的bean,则自定义一个beanutils获取

如下

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringBeanUtils implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static Object getBean(String name) {
        return context.getBean(name);
    }

    public static  T getBean(Class clazz) {
        return context.getBean(clazz);
    }

    public static  T getBeanByName(String beanName, Class clazz) {
        return context.getBean(beanName, clazz);
    }


}

七、效果

七http://localhost:9002/hello

Springboot+Netty_第1张图片

你可能感兴趣的:(spring,boot,java,后端)