编写版本:v3.3.7
适用版本:所有版本

基本解决方案

  1. 调整JVM参数,增大内存、调整新生代内存比例等;如:-XX:SurvivorRatio=8 -Xmx4g -Xms4g -Xmn1536m -Xss300kJVM参数说明

  2. 将应用日志输出级别调整为warn或以上级别,项目中的log4j2.yml文件中修改相关配置;

  3. application.yml文件中添加authorization.permission-filter-enable: false,关闭接口权限校验,减少请求处理时间;此处只是关闭接口权限,并不是关闭令牌校验,访问系统还是需要令牌的关闭该参数风险:会出现越权问题

  4. 业务表(由业务对象创建的数据表)自行添加关键索引;

  5. 前端启用多域名访问,多域名方案3.3.3+新增功能

  6. application.yml文件中添加authorization.log-api-invoke.enable: false,关闭接口日志记录,减少数据库压力;3.3.7+新增功能

  7. Web容器参数调优

    • Undertow
      • UNDERTOW_IO_THREADS=20 #与服务器CPU线程数一致
      • UNDERTOW_WORKER_THREADS=256 #可以根据机器情况增大
      • UNDERTOW_BUFFER_SIZE=1024
      • UNDERTOW_DIRECT_BUFFERS=true
  8. 数据库服务器磁盘使用SSD固态硬盘,经测试发现使用SSD固态硬盘可以提升5~10倍性能;

  9. MySQL5.7参数优化

     [client]
     default-character-set = utf8
     [mysqld]
     port = 3306
     default-storage-engine = INNODB
     character-set-server = utf8
     collation-server = utf8_general_ci
     max_connections = 1024
     max_allowed_packet = 1024M #影响大SQL执行,仅供参考
     lower_case_table_names = 1
     innodb_buffer_pool_size = 50G #影响性能,仅供参考
     join_buffer_size = 256M #影响性能,仅供参考
     read_rnd_buffer_size = 16M #影响性能,仅供参考
     sort_buffer_size = 16M #影响性能,仅供参考
    
     innodb_read_io_threads = 10 #影响性能,仅供参考
     innodb_write_io_threads = 10 #影响性能,仅供参考
    
     query_cache_type = 1 #影响性能,仅供参考
     query_cache_size = 10G #影响性能,仅供参考
    
     #sata/sas硬盘这个值在200
     #sas raid10: 2000
     #ssd硬盘:8000
     #fusion-io(闪存卡):25,000-50,000
     innodb_io_capacity=2000
     innodb_io_capacity_max=4000
    
     sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
  10. MySQL8.0参数优化

     [client]
     default-character-set = utf8
     [mysqld]
     port = 3306
     default-storage-engine = INNODB
     character-set-server = utf8
     collation-server = utf8_bin
     max_connections = 1024
     max_allowed_packet = 64M
     lower_case_table_names = 1
     innodb_buffer_pool_size = 30G
     innodb_buffer_pool_instances = 10
     join_buffer_size = 256M
     read_rnd_buffer_size = 16M
     read_buffer_size = 16M
     sort_buffer_size = 16M
     open_files_limit = 65535
     innodb_read_io_threads = 20
     innodb_write_io_threads = 16
     innodb_thread_concurrency = 0
     innodb_flush_log_at_trx_commit = 2
     binlog_format = mixed
     tmp_table_size = 256M
     max_heap_table_size = 256M
     thread_cache_size = 64
     disable-log-bin
     log_slave_updates = 0
     sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
     datadir=/var/lib/mysql
     socket=/var/lib/mysql/mysql.sock
     symbolic-links=0
     pid-file=/var/run/mysqld/mysqld.pid
  11. 使用Spring-jdbc NamedParameterJdbcTemplate和mysql-connector-java,并且我在几乎每一个时间都会发出大量的“额外”SQL声明全部看起来像”SHOW FULL COLUMNS FROM …”

    • 在数据库链接后面添加参数useDynamicCharsetInfo=false
    • 例:jdbc:mysql://192.168.3.240:3306/ibps_business_v3_optimize_05?useDynamicCharsetInfo=false&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=CTT
  12. 遵循分布式应用方式部署

    • 每个应用都独立部署,将IO分摊到不同机器;
    • 特别是数据库的IO瓶颈问题,将不同数据库都独立服务器部署,将IO分摊到不同机器;
  13. linux系统修改open files参数

    1. ulimit -a查看open files的值是多少
    2. vi /etc/security/limits.conf
      添加以下内容
       * soft nofile 65535
       * hard nofile 524288
    3. 重新登陆会话即可使其生效
  14. linux系统内核优化CentOS为例完整

    vi /etc/sysctl.conf

      # 其值为0时表示禁止进行IP转发;如果是1,则说明IP转发功能已经打开。
      net.ipv4.ip_forward = 0 #如何值为0出现ip无法连接,则改为1
      net.ipv4.conf.all.send_redirects = 0
      net.ipv4.conf.default.send_redirects = 0
      # 确保无人能修改路由表
      net.ipv4.conf.all.accept_redirects = 0
      net.ipv4.conf.default.accept_redirects = 0
      net.ipv4.conf.all.secure_redirects = 0
      net.ipv4.conf.default.secure_redirects = 0
      #处理无源路由的包
      net.ipv4.conf.all.accept_source_route = 0
      net.ipv4.conf.default.accept_source_route = 0
      # 启用源路由核查功能/反向路径过滤
      net.ipv4.conf.all.rp_filter = 1
      net.ipv4.conf.default.rp_filter = 1
      # 关闭组合键了解系统运行状态功能
      kernel.sysrq = 0
      # 控制core文件的文件名是否添加pid作为扩展
      kernel.core_uses_pid = 1
      #开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理
      net.ipv4.tcp_syncookies = 1
      #每个消息队列的大小(单位:字节)限制
      kernel.msgmnb = 65536
      #整个系统最大消息队列数量限制
      kernel.msgmax = 65536
      #单个共享内存段的大小(单位:字节)限制,计算公式64G*1024*1024*1024(字节)
      kernel.shmmax = 68719476736
      #所有内存大小(单位:页,1页 = 4Kb),计算公式16G*1024*1024*1024/4KB(页)
      kernel.shmall = 4294967296
      #timewait的数量,默认是180000
      net.ipv4.tcp_max_tw_buckets = 6000
      #开启有选择的应答
      net.ipv4.tcp_sack = 1
      #支持更大的TCP窗口. 如果TCP窗口最大超过65535(64K), 必须设置该数值为1
      net.ipv4.tcp_window_scaling = 1
      #TCP读buffer
      net.ipv4.tcp_rmem = 4096        87380   4194304
      #TCP写buffer
      net.ipv4.tcp_wmem = 4096        16384   4194304
      #为TCP socket预留用于发送缓冲的内存默认值(单位:字节)
      net.core.wmem_default = 8388608
      #为TCP socket预留用于发送缓冲的内存最大值(单位:字节)
      net.core.wmem_max = 16777216
      #为TCP socket预留用于接收缓冲的内存默认值(单位:字节)  
      net.core.rmem_default = 8388608
      #为TCP socket预留用于发送缓冲的内存最大值(单位:字节)
      net.core.rmem_max = 16777216
      #每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目
      net.core.netdev_max_backlog = 262144
      #系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)
      net.core.somaxconn = 262144
      #系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)
      net.ipv4.tcp_max_orphans = 3276800
      #记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128
      net.ipv4.tcp_max_syn_backlog = 262144
      #时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉
      net.ipv4.tcp_timestamps = 0
      #为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量
      net.ipv4.tcp_synack_retries = 1
      #在内核放弃建立连接之前发送SYN包的数量
      net.ipv4.tcp_syn_retries = 1
      #开启TCP连接中time_wait sockets的快速回收
      net.ipv4.tcp_tw_recycle = 1
      #开启TCP连接复用功能,允许将time_wait sockets重新用于新的TCP连接(主要针对time_wait连接)
      net.ipv4.tcp_tw_reuse = 1
      #1st低于此值,TCP没有内存压力,2nd进入内存压力阶段,3rdTCP拒绝分配socket(单位:内存页)
      net.ipv4.tcp_mem = 94500000 915000000 927000000
      #如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60 秒。2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。
      net.ipv4.tcp_fin_timeout = 1
      #表示当keepalive起用的时候,TCP发送keepalive消息的频度(单位:秒)
      net.ipv4.tcp_keepalive_time = 30
      #对外连接端口范围
      net.ipv4.ip_local_port_range = 1024    65000
      #表示文件句柄的最大数量
      fs.file-max = 102400
      # 允许更多的PIDs (减少滚动翻转问题); may break some programs 32768
      kernel.pid_max = 1000000
      # 最大监听文件数
      fs.inotify.max_user_watches = 524288
      #修改防火墙表大小,默认65536
      net.netfilter.nf_conntrack_max = 655350
      net.netfilter.nf_conntrack_tcp_timeout_established = 1200

    执行命令 sysctl -p 使其生效

  15. 高并发场景下一级缓存会造成FullGC频繁,可以选择禁用一级缓存,但会给二级缓存造成更大压力(可以提供redis性能来弥补),不一定能提升性能(慎重,已知影响:流程接口性能会下降) 3.4.0+

  16. Oauth2服务开启本地缓存com.lc.context.user.enabled: ${CONTEXT_USER_ENABLED:true}3.4.0+新增功能

  17. Platform服务开启本地缓存com.lc.context.party.enabled: ${CONTEXT_PARTY_ENABLED:true}3.4.0+新增功能

  18. Platform服务开启J2cache二次缓存3.4.0+新增功能

    com.lc.context.dictionary.enabled: ${CONTEXT_DICTIONARY_ENABLED:true}
    com.lc.context.role.resources.enabled: ${CONTEXT_ROLE_RESOURCES_ENABLED:true}
  19. Business服务开启J2cache二次缓存com.lc.context.datatemplate.data.builder.enabled: ${CONTEXT_DATATEMPLATE_DATA_BUILDER_ENABLED:true}3.4.0+新增功能

  20. 开启缓存初始化加载器,http://doc.bpmhome.cn/docs/ibps_v3_deploy/ibps_v3_deploy-1dcjge03iaqdu 3.4.4+新增功能

  21. 二次缓存配置cache.short.enabled: ${CACHE_SHORT_ENABLED:true} 3.5.0+新增功能

  22. 修改文件application-common.yml中的配置aop.method.signature.open: false 3.5.0+新增功能

  23. 开启web容器的gzip压缩功能,在文件application-common.yml中的配置server.compression.enabled: true 3.5.2+新增功能<适用所有版本>

  24. 开启nginx的gzip压缩功能,生产部署Nginx3.5.2+新增功能<适用所有版本>

    http {
     # 开启GZIP
     gzip  on;
     gzip_min_length  1k;
     gzip_buffers     4 16k;
     gzip_http_version 1.1;
     gzip_comp_level 9;
     gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
     gzip_disable "MSIE [1-6]\.";
     gzip_vary on;
    }
  25. 后端服务使用HikariCP连接池,相关配置在application-common.yml文件中; 3.5.2+新增功能

    com.lc.db.datasources.druid-enabled: ${DATASOURCES_DRUID_ENABLED:false}
    com.lc.db.datasources.hikari-enabled: ${DATASOURCES_HIKARI_ENABLED:true}
  26. mysql判断为空不为空的表达式优化

    TASK_ID_ is null #效率较低
    length(TASK_ID_) is null #效率较高,建议使用这种方式判断
    TASK_ID_ is not null #效率较低
    length(TASK_ID_) is not null #效率较高,建议使用这种方式判断
  27. 远程服务调用合并,将同一个资源的多次请求合并成一次,需要全面分析代码。

文档更新时间: 2024-01-09 12:45   作者:Eddy