• 服务端优化-连接性能,io模型,web容器


    1.写在前面

    在上一篇文章中,我们分享了服务端调优-tomcat方向的调优。

    分享了,如何对内嵌tomcat的配置进行调优等内容。

    具体的详情可以查看: # 服务端优化-Tomcat调优

    那我们还可以从哪些方面进行调优呢?

    我们这里还可以从以下这几个方面进行调优:

    • Web连接性能调优
    • 网络IO模型调优
    • Web容器调优

    那就废话不多说了,直接上正菜吧:

    2.Web连接性能调优

    2.1什么是长连接?

    HTTP 持久连接(Keep-Alive)也叫做长连接,它是一种 TCP 的连接方式,连接会被浏览器和服务器所缓存,在下次连接同一服务器时,缓存的连接被重新使用。

    由于 HTTP 是无状态的,“一次性”通信模式。所以持久连接,可以减少创建连接的开销,提高性能!

    长连接是服务端与客户端协作的技术:浏览器在请求的头部添加 Connection:Keep-Alive,以此告诉服务器“我支持长连接,你支持的话就和我建立长连接吧”,而倘若服务器的确支持长连接,那么就在响应头部添加“Connection:Keep-Alive”,从而告诉浏览器“我的确也支持,那我们建立长连接吧”。

    服务器还可以通过 Keep-Alive:timeout=10, max=100 的头部告诉浏览器“我希望 10 秒算超时时间,最长不能超过 100 秒”。HTTP/1.1 支持长连接,大部分浏览器和服务器也提供了长连接的支持。

    可以想象,要想发起长连接,服务器和浏览器必须共同合作才可以。一方面浏览器要保持连接,另一方面服务器也不会断开连接。也就是说要想建立长连接,服务器和浏览器需要进行协商,而如何协商就要靠伟大的 HTTP 协议了。

    在 Tomcat 里允许配置 Connector 【Acceptor】节点,也就是配置长连接。与长连接直接相关的有两个属性分别是:

    • keepAliveTimeout: 表示在下次请求过来之前,tomcat保持该连接多久 ,默认值20s
      • 假如客户端不断有请求过来,且为超过过期时间,则该连接将一直保持。
    • maxKeepAliveRequests: 表示该连接最大支持的请求数 ,默认值 100
      • 超过该请求数的连接也将被关闭(现象是返回Connection: close头给客户端)
      • 设置为 0 ,Keep Alive 的最大请求数将没有限制。

    在 Tomcat 里默认长连接是打开的,想关闭长连接时只要将 maxKeepAliveRequests 设置为 1 就可以。频繁创建和销毁连接,会影响系统性能。因此我们需要改造web服务,提升web服务的长连接的性能。

    1. /*
    2. * @Author llsydn
    3. * 注意:
    4. * SpringBoot默认使用的是NIO模型
    5. * keepalive参数调优,在application.properties配置文件内不支持修改keepalive!
    6. **/
    7. @Configuration
    8. public class TomcatConfig {
    9. //自定义SpringBoot嵌入式Tomcat
    10. @Bean
    11. public TomcatServletWebServerFactory servletContainer() {
    12. TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {};
    13. tomcat.addAdditionalTomcatConnectors(http11NioConnector());
    14. return tomcat;
    15. }
    16. //配置keepAlive
    17. public Connector http11NioConnector() {
    18. Connector connector=new Connector("org.apache.coyote.http11.Http11NioProtocol");
    19. Http11NioProtocol nioProtocol = (Http11NioProtocol)connector.getProtocolHandler();
    20. //等待队列最多允许 1000 个线程在队列中等待
    21. nioProtocol.setAcceptCount(1000);
    22. // 设置最大线程数
    23. nioProtocol.setMaxThreads(1000);
    24. // 设置最大连接数
    25. nioProtocol.setMaxConnections(20000);
    26. //定制化keepalivetimeout,设置 30 秒内没有请求则服务端自动断开keepalive链接
    27. //默认是20s
    28. nioProtocol.setKeepAliveTimeout(30000);
    29. //当客户端发送超过 10000 个请求则自动断开keepalive链接
    30. //默认 100 个
    31. nioProtocol.setMaxKeepAliveRequests(10000);
    32. // 请求方式
    33. connector.setScheme("http");
    34. connector.setPort(9002); //自定义的
    35. connector.setRedirectPort(8443);
    36. return connector;
    37. }
    38. }
    1. // 监控ESTABLISHED,TIME_WAIT 线程的数量
    2. netstat -n | awk '/^tcp/ {++y[$NF]} END {for(w in y) print w, y[w]}'
    3. //查看网络连接数:
    4. netstat -an |wc -l
    5. netstat -an |grep xx |wc -l // 查看某个/特定PID的连接数
    6. netstat -an |grep TIME_WAIT |wc -l // 查看连接数等待time_wait状态连接数
    7. netstat -an |grep ESTABLISHED |wc -l // 查看建立稳定连接数量
    8. //常用的三个状态是:
    9. ESTABLISHED 表示正在通信,
    10. TIME_WAIT 表示主动关闭,
    11. CLOSE_WAIT 表示被动关

    不使用长连接:连接频繁被关闭,浪费系统资源

    使用长连接:连接长期持有,性能相对于不使用长连接要好

    3.网络IO模型调优

    Java的NIO【new io】是从Java 1.4版本开始引入的一套新的IO API用于替代标准的Java IO API。

    众所周知文件读写【io】性能,影响应用程序性能是的关键因素之一。也就是所谓的input输入流和Output输出流。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。

    JDK 7之后Java对NIO再次进行了极大的扩展,增强了对文件处理和文件系统特性的支持。我们称之为AIO也叫NIO2。

    使用nio2的http协议对请求进行改写。发现服务响应时间大幅缩短

    1. /*
    2. * @Author llsydn
    3. **/
    4. @Configuration
    5. public class TomcatConfig {
    6. //自定义SpringBoot嵌入式Tomcat
    7. @Bean
    8. public TomcatServletWebServerFactory servletContainer() {
    9. TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {};
    10. tomcat.addAdditionalTomcatConnectors(http11Nio2Connector());
    11. return tomcat;
    12. }
    13. //配置连接器nio
    14. public Connector http11Nio2Connector() {
    15. Connector connector=new Connector("org.apache.coyote.http11.Http11Nio2Protocol");
    16. Http11Nio2Protocol nio2Protocol = (Http11Nio2Protocol) connector.getProtocolHandler();
    17. //等待队列最多允许 1000 个线程在队列中等待
    18. nio2Protocol.setAcceptCount(1000);
    19. // 设置最大线程数
    20. nio2Protocol.setMaxThreads(1000);
    21. // 设置最大连接数
    22. nio2Protocol.setMaxConnections(20000);
    23. //定制化keepalivetimeout,设置 30 秒内没有请求则服务端自动断开keepalive链接
    24. nio2Protocol.setKeepAliveTimeout(30000);
    25. //当客户端发送超过 10000 个请求则自动断开keepalive链接
    26. nio2Protocol.setMaxKeepAliveRequests(10000);
    27. // 请求方式
    28. connector.setScheme("http");
    29. connector.setPort(9003); //自定义的
    30. connector.setRedirectPort(8443);
    31. return connector;
    32. }
    33. }

    调优前:

    调优后:

    4.Web容器调优:切换undertow

    SpringBoot的web环境中默认使用tomcat作为内置服务器,其实SpringBoot提供了另外 2 中内置服务器 供我们选择,我们可以很方便的进行切换。

    • Undertow红帽公司开发的一款 基于 NIO 的高性能 Web 嵌入式服务器 。轻量级Servlet服务器,比Tomcat更轻量级没有可视化操作界面,没有其他的jsp类似功能,只专注于服务器部署,因此undertow服务器性能略好于Tomcat服务器;

    • Jetty开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。

    配置操作过程:

    1. 在spring-boot-starter-web排除tomcat
    1. org.springframework.boot
    2. spring-boot-starter-web
    3. org.springframework.boot
    4. spring-boot-starter-tomcat
    1. 导入其他容器的starter
    1. org.springframework.boot
    2. spring-boot-starter-undertow
    1. 配置
    1. # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接
    2. server.undertow.threads.io= 1000
    3. # 阻塞任务线程池, 当执行类似servlet请求阻塞IO操作, undertow会从这个线程池中取得线程
    4. # 默认值是IO线程数*8
    5. server.undertow.threads.worker= 8000
    6. # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
    7. # 每块buffer的空间大小,越小的空间被利用越充分,不要设置太大,以免影响其他应用,合适即可
    8. server.undertow.buffer-size=1024
    9. # 每个区分配的buffer数量 , 所以pool的大小是buffer-size * buffers-per-region
    10. # 是否分配的直接内存(NIO直接分配的堆外内存)
    11. server.undertow.direct-buffers= true

    好了,以上就是 服务端优化-连接性能,io模型,web容器 的分享了。

    个人得实操,可能也有些不足,大家轻点喷!!!

    个人理解,也可能不够全面,班门弄斧了。

    如果觉得有收获的,帮忙 点赞、评论、收藏 一下呗!!!

  • 相关阅读:
    我今年50岁了,还在干前端
    【Effective Objective - C】—— block 块
    护眼灯真的可以护眼吗?2022护眼台灯该怎样选择
    CPDA|对招聘HR来说,会数据分析有多香?
    机器视觉 opencv 深度学习 驾驶人脸疲劳检测系统 -python 计算机竞赛
    论文回顾:Playful Palette: An Interactive Parametric Color Mixer for Artists
    施工小能手路边石混凝土成型机的工艺原理
    【MATLAB】 小波分解信号分解+FFT傅里叶频谱变换组合算法
    nohup安装和用法
    攻防世界maze做法(迷宫题)
  • 原文地址:https://blog.csdn.net/Q54665642ljf/article/details/126343251