Netty入门指南之传统通信的问题

作者简介:☕️大家好,我是Aomsir,一个爱折腾的开发者!
个人主页:Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客
当前专栏:Netty应用专栏_Aomsir的博客-CSDN博客

文章目录

  • 参考文献
  • 前言
  • 多线程版
  • 线程池版
  • 总结

参考文献

  • 孙哥suns说Netty
  • Netty官方文档

前言

前一篇文章中,我学到了与Netty有关的基础知识,了解NIO这个非阻塞式IO,那今天我们来聊聊传统的网络通信开发方式以及它所存在的问题,也就是使用 Socket的方式。Socket是阻塞式的IO,我们要做通信肯定得涉及多线程或者线程池的方式,这两种方式对于Socket都不友好,都有问题,如下详细分析一下。

注意:由于我们平常开发都是面向Tomcat开发的,很少会有机会能够接触Socket编程

多线程版

下面是多线程版网络通信的情况。从图中可以明显看出,随着客户端请求服务端的增加,服务端为处理这些请求不断创建新线程,而这一过程缺乏充分的限制,会无节制的进行创建。每次虚拟机创建线程都需要与操作系统进行通信,这会耗费时间和占用内存,导致内存使用量不断上升。此外,当所创建的线程数量超过了CPU核心数时,CPU就不得不进行轮转处理,这将导致CPU占用率飙升。
在这里插入图片描述

