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

本文主要是介绍java基础巩固-宇宙第一AiYWM:为了维持生计,做项目经验之~SSM项目错误集锦Part5(页面好卡呀、反应好慢呀)~整起,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 项目中出现了一些问题:
    • 页面很卡、点个刷新得半天才能出来新页面(虽然我们项目前端使用了Ajax,听他们汇报时说可以实现局部刷新,而不用将整个页面刷新一遍,那肯定效果能好点)
    • 点一个普通的查询按钮,数据量大时会得半天才能把页面上的表格、饼状图、折线图等展示出来
    • 导出大文件时很费时间
  • 优化方式的话:
    • 之前接触到了数据库相关的优化
    • 码农的荒岛求生老师关于Linux 性能分析工具汇总
    • 然后用策略模式优化excel导出的代码
    • 将单体架构变为微服务架构等
    • 但是,从来没有想过,对服务器进行优化(我们的项目用的服务器就是Tomcat,一个Tomcat安装好到Linux系统上,然后项目war扔在里面,你跑吧),今天试试捋一捋思路
  • 服务器性能调优可以从几个角度去出发:
    • 服务器配置选择:
      • 服务器一般是由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

这篇关于java基础巩固-宇宙第一AiYWM:为了维持生计,做项目经验之~SSM项目错误集锦Part5(页面好卡呀、反应好慢呀)~整起的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/334237

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p