• 关于netty


    关于netty

    netty 是一个非阻塞IO框架,用于Java网络应用开发,特点是异步处理,并发处理能力,netty里面包含有reactor框架的实现,是一个非常高级的框架体系。

    netty特性

    netty 处理快,更少的资源需求,响应快,可以作为高并发场景服务器的一个选择

    reactor 个人理解是 react:响应式, or :对象,就是响应式框架,netty 就是运用reactor 的核心设计思想编写的高性能高并发网络请求处理器框架。

    以下来自维基百科,自由的百科全书

    跳到导航跳到搜索

    注意:本条目主题可能尚无中文译名,因而使用原文或其拉丁字母转写作为标题。如果您在可靠来源中找到本主题的中文名称,请勇于将其移动至中文标题。(2019年2月)

    JBoss-Netty-logo.png
    开发者 Netty项目社区
    稳定版本 4.1.31.Final[1](2018年10月30日,2年前)
    预览版本 5.0.0.Alpha3(2016年1月14日,5年前)
    源代码库 github.com/netty/netty编辑维基数据链接
    编程语言 Java
    类型 Enterprise Integration Patterns Message Oriented Middleware
    许可协议 Apache许可证 2.0
    网站 netty.io 编辑维基数据

    Netty是一个非阻塞I/O客户端-服务器框架,主要用于开发Java网络应用程序,如协议服务器和客户端。异步事件驱动的网络应用程序框架和工具用于简化网络编程,例如TCPUDP套接字服务器。[2]Netty包括了反应器编程模式的实现。Netty最初由JBoss开发,现在由Netty项目社区开发和维护。

    除了作为异步网络应用程序框架,Netty还包括了对HTTPHTTP2DNS及其他协议的支持,涵盖了在Servlet容器内运行的能力、对WebSockets的支持、与Google Protocol Buffers的集成、对SSL/TLS的支持以及对用于SPDY协议和消息压缩的支持。自2004年以来,Netty一直在被积极开发。[3]

    从版本4.0.0开始,Netty在支持NIO和阻塞Java套接字的同时,还支持使用NIO.2作为后端。

    用netty写一个简单非阻塞请求响应服务器

    简单示意代码

    服务端

    服务器 HttpServer

    package net.narule.jnetty.httpdemo;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.EventLoopGroup;
    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 java.net.InetSocketAddress;
    
    /**
     * netty server
     */
    public class HttpServer {
    
        int port ;
    
        public HttpServer(int port){
            this.port = port;
        }
    
        public void start() throws Exception{
            ServerBootstrap bootstrap = new ServerBootstrap();
            // 事件监听相关对象配置 netty 循环监听是否有新事件
            // 如果有 马上将事件交给处理器,处理器层层循环处理,会循环到自定义消息解析器  HttpRequestHandler
            EventLoopGroup boss = new NioEventLoopGroup();
            EventLoopGroup work = new NioEventLoopGroup();
            bootstrap.group(boss,work)
                    .handler(new LoggingHandler(LogLevel.DEBUG))
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new HttpServerInitializer());
    
            ChannelFuture f = bootstrap.bind(new InetSocketAddress(port)).sync();
            System.out.println("server start... port : " + port);
            f.channel().closeFuture().sync();
    
        }
    
    }
    

    请求处理器初始化 HttpServerInitializer

    initChannel 处理器配置。可以配置多个

    package net.narule.jnetty.httpdemo;
    
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelPipeline;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.handler.codec.http.HttpObjectAggregator;
    import io.netty.handler.codec.http.HttpServerCodec;
    
    public class HttpServerInitializer extends ChannelInitializer<SocketChannel> {
    
    	@Override
    	protected void initChannel(SocketChannel ch) throws Exception {
    		ChannelPipeline pipeline = ch.pipeline();
    		// http 编解码
            pipeline.addLast(new HttpServerCodec());
            // http 消息聚合器                                                                     512*1024为接收的最大contentlength
            pipeline.addLast("httpAggregator",new HttpObjectAggregator(512*1024)); 
            // 请求处理器
            pipeline.addLast(new HttpRequestHandler());
    		
    	}
    }
    

    消息处理器 HttpRequestHandler

    重写channelRead0 方法处理请求的消息并返回

    package net.narule.jnetty.httpdemo;
    
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelFutureListener;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.handler.codec.http.DefaultFullHttpResponse;
    import io.netty.handler.codec.http.FullHttpRequest;
    import io.netty.handler.codec.http.FullHttpResponse;
    import io.netty.handler.codec.http.HttpHeaderNames;
    import io.netty.handler.codec.http.HttpResponseStatus;
    import io.netty.handler.codec.http.HttpVersion;
    import io.netty.util.CharsetUtil;
    
    public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    
    	    @Override
    	    public void channelReadComplete(ChannelHandlerContext ctx) {
    	        ctx.flush();
    	    }
    
    	    @Override
    	    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
    			// 处理数据
    	    	Date date = new Date(System.currentTimeMillis());
    	        String uri = req.uri();
    	        Map<String,String> data = new HashMap<>();
    	        String protocal = req.protocolVersion().text(); //获取HTTP协议版本
    	        String content = req.content().toString(CharsetUtil.UTF_8); //获取HTTP协议版本
    	        System.out.println("request uri:" + uri);
    	        System.out.println("request content:" + content);
    	        boolean match = false; 
    	        if(uri.contains("J")) {
    	        	match = true;
    	        }
    	        data.put("match", String.valueOf(match));
    	        data.put("protocal", protocal);
    	        data.put("uri", uri);
    	        data.put("time", date.toString());
    	        data.put("content", content);
    	        System.getProperty("HOST");
    	        String responsedata = "{";
    	        Set<String> keySet = data.keySet();
    	        int size = data.size();
    	        for (String key : keySet) {
    	        	size --;
    	        	responsedata = responsedata + """ + key  + "":" + """ + data.get(key) + (size == 0? ""}" : "",");
    			}
    	        
    	        // 创建http响应
    	        FullHttpResponse response = new DefaultFullHttpResponse(
    	                                        HttpVersion.HTTP_1_1,
    	                                        HttpResponseStatus.OK,
    	                                        Unpooled.copiedBuffer(responsedata, CharsetUtil.UTF_8));
    	       // 设置头信息
    	        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8");
    	       // 将处理后的数据 write到客户端、
    	        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    	    }
    	    
    }
    

    启动

    main方法启动服务

    public static void main(String[] args) throws Exception{
            HttpServer server = new HttpServer(80);// 80为启动端口
            server.start();
    }
    
    server start... port : 80
    

    客户端测试

    浏览器发送请求

    直接url栏输入get请求:

    http://localhost/test?name=J&time=-1
    

    返回结果

    {
        "match":"true",
        "time":"Sun Jul 11 21:52:22 CST 2021",
        "protocal":"HTTP/1.1",
        "uri":"/test?name=J&time=-1",
        "content":""
    }
    

    发送请求

    http://localhost/test?name=nos&time=-1
    

    返回结果

    {
        "match":"false",
        "time":"Sun Jul 11 21:52:22 CST 2021",
        "protocal":"HTTP/1.1",
        "uri":"/test?name=nos&time=-1",
        "content":""
    }
    
  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    103. Binary Tree Zigzag Level Order Traversal
    102. Binary Tree Level Order Traversal
    690. Employee Importance
    1723. Find Minimum Time to Finish All Jobs
    LeetCode 329 矩阵中最长增长路径
    7.2 物理内存管理
    LeetCode 面试题 特定深度节点链表
    LeetCode 100 相同的树
    npm安装包命令详解,dependencies与devDependencies实际区别
  • 原文地址:https://www.cnblogs.com/Narule/p/14999938.html
Copyright © 2020-2023  润新知