4.工具
1.http客户端
1.1.HttpClient
HttpClient 3.x原本是Apache Commons项目下的一个子项目。然而,在2007年,Commons项目独立,并且不再对HttpClient 3.x进行维护。 同年,HttpComponents项目(HttpClient 4.x)也脱离Commons项目,成为Apache的顶级项目,并承担起HttpClient 4.x及后续版本的开发维护工作。
HttpClient 4.x版本是一个从底层重新设计,几乎完全重写的版本,采用模块化的结构,使用更加灵活,性能更好。
httpclient3.1无法正常关闭连接
1.现象
经过测试,apache commns httpclient 3.1,在发送请求后,不会自动关闭连接。导致被调用方的tcp数量不断的累计, 出现大量的 time_wait(根据设置的超时时间,累成的时间不同,如nginx配置了keepalive_timeout=10,则会保持连接10s)。
如果并发过高,不进行关闭的话,应用会linux下运行会出现 too many open files 的错误,导致服务不可用。
2.分析原因
3.1版本的 httpclient ,默认使用了SimpleHttpConnectionManager进行连接管理。但是在我们调用releaseConnection的时候, alwaysClose默认是false,虽然可以使连接复用,但是却导致了连接长期不释放。官方的意思是想让我们复用http连接,避免频繁的进行tcp连接与释放, 但是官方文档没有进行说明,代码案例没有正常使用,导致了目前市面上存在大量的错误使用。

3.解决方案
- 方案1。设置alwaysClose默认是false,如下图所示。
- 方案2。通过在释放连接后,关闭空闲的连接,如下图所示。

3.方案3【推荐】。尽可能升级到新版本的httpclient。新版本支持很多与微服务相关的特性,方便后期改造。并且httpclient3及以下的版本已经被官方舍弃
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
httpclient性能优化
很多时候使用httpclient,都比较粗犷,就是每次请求时初始化一个httpclient,生成一个httpPost对象,执行,然后从返回结果取出entity,保存成一个字符串,最后显式关闭response和client。
优化点如下:
- httpclient。httpclient是一个线程安全的类,可以理解为打开一个浏览器客户端,全局有一个就行,不会有性能问题。
- 反复创建tcp连接的开销。连接复用,采用keep alive的方式实现。
- 重复缓存entity的开销。如下代码,需要将response流中的数据复制一份转为字符串,造成资源浪费。
HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity);方案:使用httpclient4提供了一个 PoolingHttpClientConnectionManager 作为连接池。
1.2.Okio&OkHttp
1.3.RestTemplate
1.4.Feign
本质开始一个httpclient。只不过被spring cloud 封装了下。
1.5.Forest
底层封装了2种不同的http框架:Apache httpClient 和 OKhttp。
开源地址:https://gitee.com/dt_flys/forest
而Forest这个开源项目其定位则是一个高阶的http工具,主打友好和易用性。从使用角度出发, 个人感觉Forest配置性更加简单直接。提供的很多功能也能解决很多人的痛点。
2.其他协议工具
2.1.netty
Netty是一个高性能、异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。它极大地简化了TCP和UDP套接字服务器等网络编程,例如TCP和UDP套接字服务器。
2.1.1.核心组件
Netty的核心组件包括:Channel、EventLoop、ChannelHandler、ChannelFuture、ChannelPipeline。

