返回顶部
首页 > 资讯 > 后端开发 > Python >在SpringBoot中,如何使用Netty实现远程调用方法总结
  • 566
分享到

在SpringBoot中,如何使用Netty实现远程调用方法总结

2024-04-02 19:04:59 566人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

Netty Netty是一个NIO客户端服务器框架: 它可快速轻松地开发网络应用程序,例如协议服务器和客户端。 它极大地简化和简化了网络编程,例如tcp和UDP套接

Netty

Netty是一个NIO客户端服务器框架

  • 它可快速轻松地开发网络应用程序,例如协议服务器和客户端。
  • 它极大地简化和简化了网络编程,例如tcp和UDP套接字服务器。

Nio是一种非阻塞IO ,它具有以下的特点

  • 线程可以连接多个客户端。
  • 选择器可以实现单线程管理多个Channel,新建的通道都要向选择器注册。
  • 一个SelectionKey键表示了一个特定的通道对象和一个特定的选择器对象之间的注册关系。
  • selector进行select()操作可能会产生阻塞,但是可以设置阻塞时间,并且可以用wakeup()唤醒selector,所以NIO是非阻塞IO。

Netty模型selector模式

它相对普通NIO的在性能上有了提升,采用了:

  • NIO采用多线程的方式可以同时使用多个selector
  • 通过绑定多个端口的方式,使得一个selector可以同时注册多个ServerSocketServer
  • 单个线程下只能有一个selector,用来实现Channel的匹配及复用

image

半包问题

TCP/IP在发送消息的时候,可能会拆包,这就导致接收端无法知道什么时候收到的数据是一个完整的数据。在传统的BIO中在读取不到数据时会发生阻塞,但是NIO不会。为了解决NIO的半包问题,Netty在Selector模型的基础上,提出了Reactor模式,从而解决客户端请求在服务端不完整的问题。

netty模型reactor模式

在selector的基础上解决了半包问题。

image

上图,简单地可以描述为"boss接活,让work干":manReactor用来接收请求(会与客户端进行握手验证),而subReactor用来处理请求(不与客户端直接连接)。

SpringBoot使用Netty实现远程调用

Maven依赖


<!--lombok-->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.2</version>
  <optional>true</optional>
</dependency>

<!--netty-->
<dependency>
  <groupId>io.netty</groupId>
  <artifactId>netty-all</artifactId>
  <version>4.1.17.Final</version>
</dependency>

服务端部分

NettyServer.java:服务启动监听器


@Slf4j
public class NettyServer {
    public void start() {
        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8082);
        //new 一个主线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        //new 一个工作线程组
        EventLoopGroup workGroup = new NioEventLoopGroup(200);
        ServerBootstrap bootstrap = new ServerBootstrap()
                .group(bossGroup, workGroup)
                .channel(NiOServerSocketChannel.class)
                .childHandler(new ServerChannelInitializer())
                .localAddress(socketAddress)
                //设置队列大小
                .option(ChannelOption.SO_BACKLOG, 1024)
                // 两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文
                .childOption(ChannelOption.SO_KEEPALIVE, true);
        //绑定端口,开始接收进来的连接
        try {
            ChannelFuture future = bootstrap.bind(socketAddress).sync();
            log.info("服务器启动开始监听端口: {}", socketAddress.getPort());
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            log.error("服务器开启失败", e);
        } finally {
            //关闭主线程组
            bossGroup.shutdownGracefully();
            //关闭工作线程组
            workGroup.shutdownGracefully();
        }
    }
}

ServerChannelInitializer.java:netty服务初始化器



public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        //添加编解码
        socketChannel.pipeline().addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
        socketChannel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
        socketChannel.pipeline().addLast(new NettyServerHandler());
    }
}

NettyServerHandler.java:netty服务端处理器



@Slf4j
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("Channel active......");
    }

    
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("服务器收到消息: {}", msg.toString());
        ctx.write("你也好哦");
        ctx.flush();
    }

    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

rpcServerApp.java:springBoot启动类



