日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

SpringBoot使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的示例

瀏覽:159日期:2023-04-14 11:13:18

前言

眾所周知我們?cè)谶M(jìn)行網(wǎng)絡(luò)連接的時(shí)候,建立套接字連接是一個(gè)非常消耗性能的事情,特別是在分布式的情況下,用線程池去保持多個(gè)客戶端連接,是一種非常消耗線程的行為。那么我們?cè)撏ㄟ^(guò)什么技術(shù)去解決上述的問(wèn)題呢,那么就不得不提一個(gè)網(wǎng)絡(luò)連接的利器——Netty.

正文 Netty

Netty是一個(gè)NIO客戶端服務(wù)器框架:

它可快速輕松地開(kāi)發(fā)網(wǎng)絡(luò)應(yīng)用程序,例如協(xié)議服務(wù)器和客戶端。 它極大地簡(jiǎn)化和簡(jiǎn)化了網(wǎng)絡(luò)編程,例如TCP和UDP套接字服務(wù)器。

NIO是一種非阻塞IO ,它具有以下的特點(diǎn)

單線程可以連接多個(gè)客戶端。 選擇器可以實(shí)現(xiàn)但線程管理多個(gè)Channel,新建的通道都要向選擇器注冊(cè)。 一個(gè)SelectionKey鍵表示了一個(gè)特定的通道對(duì)象和一個(gè)特定的選擇器對(duì)象之間的注冊(cè)關(guān)系。 selector進(jìn)行select()操作可能會(huì)產(chǎn)生阻塞,但是可以設(shè)置阻塞時(shí)間,并且可以用wakeup()喚醒selector,所以NIO是非阻塞IO。

Netty模型selector模式

它相對(duì)普通NIO的在性能上有了提升,采用了:

NIO采用多線程的方式可以同時(shí)使用多個(gè)selector 通過(guò)綁定多個(gè)端口的方式,使得一個(gè)selector可以同時(shí)注冊(cè)多個(gè)ServerSocketServer 單個(gè)線程下只能有一個(gè)selector,用來(lái)實(shí)現(xiàn)Channel的匹配及復(fù)用

SpringBoot使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的示例

半包問(wèn)題

TCP/IP在發(fā)送消息的時(shí)候,可能會(huì)拆包,這就導(dǎo)致接收端無(wú)法知道什么時(shí)候收到的數(shù)據(jù)是一個(gè)完整的數(shù)據(jù)。在傳統(tǒng)的BIO中在讀取不到數(shù)據(jù)時(shí)會(huì)發(fā)生阻塞,但是NIO不會(huì)。為了解決NIO的半包問(wèn)題,Netty在Selector模型的基礎(chǔ)上,提出了reactor模式,從而解決客戶端請(qǐng)求在服務(wù)端不完整的問(wèn)題。

netty模型reactor模式

在selector的基礎(chǔ)上解決了半包問(wèn)題。

SpringBoot使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的示例

上圖,簡(jiǎn)單地可以描述為'boss接活,讓work干':manReactor用來(lái)接收請(qǐng)求(會(huì)與客戶端進(jìn)行握手驗(yàn)證),而subReactor用來(lái)處理請(qǐng)求(不與客戶端直接連接)。

SpringBoot使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用

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>

服務(wù)端部分

NettyServer.java:服務(wù)啟動(dòng)監(jiān)聽(tīng)器

@Slf4jpublic class NettyServer { public void start() { InetSocketAddress socketAddress = new InetSocketAddress('127.0.0.1', 8082); //new 一個(gè)主線程組 EventLoopGroup bossGroup = new NioEventLoopGroup(1); //new 一個(gè)工作線程組 EventLoopGroup workGroup = new NioEventLoopGroup(200); ServerBootstrap bootstrap = new ServerBootstrap().group(bossGroup, workGroup).channel(NioServerSocketChannel.class).childHandler(new ServerChannelInitializer()).localAddress(socketAddress)//設(shè)置隊(duì)列大小.option(ChannelOption.SO_BACKLOG, 1024)// 兩小時(shí)內(nèi)沒(méi)有數(shù)據(jù)的通信時(shí),TCP會(huì)自動(dòng)發(fā)送一個(gè)活動(dòng)探測(cè)數(shù)據(jù)報(bào)文.childOption(ChannelOption.SO_KEEPALIVE, true); //綁定端口,開(kāi)始接收進(jìn)來(lái)的連接 try { ChannelFuture future = bootstrap.bind(socketAddress).sync(); log.info('服務(wù)器啟動(dòng)開(kāi)始監(jiān)聽(tīng)端口: {}', socketAddress.getPort()); future.channel().closeFuture().sync(); } catch (InterruptedException e) { log.error('服務(wù)器開(kāi)啟失敗', e); } finally { //關(guān)閉主線程組 bossGroup.shutdownGracefully(); //關(guān)閉工作線程組 workGroup.shutdownGracefully(); } }}

ServerChannelInitializer.java:netty服務(wù)初始化器

/*** netty服務(wù)初始化器**/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服務(wù)端處理器

/*** netty服務(wù)端處理器**/@Slf4jpublic class NettyServerHandler extends ChannelInboundHandlerAdapter { /** * 客戶端連接會(huì)觸發(fā) */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { log.info('Channel active......'); } /** * 客戶端發(fā)消息會(huì)觸發(fā) */ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { log.info('服務(wù)器收到消息: {}', msg.toString()); ctx.write('你也好哦'); ctx.flush(); } /** * 發(fā)生異常觸發(fā) */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); }}