public class AomsirServer {public static void main(String[] args) {ServerSocket serverSocket = null;try {serverSocket = new ServerSocket(8080);Socket socket = null;while (true) {socket = serverSocket.accept();new Thread(new AomsirServerHandler(socket)).start();}} catch (Exception e) {e.printStackTrace();} finally {if (serverSocket != null) {try {serverSocket.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}/*** 用于处理通信请求的线程*/
class AomsirServerHandler implements Runnable {private Socket socket;public AomsirServerHandler(Socket socket) {this.socket = socket;}public void run() {BufferedReader bufferedReader = null;try {bufferedReader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));while (true) {String line = bufferedReader.readLine();if (line != null) {System.out.println("line = " + line);}}} catch (Exception e) {e.printStackTrace();} finally {if (bufferedReader != null) {try {bufferedReader.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}
public class AomsirClient {public static void main(String[] args) {Socket socket = null;PrintWriter printWriter = null;try {socket = new Socket("127.0.0.1", 8080);printWriter = new PrintWriter(socket.getOutputStream());printWriter.write("send date to server ");printWriter.flush();} catch (Exception e) {e.printStackTrace();} finally {if (socket != null) {try {socket.close();} catch (IOException e) {throw new RuntimeException(e);}}if (printWriter != null) {printWriter.close();}}}
}

线程池版

在上述多线程版网络通信中,服务端以一种无限制的方式为每个请求创建新线程,这导致高并发下线程数量无限增加。为了解决这一问题,我们提出了一种解决方案,即使用线程池。这是一种基于池化思想的方法,通过在服务端启动时创建固定数量的线程(例如N个),来限制后续线程的创建。这N个线程将专用于后续请求的处理,不再创建新的线程。当一个请求完成处理后,线程将被放回线程池,以供后续请求使用。如果请求数量超过了线程池的线程数量,后续请求将进入队列等待。这一方法有效地解决了无节制创建线程的问题。

然而,尽管线程池解决了线程创建问题,它引入了新的潜在问题,即阻塞问题。举例来说,如果线程1分配给了客户端A,但客户端1在某一时刻发生阻塞,无法继续处理请求,线程1将不得不一直等待客户端A,无法返回线程池,导致服务端处理请求的效率降低。
在这里插入图片描述

public class AomsirServer1 {// 创建线程池private static ExecutorService executorService;// 初始化线程池static{executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),20,120L, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(1000));}public static void main(String[] args) {ServerSocket serverSocket = null;try {serverSocket = new ServerSocket(8080);Socket socket = null;while (true) {socket = serverSocket.accept();//new Thread(new SunsServerHandler(socket)).start();//线程池executorService.execute(new AomsirServerHandler(socket));}} catch (Exception e) {e.printStackTrace();} finally {if (serverSocket != null) {try {serverSocket.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}/*** 服务端处理客户端请求的线程*/
class AomsirServerHandler implements Runnable {private Socket socket;public AomsirServerHandler(Socket socket) {this.socket = socket;}public void run() {BufferedReader bufferedReader = null;try {bufferedReader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));while (true) {String line = bufferedReader.readLine();if (line != null) {System.out.println("line = " + line);}}} catch (Exception e) {e.printStackTrace();} finally {if (bufferedReader != null) {try {bufferedReader.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}
public class AomsirClient1 {public static void main(String[] args) {Socket socket = null;PrintWriter printWriter = null;try {socket = new Socket("127.0.0.1", 8080);printWriter = new PrintWriter(socket.getOutputStream());printWriter.write("send date to server ");printWriter.flush();} catch (Exception e) {e.printStackTrace();} finally {if (socket != null) {try {socket.close();} catch (IOException e) {throw new RuntimeException(e);}}if (printWriter != null) {printWriter.close();}}}
}

总结

在客户端-服务器结构中,使用BIO(阻塞I/O)进行网络通信时,无论是无限制地创建线程,还是通过线程池限制线程创建,都难以避免一个共同的问题:当客户端连接到服务器后,在一段时间内不进行通信,线程将被空闲浪费,导致资源的低效利用。

为了解决这个问题,我们可以采用NIO(非阻塞I/O)来处理网络通信。NIO允许服务器同时管理多个连接,而不需要为每个连接创建一个单独的线程。这使得服务器能够更高效地处理大量连接,减少了资源浪费。Netty是一个常见的工具,它底层使用了NIO,为我们开发者提供了更容易使用和管理的方式来构建高性能的网络应用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/132930.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于APM(PIX)飞控和missionplanner制作遥控无人车-从零搭建自主pix无人车无人坦克

前面的步骤和无人机调试一样&#xff0c;可以参考无人机相关专栏。这里不再赘述。 1.安装完rover的固件后&#xff0c;链接gps并进行校准。旋转小车不同方向&#xff0c;完成校准&#xff0c;弹出成功窗口。 2.校准遥控器。 一定要确保遥控器模式准确&#xff0c;尤其是使用没…

轻量封装WebGPU渲染系统示例<20>- 美化一下元胞自动机(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/GameOfLifePretty.ts 系统特性: 1. 用户态与系统态隔离。 2. 高频调用与低频调用隔离。 3. 面向用户的易用性封装。 4. 渲染数据(内外部相关资源)和渲染机制分离…

使用Anaconda安装TensorFlow环境以及没有搜到的报错的解决方法

1.在官网下载Anaconda 这一步几乎不会有人报错 下稳定的版本 或者最新的版本都可以 2.TensorFlow分两个版本 一个是用cpu跑 另一个是用gpu跑 显而易见 cpu的计算性能已经比不上现在主流的显卡了 所以有独显的电脑尽量安装gpu版本 CPU版本: 先给出cpu版本的安装方法: 打开A…

描述低轨星座的特点和通信挑战,以及它们在5G和B5G中的作用。

文章目录 2章4 章5章&#xff08;没看&#xff09;6章&#xff08;没看&#xff09; 2章 将卫星星座中每个物理链路中可实现的数据速率、传播延迟和多普勒频移与3GPP技术报告中的参数进行分析和比较[3]。 相关配置 面向连接的网络&#xff0c;预先简历链路 卫星和地面终端有…

自动化测试--验证邮件内容

场景 业务上有许多发送邮件的场景&#xff0c;发送的邮件基本上都是自动发送的&#xff0c;而且邮件内容是很重要的&#xff0c;对于邮件发没发送&#xff0c;发送的时间点对不对每次回归测试工作量太大了&#xff0c;所以考虑把这部分内容加入到自动化测试中 工具 python g…

了解计算机的大小端存储模式

我们在计算机中存储数据时&#xff0c;数据是如何组织和表示的是一个重要的问题。其中一个关键概念是 大小端存储模式&#xff08;Endianness&#xff09;&#xff0c;它描述了多字节数据在内存中的存储方式。本文将介绍大小端存储模式的原理、应用和区别。 什么是大小端存储模…

通过全流量查看部门或客户端网络使用情况

近年来&#xff0c;随着数字化转型和云计算服务的广泛应用&#xff0c;组织和企业对于网络带宽和性能的需求也在不断增长。 网络的稳定性、性能和安全性对于业务流程的顺畅运行至关重要。因此&#xff0c;了解部门或客户端网络的使用情况是网络管理和优化的关键。本文将通过Ne…

Docker数据管理、网络与Cgroup资源限制

目录 一、Docker的数据管理 1、数据卷 2、数据卷容器 3、端口映射 4、容器互联 二、Docker网络 2.1Docker网络实现原理 2.2Docker 的网络模式 3.3网络模式详解&#xff1a; host模式 container模式 none模式 bridge模式 自定义网络 创建自定义网络 三、Cgroup资源…

Maven修改仓库和镜像地址

目录 1、修改仓库地址2、修改镜像地址 1、修改仓库地址 使用IDEA时,如果不指定自己下载的Maven,idea会默认使用自带的Maven 3&#xff08;bundle)。maven 3默认的仓库路径一般是在c盘的用户文件夹中的.m2目录下&#xff1a; 当maven下的pom文件中的依赖逐渐增加时,maven仓库下…

0基础学习VR全景平台篇第116篇:认识修图软件Photoshop

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 今天给大家讲解修图软件Photoshop&#xff0c;下面我们开始吧&#xff01; &#xff08;PS软件课程大纲&#xff09; 1.Photoshop是什么 发明人Adobe Photoshop&#xff0c;简称…

剑指Offer-推理二叉树

剑指Offer-推理二叉树 LCR 124. 推理二叉树 题目如下 某二叉树的先序遍历结果记录于整数数组 preorder&#xff0c;它的中序遍历结果记录于整数数组 inorder。请根据 preorder 和 inorder 的提示构造出这棵二叉树并返回其根节点。 注意&#xff1a;preorder 和 inorder 中均…

JavaScript作用域实战

● 首先&#xff0c;我们先创建一个函数&#xff0c;和以前一样&#xff0c;计算一个年龄的 function calcAge(birthYear) {const age 2037 - birthYear;return age; }● 然后我们创建一个全局变量&#xff0c;并调用这个函数 const firstName "IT知识一享"; cal…

Thread类的基本操作(JAVA多线程)

线程是操作系统中的概念&#xff0c;操作系统内核实现了线程这样的机制&#xff0c;并提供了一些API供外部使用。 JAVA中 Thread类 将系统提供的API又近一步进行了抽象和封装&#xff0c;所以如果想要使用多线程就离不开 Thread 这个类。 线程的创建(Thread类) 在JAVA中 创建…

中国多主数据库:压强投入,期待破茧

拿破仑曾说&#xff1a;“战争的艺术就是在某一点上集中最大优势兵力”&#xff0c;强调了力量集中的重要性。 如今&#xff0c;国际形势风云变幻&#xff0c;西方世界对中国的围剿不再仅仅体现在军事和地缘政治上&#xff0c;而更多表现在经济与科技上。在科技领域&#xff0…

Akshare获取同花顺行业

使用akshare可以很方便的获取同花顺行业列表&#xff0c;与每个行业对应的个股信息&#xff0c;流程如下&#xff1a; 使用ak.stock_board_industry_summary_ths()获取行业列表循环行业列表&#xff0c;使用ak.stock_board_industry_cons_ths()获取行业对应的个股信息 官方文…

MySQL数据库入门到大牛_02_MySQL环境搭建、演示使用、图形化管理工具、一二章练习

文章目录 1. MySQL的卸载步骤1&#xff1a;停止MySQL服务步骤2&#xff1a;软件的卸载步骤3&#xff1a;残余文件的清理步骤4&#xff1a;清理注册表&#xff08;选做&#xff09;步骤5&#xff1a;删除环境变量配置 2. MySQL的下载、安装、配置2.1 MySQL的4大版本2.2 软件的下…

Python基础(第五期): python数据容器(序列) 列表 集合 元素 字符串 字典 序列遍历操作

python基础专栏 python基础&#xff08;第五期&#xff09; 文章目录 python基础&#xff08;第五期&#xff09;数据容器一、列表1、列表的定义2、列表的下标索引 3、列表的(添加)方法3.1 列表的查询方法3.2 修改特定下标索引的值3.3 列表指定位置插入元素3.3 列表指定元素的追…

【Linux】-文件操作(重定向、缓冲区以及Linux下一切皆文件的详解)

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

电脑监控软件丨2023全网最详细解析

电脑监控软件是一个比较敏感的话题&#xff0c;因为很多员工会觉得电脑监控侵犯了自己的隐私&#xff0c;电脑上企业会觉得安装软件只不过是为了保护自己的核心利益。 对于此&#xff0c;我们要辩证的看待。 今天我们从企业的角度出发&#xff0c;谈谈电脑监控软件的话题。 必…

【python VS vba】(5) 在python中使用xlwt操作Excel(待完善ing)

目录 1 什么是xlwt 2 导入xlwt 3 相关语法 3.1 创建新的workbook 3.2 创建新的sheet 3.3 保存workbook 4 python里表格的形式 4.1 矩阵 4.2 EXCEL的数据形式 完全等于矩阵的数字结构 4.3 python里矩阵 5 具体代码 5.1 代码 5.2 结果 5.3 要注意的问题 5.3.1 不能…