@Slf4j
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class RpcServerApp extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(RpcServerApp.class);
    }

    
    public static void main(String[] args) {
        SpringApplication.run(RpcServerApp.class, args);
        //开启Netty服务
        NettyServer nettyServer =new  NettyServer ();
        nettyServer.start();
        log.info("======服务已经启动========");
    }
}

客户端部分

NettyClientUtil.java:NettyClient工具



@Slf4j
public class NettyClientUtil {

    public static ResponseResult helloNetty(String msg) {
        NettyClientHandler nettyClientHandler = new NettyClientHandler();
        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap()
                .group(group)
                //该参数的作用就是禁止使用Nagle算法,使用于小数据即时传输
                .option(ChannelOption.TCP_nodeLAY, true)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast("decoder", new StringDecoder());
                        socketChannel.pipeline().addLast("encoder", new StringEncoder());
                        socketChannel.pipeline().addLast(nettyClientHandler);
                    }
                });
        try {
            ChannelFuture future = bootstrap.connect("127.0.0.1", 8082).sync();
            log.info("客户端发送成功....");
            //发送消息
            future.channel().writeAndFlush(msg);
            // 等待连接被关闭
            future.channel().closeFuture().sync();
            return nettyClientHandler.getResponseResult();
        } catch (Exception e) {
            log.error("客户端Netty失败", e);
            throw new BusinessException(CouponTypeEnum.OPERATE_ERROR);
        } finally {
            //以一种优雅的方式进行线程退出
            group.shutdownGracefully();
        }
    }
}

NettyClientHandler.java:客户端处理器



@Slf4j
@Setter
@Getter
public class NettyClientHandler extends ChannelInboundHandlerAdapter {

    private ResponseResult responseResult;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端Active .....");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("客户端收到消息: {}", msg.toString());
        this.responseResult = ResponseResult.success(msg.toString(), CouponTypeEnum.OPERATE_SUCCESS.getCouponTypeDesc());
        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

验证

测试接口


@RestController
@Slf4j
public class UserController {

