理解java底层通讯协议
引言:
本周自己重新对底层通讯方式进行了学习,在此做一个输出。
分别从客户端发送多个请求的需求角度与服务端接收多个连接发送请求的需求角度,剖析4种基于java自身技术实现的消息方式通讯所带来的影响,解决方式以及各自通讯方式的区别和优缺点。
通讯协议的特性:

4种组合通讯方式区别和优缺点剖析:
TCP/IP+BIO:
对于客户端同时发送多个请求到服务端的问题:
简单直接的解决方式:生成多个socket连接
上述解决方式带来的影响:
1.生成太多的socket客户端会消耗大量的本地资源,当客户端机器多,服务端机器少时,客户端生成太多的socket会导致服务器端需要支撑非常高的连接数。
2.生成socket连接的过程通常是比较慢的,频繁创建会导致系统性能不足的问题。
针对上述影响问题的常见解决方案:
1.通常采用连接池的方式来维护socket连接,好处:一方面限制了能创建socket的个数,另一方面连接池避免了重复创建socket。
连接池方式带来的问题:
1.连接池中的socket个数是有限的,同时要用socket连接的请求过多的情况下就会造成资源竞争与大量的等待。
2.另外就是会遇到合理限制等待超时时间的问题,如果不设置超时会导致服务端处理变慢,进而导致客户端请求都在无限等待,而客户端资源是有限的,因此很容易出现服务端瓶颈引起客户端挂掉的现象。
那么,超时时间设置多少?这取决于客户端的请求量,以及服务端的处理速度,要在性能和出错率之间保持平衡。
对于服务端能同时接受多个连接发送的请求的问题:
直接的解决方案:
在accept获取socket后,将此socket放入一个线程中处理,即一个连接一个线程模式,这样服务器就可以接受多个连接发送请求了。
上述解决方式带来的影响:
1.无论socket连接上是否有真实的请求,都要耗费一个线程,为避免创建过多线程导致服务器资源耗尽,需限制线程创建的数量,这就造成了采用BIO情况下服务端所支撑的连接数是有限的问题。
TCP/IP+NIO:
对于客户端同时发送多个请求到服务端的问题:
实现方式:
与TCP/IP+BIO方式没有什么不同,但NIO可以做到不阻塞,如果服务器返回响应带上请求标识,那么客户端则可采用连接复用的方式,这可以降低连接池带来的资源争抢问题。
对于连接不复用的情况则采用socket.setSoTimeout方式来控制同步请求超时,连接复用设置超时时间可基于blockingqueue,对象的wait/notify机制,futrue机制来实现。
对于服务端能同时接受多个连接发送的请求的问题:
解决方式:
采用一个线程来监视连接事件,另一个或多个线程来监听网络读写流的事件,只有当实际网络流读写事件发生后,再放入线程池中处理。
带来的影响:
比TCP/IP+BIO方式能接受更多的连接,而这些连接只有在真实请求发生时才会创建线程处理,节省资源。
但当连接数不多,且连接数请求发送非常频繁时,不会带来太大的优势,不过实际场景中通常是服务端要支持接受非常多的连接,但是这些连接同时发送的请求并不多。
UDP/IP+BIO:
实现方式:
采用receive和send方法进行读写操作。
由于UDP方式不建立通讯连接,故没有连接竞争的问题,只是读写流的动作是同步的。
对于服务端能同时接受多个发送的请求,通过采用每收到一个packet 就放入一个线程中进行处理来实现。
UDP/IP+NIO:
对于UDP/IP通讯方式,NIO带来的好处只有在有流要读写时才做相应的IO操作,不用像BIO方式直接阻塞当前线程。
参考:《分布式java应用》
理解java底层通讯协议的更多相关文章
- 使用delphi 开发多层应用(十六)使用XMLRPC 实现basic4android 远程调用RTC服务(讲述了RTC的特点,其底层通讯协议是自己封装SOCK 库,与kbmmw 的适合场合不完全一样)
RealThinClient (以下简称RTC) 也是一款delphi 多层开发的框架,由于其底层通讯协议是自己封装SOCK 库,抛弃了 大家诟病的indy,因此表现的非常稳定,效率也非常高, ...
- JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用
JAVA之旅(三十二)--JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用 GUI写到一半电脑系统挂了,也就算了,最多GUI还有一个提示框和实例, ...
- java基础55 UDP通讯协议和TCP通讯协议
本文知识点(目录): 1.概述 2.UDP通讯协议 3.TCPP通讯协议 1.概述 1.在java中网络通讯作为Socket(插座)通讯,要求两台都必须安装socket. 2.不同的 ...
- JDK学习---深入理解java中的HashMap、HashSet底层实现
本文参考资料: 1.<大话数据结构> 2.http://www.cnblogs.com/dassmeta/p/5338955.html 3.http://www.cnblogs.com/d ...
- 如何快速掌握plc或工控机与其他设备的modbus通讯协议?包括格式与实际过程 RT,本人从事工控行业多年,对于PLC与触摸屏也算比较熟悉,唯独对这个通讯协议比较难理解,请教高人指导,从什么地方开始下手,或者是说如何正确理解报文格式或正确写入
Modbus协议是OSI模型的第七层的应用层通讯协议,定义了不同类型设备间交换信息方式,以及信息的格式. Modbus的工作方式是请求/应答,每次通讯都是主站先发送指令,可以是广播,或是向特定从站的单 ...
- 理解java容器底层原理--手动实现HashMap
HashMap结构 HashMap的底层是数组+链表,百度百科找了张图: 先写个链表节点的类 package com.xzlf.collection2; public class Node { int ...
- 《深入理解JAVA虚拟机》笔记1
java程序运行时的内存空间,按照虚拟机规范有下面几项: )程序计数器 指示下条命令执行地址.当然是线程私有,不然线程怎么能并行的起来. 不重要,占内存很小,忽略不计. )方法区 这个名字很让我迷惑. ...
- 【Java】「深入理解Java虚拟机」学习笔记(4)- 类文件结构
我为什么喜欢Java,另一个重要原因就是跨平台,WORA. 程序员是爽了,但肯定有人要为你遮风挡雨,解决WORA的基石就是字节码+虚拟机. ♣Tip 其实这里存在两种无关性,一是平台无关性.另一个是语 ...
- MQTT是IBM开发的一个即时通讯协议,构建于TCP/IP协议上,是物联网IoT的订阅协议,借助消息推送功能,可以更好地实现远程控制
最近一直做物联网方面的开发,以下内容关于使用MQTT过程中遇到问题的记录以及需要掌握的机制原理,主要讲解理论. 背景 MQTT是IBM开发的一个即时通讯协议.MQTT构建于TCP/IP协议上,面向M2 ...
随机推荐
- CentOS GRUB损坏修复方法
前言 博客很久没有更新了,一个原因就是原来存放部署博客的环境坏了,硬盘使用的是SSD,只要读取到某个文件,整个磁盘就直接识别不到了,还好博客环境之前有做备份,最近一直没有把部署环境做下恢复,今天抽空把 ...
- Charles mock数据详解
Charles是一款非常好用的代理工具,关于Charles的安装.破解.安装证书,连接手机代理等使用方法详见我之前的博客:https://www.cnblogs.com/feng0815/p/8043 ...
- Golang 实现 Redis(6): 实现 pipeline 模式的 redis 客户端
本文是使用 golang 实现 redis 系列的第六篇, 将介绍如何实现一个 Pipeline 模式的 Redis 客户端. 本文的完整代码在Github:Godis/redis/client 通常 ...
- 面经分享!蚂蚁金服三面被拒,重拾起鼓四面猿辅导成功拿下offer!
前言 一直有小伙伴要我分享面经,说自己想面互联网公司,无奈经验太少想多看看其他人是怎么面的.我这两天刚好和一个刚拿到猿辅导offer的朋友吃了个饭,他向我说了说自己的面试经历.粉丝朋友是末流211毕业 ...
- 理解Volatile关键字,其实看这一篇就够了,写的非常细致
前言 volatile是Java虚拟机提供的轻量级的同步机制. volatile关键字作用是什么? 两个作用: 1.保证被volatile修饰的共享变量对所有线程总数可见的,也就是当一个线程修改了一个 ...
- 如何用OCR文字识别软件将PDF转换成Excel
最近老板老是让小编处理PDF文件,这OCR识别软件咱也不懂,也不敢问,只能一字一字的码在Excel上,但是这波操作效率不高,还没完成任务,老板又发了一堆PDF文件需要处理,怎么办呢? 跟朋友说了这事后 ...
- FL studio系列教程(十):FL Studio中如何新建样本
FL Studio中强调以样本为核心的编曲模式.样本其实就是一个小的音序片段,可以是单独的乐器或单独的打击乐,还可以是他们组合的一个小音序片段,它是我们学习编曲的最基础知识.所以本文主要为大家讲解的是 ...
- MindManager中主题间距/线条粗细的灵活调整
在MindManager中,主题和线条是思维导图的基本元素,只有通过它们才能将要表达的思想呈现.并联系起来.因此,关于它们的属性设置就会多一点,如颜色.宽度.位置等.而调整主题之间的距离及线条的粗细, ...
- H5系列之drag拖放
H5中, 有个属性,draggable="true", 这个属性呢(默认false),需要加在标签上,加上去该标签就可以拖动了, 看下gif图吧 默认的标签,是不能拖动的,但是有两 ...
- request封装
request封装 import requests class RequestsHandler: def __init__(self): self.session = requests.Session ...