java基础巩固-宇宙第一AiYWM:为了维持生计,做项目经验之~SSM项目错误集锦Part5(页面好卡呀、反应好慢呀)~整起

  • 项目中出现了一些问题:
    • 页面很卡、点个刷新得半天才能出来新页面(虽然我们项目前端使用了Ajax,听他们汇报时说可以实现局部刷新,而不用将整个页面刷新一遍,那肯定效果能好点)
    • 点一个普通的查询按钮,数据量大时会得半天才能把页面上的表格、饼状图、折线图等展示出来
    • 导出大文件时很费时间
  • 优化方式的话:
  • 服务器性能调优可以从几个角度去出发:
    • 服务器配置选择:
      • 服务器一般是由CPU、内存、磁盘和网卡组成,因此选择 服务器配置就是选择CPU核数、内存大小、磁盘大小及类型、网络带宽,因为软件的最终运行性能与软件的实现方式是紧密相关的,即使是同一个后端应用程序中的两个接口,由于具体功能的差别,性能也会有所差别,所以其实咱们是没有办法知道一台需要达到1000000TPS的后端服务器的配置应该是什么样子的!因此,服务器配置的选择应该基于具体的测试结果【一开始可以选用配置较低的服务器做调优和测试,并以该服务器的测试结果作为选择服务器的依据】
        • 举个例子,但是,还是那句话,例子毕竟是例子,需要具体问题具体分析
          在这里插入图片描述
    • 服务器负载分析:
      • 对服务器负载进行分析时,主要分析CPU使用率、内存使用率、磁盘I/O,服务器负载和带宽使用情况
      • CPU使用率:CPU使用率反应的是CPU的忙碌情况
        • 在实际情况下,为了应对一下突发性的请求压力,服务器CPU使用率一般需要在75%以下。如果一台服务器的CPU使用率多次高于75%,这时候就考虑增加新的服务器
        • htop工具【yum install htop -y,安装完成后我们就可以通过htop命令观察CPU负载了】可以非常直观看到CPU使用率、内存使用率、及负载等信息
          • 输入htop命令后我们可以很直观的看到CPU负载情况,该命令的CPU使用率会以多个核作为单位进行显示。操作系统机会自动分配多个核的负载,当所有核的CPU使用率都超过75%时才能认为服务器的CPU使用率已经超过75%。
      • 内存使用率:内存用于存放程序的代码及数据,一般分为物理内存和虚拟内存,其中物理内存指的是服务器的内存,而虚拟内存指的是硬盘的一块空间【当物理内存使用率达到100%时将会使用虚拟内存】
        • 虚拟内存的读写速度远远低于物理内存,如果程序被放在了虚拟内存执行,那么程序的执行效率会变得很低。一般而言,服务器的物理内存应该保持在80%以下,虚拟内存使用率保持在0%
        • 可以通过hop工具进行查看服务器内存使用情况
      • 磁盘I/O:磁盘I/O指的是磁盘的读写
        • 可以使用iostat工具【yum install sysstat -y,安装完成后我们就可以通过iostat命令磁盘使用情况了。】来实现磁盘监控,查看磁盘的使用情况
          在这里插入图片描述
      • 平均负载:指的是 单位时间内平均的活跃进程数,是一个表示服务器负载的指标。
        • 一般情况下需要保证平均负载的值小于当前服务器的CPU核数
        • 可以使用htop命令查看服务器平均负载。一般情况下服务器的平均负载需要小于当前服务器的CPU核数,为了应对突发状况,服务器的平均负载应该在75%即3 以下
      • 网络使用情况:当带宽不足时会大大增加请求的响应时间。为了防止突发性并发压力,应该保证服务器的带宽使用率在80%以上,物理网卡限制了服务器所能使用的最大宽带
        • 可以使用nload工具【yum install nload -y,网络使用情况分为流入网卡的数据与流出网卡的数据。流入网卡的对应下行带宽的网速,流出网卡的数据对应上行带宽的网速。如果 “当前网速” 持续接近 “最大网速” 时,代表带宽使用率已经接近100%】查看网路使用情况
    • 服务器内核参数调优。
      • 并不是所有的服务器都需要做高并发性能调优一般来说,只需要对要处理高并发请求的服务器进行内核参数调优即可,常见的包括:前端服务器,后端服务器,数据库服务器。
      • 服务器常见的调优参数主要有两个:
        • 单个进程最大打开文件数:修改单个文件最大打开文件数,只需要编辑/etc/security/limits.conf文件
          在这里插入图片描述
        • TCP相关设置:修改TCP相关参数,可以优化TCP高并发通信,编辑/etc/sysctl.conf文件
          # 为防止洪水攻击,高并发系统需要将此项关闭
          net.ipv4.tcp_syncookies = 0
          
          # 开启TCP连接重用,允许处理TIME-WAIT状态的连接重新用于新的TCP连接
          net.ipv4.tcp_tw_reuse = 1
          
          # 开启快速回收TCP连接中处于TIME-WAIT状态的连接
          net.ipv4.tcp_tw_recycle = 1
          
          #修改超时时间( s ),该值表示如果连接由本端关闭,则连接处于 FIN-WAIT-2状态的时间为 
          net.ipv4.tcp_fin_timeout = 30
          
          #当 keepalive(长连接)启用的时候,TCP发送 keepalive 消息(探测包)的时间间隔( s ),默认为2个小时
          net.ipv4.tcp_keepalive_time =1200
          
          #服务器对外连接的端口范围,影响该服务器与其他服务器的连接数
          net.ipv4.ip_local_port_range =102465535
          
          #SYN队列的长度,可以容纳更多等待连接的网络连接数,默认为1024 
          net.ipv4.tcp_max_syn_backlog = 65535
          
          #保持 TIME_WAIT 状态连接的最大数量,如果超过此值,TIME_WAIT 将立刻被清除并打印警告信息,默认为180000
          net.ipv4.tcp_max_tw_buckets =5000
          
          #每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目
          net.core.netdev_max_backlog =65535
          
          # TCP最大连接数
          net.core.somaxconn = 65535
          
          #预留用于接收缓冲的内存默认值(字节) 
          net.core.rmem_default = 8388608
          
          #预留用于接收缓冲的内存最大值(字节) 
          net.core.rmem_max = 16777216
          
          #预留用于发送缓冲的内存默认值(字节) 
          net.core.wmem_default = 8388608
          
          #预留用于发送缓冲的内存最大值(字节) 
          net.core.wmem_maX = 16777216
          
          #避免时间戳异常
          net.ipv4.tcp_timestamps = 0
          
          #系统中最多有多少个 TCP 套接字不被关联到任何一个用户文件句柄上,如果超过这个数字,连接将即刻被复位并打印警告信息,这个限制仅仅是为了防止简单的DoS 攻击
          net.ipv4.tcp_max_orphans =3276800
          
    • 数据复制:
      • 如果应用程序不关心数据的内容,就没有必要将数据拷贝到应用缓冲区,可以借助内核接口直接将数据拷贝到内核缓冲区处理,如在提供文件下载服务时,不需要将文件内容先读到应用缓冲区,在调用send接口发送出去,可以直接使用sendfile (零拷贝)接口直接发送出去。
        在这里插入图片描述
    • 资源池:资源池是一个抽象的概念,常见的包括进程池、线程池、 内存池、连接池
      • 在服务运行期间,需要使用系统调用为用户分配资源,通常系统资源的分配都是比较耗时的,如动态创建进程/线程。可以考虑在服务启动时预先分配资源,即创建资源池,当需要资源,从资源池中获取即可,若资源池不够用时,再动态的分配,使用完成后交还到资源池中。这实际上是用空间换取时间,在服务运行期间可以节省非必要的资源创建过程。需要注意的是,使用资源池还需要根据业务和硬件环境对资源池的大小进行限制
    • 锁/上下文切换:
      • 对共享资源的操作是并发程序中经常被提起的一个话题,都知道在业务逻辑上无法保证同步操作共享资源时,需要对共享资源加锁保护,但是锁不仅不能处理任何业务逻辑,而且还存在一定的系统开销。并且对锁的不恰当使用,可能成为服务期性能的瓶颈
        • 如果能够在设计层面避免共享资源竞争,就可以避免锁
        • 若无法避免对共享资源的竞争,优先考虑使用无锁队列的方式实现共享资源
        • 使用锁时,优先考虑使用读写锁;此外,锁的范围也要考虑,尽量较少锁的颗粒度,避免其他线程无谓的等待。
      • 并发程序需要考虑上下文切换的问题,内核调度线程(进程)执行是存在系统开销的,若线程(进程)调度占用CPU的时间比重过大,那处理业务逻辑占用的CPU时间就会不足。在项目中,线程(进程)数量越多,上下文切换会很频繁,因此是 不建议为每个用户连接创建一个线程,并发模式,一个线程可同时处理多个用户连接,是比较合理的解决方案
        • 多核的机器上,并发程序的不同线程可以运行在不同的CPU上,只要线程数量不大于CPU数目,上下文切换不会有什么问题,在实际的并发网络模块中,线程(进程)的个数也是根据CPU数目来确定的。在多核机器上,可以设置CPU亲和性,将进程/线程与CPU绑定,提高CPU cache的命中率,建好内存访问损耗
    • 有限状态机器:
      • 最典型的是内核协议栈中TCP状态转移有限状态机中每种类型对应执行逻辑单元的状态,对逻辑事务的处理非常有效。
      • 有限状态机包括两种,
        • 一种是每个状态都是相互独立的,状态间不存在转移;
          在这里插入图片描述
        • 另一种就是状态间存在转移。
          在这里插入图片描述
    • 时间轮:经常会面临一些业务定时超时的需求。比如:功能需求:服务器需要维护来自大量客户端的TCP连接(假设单机服务器需要支持的最大TCP连接数在10W级别),如果某连接上60s内没有数据到达,就认为相应的客户端下线。
      • 解决方案如下:
        • 方案a :轮询扫描
          在这里插入图片描述
        • 方案b:多定时器触发
          在这里插入图片描述
        • 方案c:时间轮方案
          在这里插入图片描述
          在这里插入图片描述
          • 与a、b两种方案相比,方案c具有如下优势:
            在这里插入图片描述

巨人的肩膀:
高性能mysql
mysql技术内幕
月伴飞鱼
mysql中文文档
码哥字节
macrozheng

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值