    @PostMapping("/helloNetty")
    @MethodLogPrint
    public ResponseResult helloNetty(@RequestParam String msg) {
        return NettyClientUtil.helloNetty(msg);
    }
}

访问测试接口

image

服务端打印信息

image

客户端打印信息

image

到此这篇关于在SpringBoot中,如何使用Netty实现远程调用方法总结的文章就介绍到这了,更多相关Netty实现远程调用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 在SpringBoot中,如何使用Netty实现远程调用方法总结

本文链接: https://lsjlt.com/news/128529.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 在SpringBoot中,如何使用Netty实现远程调用方法总结
    Netty Netty是一个NIO客户端服务器框架: 它可快速轻松地开发网络应用程序,例如协议服务器和客户端。 它极大地简化和简化了网络编程,例如TCP和UDP套接...
    99+
    2024-04-02
  • 使用Netty实现类似Dubbo的远程接口调用的实现方法
    目录一、Netty简介二、完整代码实现1、创建接口和实现类2、客户端代码实现及动态代理和异步转同步3、服务端代码实现4、自定义编码解码器5、编写测试客户端发送请求代码一、Netty简...
    99+
    2023-05-17
    Netty Dubbo远程接口调用 Netty Dubbo远程调用
  • 在Java中实现远程方法调用(转)
    在Java中实现远程方法调用(转)[@more@]一、Java中的远程方法调用 远程方法调用(Remote Method Invocation, RMI)是Java1.1引入的分布式对象软件包,它的出现简化了在多台机器上的Java应用之间的...
    99+
    2023-06-03
  • 如何使用Springboot+netty实现Web聊天室
    这篇文章主要为大家展示了“如何使用Springboot+netty实现Web聊天室”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用Springboot+netty实现Web聊天室”这篇文章...
    99+
    2023-06-21
  • 如何在PHP中实现RPC远程调用?
    随着互联网的快速发展和云计算技术的广泛应用,分布式系统和微服务架构变得越来越普遍。在这样的背景下,远程过程调用(RPC)成为了一种常见的技术手段。RPC能够使得不同的服务在网络上实现远程调用,从而实现不同服务之间的互联操作,提高代码的复用性...
    99+
    2023-05-14
    PHP rpc 远程调用
  • springBoot使用openfeign来远程调用的实现
    目录使用openfeign来远程调用springBoot使用openfeign使用openfeign来远程调用 1、客户端调用方 导入依赖 org.springframework.c...
    99+
    2024-04-02
  • 如何在springboot中使用feign实现跨服务调用
    这篇文章给大家介绍如何在springboot中使用feign实现跨服务调用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。springboot整合feign引入依赖, 这里注意, spring-cloud.version...
    99+
    2023-06-06
  • Thymeleaf方法如何在SpringBoot中使用
    Thymeleaf方法如何在SpringBoot中使用?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。ThymeleafThymeleaf是最近SpringBoot推荐支持的模板...
    99+
    2023-05-31
    springboot thymeleaf
  • 如何使用PHP和Swoole实现RPC远程调用
    如何使用PHP和Swoole实现RPC远程调用RPC(Remote Procedure Call)是一种远程调用的协议,可以让应用程序在不同计算机上进行函数调用。RPC通常被用于构建分布式系统,其可以让不同的微服务能够协同工作。在PHP和S...
    99+
    2023-05-14
    PHP rpc swoole
  • 如何在java中使用反射调用方法
    这篇文章将为大家详细讲解有关如何在java中使用反射调用方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java有哪些集合类Java中的集合主要分为四类:1、List列表:有序的,可重复的...
    99+
    2023-06-14
  • 总结python实现父类调用两种方法的不同
    python中有两种方法可以调用父类的方法: super(Child, self).method(args) Parent.method(self, args) 我用其中的一种报了如下错误: 找不到 c...
    99+
    2022-06-04
    两种 方法 python
  • SpringBoot-RestTemplate如何实现调用第三方API
    目录1.在build.grdle加入依赖2.在config包下创建一个RestTemlateConfig3.在model包下创建一个新的包4.Constans类下将调用接口的AppK...
    99+
    2024-04-02
  • 在PHP中如何实现方法在其他文件中的调用?
    在PHP中如何实现方法在其他文件中的调用 对于PHP开发者来说,有时候我们会需要在一个文件中编写某些方法,然后在其他文件中调用这些方法。这种情况下,我们可以使用PHP的命名空间(nam...
    99+
    2024-03-05
    php 函数调用 文件路径定位
  • 在JAVA中如何调用方法
    在Java语言中方法调用的语法格式:对象变量名.方法名(实参列表);其中,圆括号中的“实参列表”为调用方法时实际传入的实际参数,称为实参列表。声明方法时圆括号中的参数称为形式参数,形式参数和实际参数在数据类型和个数上一定要匹配。例如:类Ad...
    99+
    2021-03-31
    java入门 java 调用 方法
  • springboot实现在工具类(util)中调用注入service层方法
    一、新建BeanUtil类 import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansExc...
    99+
    2024-04-02
  • 在Java中如何使用接口调用Groovy方法
    小编给大家分享一下在Java中如何使用接口调用Groovy方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!定义Java接口包含在Java中需要调用的Groovy...
    99+
    2023-06-03
  • 如何在SpringBoot中使用main方法注入service
    如何在SpringBoot中使用main方法注入service?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、SpringBoot中的main方法注入service在spri...
    99+
    2023-06-15
  • Java如何实现方法调用
    这篇文章给大家分享的是有关Java如何实现方法调用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。  Java的方法调用方法(method)的定义:  1 在java中程序员可以把在一个程序中多...
    99+
    2023-06-03
  • 使用SpringBoot如何实现远程连接redis服务器
    今天就跟大家聊聊有关使用SpringBoot如何实现远程连接redis服务器,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。使用了SpringBoot的项目,在远程连接Redis服务器...
    99+
    2023-05-31
    springboot 远程连接 redis
  • Vue2中使用axios的3种方法实例总结
    目录第一种 原始方法 直接在项目中使用(不建议使用)第二种 将请求挂载到全局( 推荐使用 )第三种 将代码进行封装总结第一种 原始方法 直接在项目中使用(不建议使用) 这种方法最简单...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作