- Channel:代表一个可以进行读写操作的通道,可以用于网络数据的读写、文件的读写等操作。
- EventLoop:负责处理所有的事件,包括读事件、写事件、连接事件、断开连接事件等。
- ChannelFuture:用于获取异步操作的结果,例如:写操作、连接操作等。
- ChannelHandler:用于处理各种事件,包括读事件、写事件、连接事件、断开连接事件等。
- ChannelPipeline:负责管理各种ChannelHandler,用于处理网络数据的读写、协议解析等操作。
2.1.2.粘包拆包
2.1.3.Netty的线程模型
- Netty的线程模型https://www.jianshu.com/p/6ae30cf5ae9e
- Reactor模式详解+源码实现:https://www.jianshu.com/p/188ef8462100
Netty采用的是基于事件驱动的Reactor模型,用于处理多个I/O源的事件分发。就是"同步非阻塞"IO模型。
Reactor模型有三种线程模式(区别在于事件接受器与事件处理器的线程数量):单线程(一对一)、多线程(一对多)、主从线程(多对多)。
实现原理:Reactor模式主要通过Selector和ChannelHandler来实现。
- Selector用于监听多个Channel的事件(等待epoll的回调事件),当某个Channel上的事件就绪时,Selector会将其放入就绪队列中。
- 然后,Netty的事件循环(EventLoop)会轮询就绪队列中的事件,并调用相应的ChannelHandler进行处理。
- Channel表示程序到某个实体(如硬件设备、文件、网络套接字或者能够执行I/O操作的程序组件)的开放连接,如读操作和写操作。
- ChannelHandler是Netty中处理I/O事件或拦截I/O操作的组件,它负责处理网络事件,如接收数据、写入数据等。开发者可以自定义ChannelHandler来实现自己的业务逻辑。
- ChannelPipeline是ChannelHandler的链表,采用责任链的模型处理Channel中的事件。当某个事件发生时会依次执行所有的ChannelHandler直到找到能够处理该事件的ChannelHandler。
2.1.4.Netty的零拷贝
在 OS 层面上的零拷贝通常指避免在 用户态(User-space) 与内核态(Kernel-space) 之间来回拷贝数据。 而在 Netty 层面 ,零拷贝主要体现在对于数据操作的优化。主要体现在以下几个方面:
- 使用 Netty 提供的 CompositeByteBuf 类, 可以将多个 ByteBuf 合并为一个逻辑上的ByteBuf, 避免了各个 ByteBuf 之间的拷贝。
- ByteBuf 支持 slice 操作, 因此可以将 ByteBuf 分解为多个共享同一个存储区域的ByteBuf, 避免了内存的拷贝。
- 通过 FileRegion 包装的 FileChannel.tranferTo 实现文件传输, 可以直接将文件缓冲区的数据发送到目标 Channel, 避免了传统通过循环 write 方式导致的内存拷贝问题。
2.2.JDK自带工具
网络编程是java擅长的领域。所有jdk提供了很多网络相关的工具。
2.3.Apache Commons net
支持多种通讯协议:
FTP/FTPS
FTP over HTTP (experimental)
NNTP
SMTP(S)
POP3(S)
IMAP(S)
Telnet
TFTP
Finger
Whois
rexec/rcmd/rlogin
Time (rdate) and Daytime
Echo
Discard
NTP/SNTP
3.序列化
只要涉及到通讯协议,就必须进行数据交互,数据就必须进行序列化与反序列化。
- 序列号原理:https://blog.csdn.net/LYJwonderful/article/details/108122360
- 性能对比https://github.com/eishay/jvm-serializers/wiki#test-platform
- 性能对比https://cloud.tencent.com/developer/article/1024786
3.1.Java序列化
对象序列化的目标:将对象保存到磁盘中,或允许在网络中直接传输对象。 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上, 通过网络将这种二进制流传输到另一个网络节点。其他程序一旦获得了这种二进制流,都可以讲这种二进制流恢复成原来的Java对象。
如果需要让某个对象支持序列化机制,则必须让它的类是可序列化的,则这个类必须实现如下两个接口之一:
- Serializable
- Externalizable
对象序列化需要注意:
- 对象的类名、Field都会被序列化; 方法、static Field、transient Field都不会被序列化。
- 实现Serializable接口的类如果需要让某个Field不被序列化,则可以在该Field前添加transient私事符。
- 保证序列化对象的Field类型也是可序列化的。
- 反序列化对象时必须有序列化对象的class文件。
- 当通过文件、网络来读取序列化后的对象时,必须按实际写入的顺序读取。
3.2.JSON
Json是目前使用最为广泛的数据格式,能非常简单的实现数据的跨平台交互。 是非常重要的一种数据格式。 相关的框架也是非常的丰富。 比如json-jdk、Jackson、gson、fastjson等等
3.3.其他
像FST,kryo,hessian、Protostuff等都有各自的序列化机制,甚至通讯协议。
4.抓包工具
4.1.常见工具
- Fiddler:
- 工具非常经典且强大,这点大家应该都所体会。它可以提供电脑端、移动端的抓包、包括 http 协议和 https 协议都可以捕获到报文并进行分析;
- 可以设置断点调试、截取报文进行请求替换和数据篡改,也可以进行请求构造,还可以设置网络丢包和延迟进行 APP 弱网测试等,它有个优势就是免费。
- Charles
- 工具别名 "花瓶",它是通过代理来实现的抓包,也就是我们在访问网页时配置代理指向 Charles 监听的端口,之后所有的请求 Charles 会帮我们转发并记录。
- Charles 的使用非常简单,配置好代理后,Charles 就开始抓包了。我们可以直接通过它的 GUI 查看包的内容。但它是收费的,和 Fiddler 工具很类似,很多 MacOS 用户喜欢用这个软件。
- Wireshark:Wireshark下载安装和使用教程
- Wiresark 是一款超级厉害的抓包工具,是从事网络工程师必用工具,也是一款跨平台的工具,Windows Linux macOS 都可以使用。 它不仅可以分析 http/https 的数据,它还可以分析网络 2 层以上都可以看到,比如 tcp 的三次握手等,但是如果你只是分析 http 协议,可以不用这么专业的工具,以免增加筛选请求成本和学习成本。
- tcpdump
- tcpdump 是 Linux 下常用的抓包工具,它是一个命令行工具,可以抓取和 Wireshark 类似的数据,而且保存的数据包,可以放到 Wireshark 中分析。如果你的 Linux 服务器需要抓包分析问题,它是一个非常好的选择。
- Hping - 是最受欢迎和免费的抓包工具之一。它允许你修改和发送自定义的 ICMP,UDP,TCP 和原始 IP 数据包。 - 此工具由网络管理员用于防火墙和网络的安全审计和测试。HPing 可用于各种平台,包括 Windows,MacOs X,Linux,FreeBSD,NetBSD,OpenBSD 和 Solaris。
- Ostinato - 是一个开源和跨平台网络包生成器和分析工具。它带有 GUI 界面,使其易于使用和理解。它支持 Windows,Linux,BSD 和 Mac OS X 平台。
- BurpSuite
- Burpsuite 工具也是基于 Java 语言开发的,所以它也可以跨各平台使用,包括 Windows,MacOS 及 Linux 等系统平台。
- Burpsuite 可以提供抓包功能,它的工作方式同样也是在浏览器和网站之间做了代理从而实现报文截取的;也能够修改数据内容并转发的功能;
- 甚至还可以选择使用爬虫爬下网站相关的数据。但是,它绝对不仅仅是一款抓包工具,它集成了很多实用的小工具可以完成更加强大的功能,
- 比如 http 请求的转发、修改、扫描等。同时这些小工具之间还可以互相协作,在 BurpSuite 这个框架下进行订制的攻击和扫描方案。
- 所以这个工具很多功能测试的人员会使用它进行报文抓取和篡改数据,很多安全测试人员会借用它进行半自动的网络安全审计,开发人员也可以使用它的扫描工具进行网站压力测试与攻击测试,功能作用范围更加广泛。
- F12
- 是众多抓包工具中最简单、最轻量级的,因为它是浏览器内置的开发者工具来提供捕获浏览器的数据报文的功能。它免安装,直接打开浏览器就可以直接使用,
- 所有使用非常好上手,适合入门级别的新手学习。它主要针对的是 HTTP 协议和 HTTPS 协议, 可以确认我们的网络数据包的一个状态, 通过分析请求和响应报文里面的内容,
- 分析出来请求数据和响应数据是否正确, 定位问题是前端问题还是后端问题。而且 F12 作为浏览器的一部分,是数据收发的一端,抓取到的 HTTPs 报文是可以得到明文数据的;
- 不过因为只能抓当前浏览器的收发报文,层次只能是在应用层 Http (s) 协议,不能抓取其他的数据报文。
- WireEdit
- WireEdit 是一个功能齐全的 WYSIWYG 网络数据包编辑器。你可以在一个简单的界面中编辑所有的数据包层。这个工具是免费使用的,但你必须联系公司获得使用权。
- 它支持 Ethernet, IPv4, IPv6, UDP, TCP, SCTP, ARP, RARP, DHCP, DHCPv6, ICMP, ICMPv6, IGMP, DNS, LLDP, RSVP, FTP, NETBIOS, GRE, IMAP,
- POP3, RTCP, RTP, SSH, TELNET, NTP, LDAP, XMPP, VLAN, VXLAN, CIFS/SMB v1 (original), BGP, OSPF, SMB3, iSCSI, SCSI, HTTP/1.1,
- OpenFlow 1.0-1.3, SIP, SDP, MSRP, MGCP, MEGACO (H.248), H.245, H.323, CISCO Skinny, Q.931/H.225, SCCP, SCMG, SS7 ISUP, TCAP,
- GSM MAP R4, GSM SM-TP, M3UA, M2UA, M2PA, CAPWAP, IEEE 802.11 等。它也是一个多平台工具。它适用于 Windows XP 和更高版本,Ubuntu 桌面和 Mac OSX。
4.2.底层工具
WinPcap 和 libpcap 。这两个是很多windows和Linux抓包的底层依赖。
4.3.tcpdump
Linux 常用的抓包工具,也用于进行流量回放,Linux系统一般都默认安装。只有命令行,图形化分析需要借助Wireshark展示。
- 本文作者:zhangxue
- 本文链接:https://lucksnow1989.github.io/article/4.网络&通讯协议/4.工具.html
- 版权声明:本文为本人原创文章,遵循 CC 4.0 BY-NC-SA版权协议,转载请附上原文出处链接和本声明。