RpcServerApp.java:SpringBoot啟動(dòng)類

/*** 啟動(dòng)類**/@Slf4j@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})public class RpcServerApp extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(RpcServerApp.class); } /** * 項(xiàng)目的啟動(dòng)方法 * * @param args */ public static void main(String[] args) { SpringApplication.run(RpcServerApp.class, args); //開(kāi)啟Netty服務(wù) NettyServer nettyServer =new NettyServer (); nettyServer.start(); log.info('======服務(wù)已經(jīng)啟動(dòng)========'); }}

客戶端部分

NettyClientUtil.java:NettyClient工具類

/*** Netty客戶端**/@Slf4jpublic class NettyClientUtil { public static ResponseResult helloNetty(String msg) { NettyClientHandler nettyClientHandler = new NettyClientHandler(); EventLoopGroup group = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap().group(group)//該參數(shù)的作用就是禁止使用Nagle算法,使用于小數(shù)據(jù)即時(shí)傳輸.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('客戶端發(fā)送成功....'); //發(fā)送消息 future.channel().writeAndFlush(msg); // 等待連接被關(guān)閉 future.channel().closeFuture().sync(); return nettyClientHandler.getResponseResult(); } catch (Exception e) { log.error('客戶端Netty失敗', e); throw new BusinessException(CouponTypeEnum.OPERATE_ERROR); } finally { //以一種優(yōu)雅的方式進(jìn)行線程退出 group.shutdownGracefully(); } }}

NettyClientHandler.java:客戶端處理器

/*** 客戶端處理器**/@Slf4j@Setter@Getterpublic 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(); }}

驗(yàn)證

測(cè)試接口

@RestController@Slf4jpublic class UserController { @PostMapping('/helloNetty') @MethodLogPrint public ResponseResult helloNetty(@RequestParam String msg) { return NettyClientUtil.helloNetty(msg); }}

訪問(wèn)測(cè)試接口

SpringBoot使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的示例

服務(wù)端打印信息

SpringBoot使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的示例

客戶端打印信息

SpringBoot使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的示例

源碼

項(xiàng)目源碼可從的我的github中獲取:github源碼地址

到此這篇關(guān)于SpringBoot使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的示例的文章就介紹到這了,更多相關(guān)SpringBoot Netty遠(yuǎn)程調(diào)用內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩 欧美一区二区三区| 99久久婷婷| 国产精品久久777777毛茸茸| 欧美不卡在线| 日本免费一区二区三区四区| 精品国产乱码久久久久久樱花| 日韩高清成人在线| 免费在线看一区| 久久久人人人| 国产拍在线视频| 四季av一区二区凹凸精品| 免费一级欧美片在线观看网站| 欧美日韩亚洲国产精品| 国产婷婷精品| 一本色道精品久久一区二区三区| 91成人精品| 亚洲综合电影一区二区三区| 免费看欧美美女黄的网站| 午夜亚洲精品| 视频一区日韩| 国产精品调教视频| 国产一区二区三区视频在线| 老司机免费视频一区二区| 国产精品一区二区免费福利视频| 四虎在线精品| 久久狠狠久久| 精品一区二区三区中文字幕 | 精品国产一区二区三区2021| 免费在线观看一区| 97精品国产| 99热国内精品| 欧美精品激情| 亚洲精品激情| 婷婷综合电影| 91亚洲无吗| 牛牛精品成人免费视频| 日韩在线高清| 亚洲免费播放| 日韩高清一区在线| 精品一区二区三区中文字幕视频 | 日韩精品一二三四| 日本一区二区免费高清| 亚洲欧美日韩视频二区| 麻豆国产精品一区二区三区 | 日韩免费在线| 欧美日韩亚洲一区在线观看| 丝袜美腿诱惑一区二区三区| 日韩精品乱码av一区二区| 1000部精品久久久久久久久| 欧美一级久久| 亚洲综合日本| 亚洲天堂一区二区| 日韩高清不卡在线| 免费视频亚洲| 精品理论电影在线| 日韩精品中文字幕一区二区| 午夜久久tv| 国产一区二区三区亚洲| 日韩欧美激情电影| 国产精品毛片一区二区三区| yellow在线观看网址| 国产欧美综合一区二区三区| 蜜臀精品一区二区三区在线观看| 久久久久99| 97精品国产一区二区三区 | 日本在线不卡视频一二三区| 91精品婷婷色在线观看| 精品国产日韩欧美精品国产欧美日韩一区二区三区 | 欧美日韩国产亚洲一区| 国产毛片精品| 亚洲精品一级二级三级| 在线亚洲国产精品网站| 99久久夜色精品国产亚洲1000部| 美腿丝袜在线亚洲一区| 欧美一级网站| 日韩va亚洲va欧美va久久| 首页欧美精品中文字幕| 国产一级一区二区| 亚洲经典在线| 亚洲激情另类| 9久re热视频在线精品| 欧美一区二区三区激情视频 | 人人精品人人爱| 日韩视频在线一区二区三区| 欧美日韩中文一区二区| 日韩另类视频| 久久久久亚洲| 一级欧洲+日本+国产| 国产99精品一区| 欧美高清一区| 五月婷婷亚洲| 亚洲欧美视频| 综合亚洲视频| 日本一区二区三区中文字幕| 日韩精品一区二区三区免费视频| 日本伊人久久| 日韩国产欧美在线播放| 日韩国产91| 国产情侣一区在线| 久久精品国产99国产精品| 久久精品国产亚洲aⅴ| 精品日韩在线| 日韩高清成人| 在线精品视频在线观看高清| 夜夜精品视频| 婷婷精品在线| 国产精品啊v在线| 国产精品久久久久久久久久白浆| 麻豆视频一区二区| 日韩在线二区| 欧美日韩第一| 久热精品在线| 日韩美女国产精品| 国产精品白浆| 日韩电影免费网站| 午夜精品影院| 欧美中文日韩| 在线免费观看亚洲| 国产精品资源| av在线资源| 欧美高清一区| 日韩免费精品| 精品国产亚洲一区二区三区在线 | 国产视频网站一区二区三区| 美女高潮久久久| 久久要要av| 美国欧美日韩国产在线播放| 欧美日韩午夜电影网| 四虎8848精品成人免费网站| 美女久久久久| 日本国产欧美| а√天堂中文在线资源8| 午夜日韩在线| 日韩精品久久理论片| 国内一区二区三区| 亚洲免费影视| 久久精品国产在热久久| 精品成人免费一区二区在线播放| 免费人成网站在线观看欧美高清| 麻豆免费精品视频| 午夜久久美女| 久久99精品久久久野外观看| 久久久久久久久99精品大| 亚洲青青久久| 日韩精品1区| 日韩av黄色在线| 久久免费大视频| 国产欧美日韩影院| 精品中文字幕一区二区三区av| 亚洲欧美久久| 岛国av在线播放| 一区二区三区国产盗摄| 国产va在线视频| 日韩高清不卡一区| 欧美69视频| 精品久久91| 一区二区三区网站| 日韩精品永久网址| 91精品国产自产精品男人的天堂 | 精品日韩毛片| 黄色网一区二区| 亚洲专区视频| 中文字幕系列一区| 久久国产人妖系列| 亚洲综合日本| 香蕉成人av| 麻豆精品一区二区综合av| 噜噜噜躁狠狠躁狠狠精品视频 | 日韩毛片视频| 欧美日韩亚洲一区| 亚洲欧美不卡| 人人草在线视频| 国产精品成人**免费视频| 麻豆久久精品| 国产综合亚洲精品一区二| 久久精品国产网站| 日韩成人在线看| 性欧美长视频| 黑丝美女一区二区| 蜜臀国产一区| 成人在线视频免费| 你懂的国产精品| 欧美日韩亚洲三区| 亚洲一区二区小说| 91成人超碰| 99视频精品全国免费| 韩国久久久久久| 精品网站999| 麻豆国产精品777777在线| 青青青国产精品| 亚洲毛片视频| 中文字幕亚洲在线观看| 手机精品视频在线观看| 亚洲午夜久久久久久尤物 | 亚洲深夜视频| 高清在线一区| 国产精品久久久久久久久妇女| 国产另类在线| 国产日产一区| 国产日韩精品视频一区二区三区|