欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

如何防止访问量过大导致mysql数据库挂掉了

程序员文章站 2022-11-02 09:06:24
如何防止访问量过大导致mysql数据库挂掉了,不合理的地方在于MaxClients和MaxRequestsPerChild。 MaxClients指定的是可以启动的APACHE进程数量上限,...

如何防止访问量过大导致mysql数据库挂掉了,不合理的地方在于MaxClients和MaxRequestsPerChild。

MaxClients指定的是可以启动的APACHE进程数量上限,对于小内存的主机,这个设置(1024个)很容易把内存用光。
MaxRequestsPerChild指定的是每个APACHE进程可以处理的最多请求次数,达到次数之后这个进程就会退出,然后重新开启新的进程。这一点的意义在于,进程会出现内存泄露的问题,就是进程使用的内存会越来越多,越来越多,越来越多,越来越多,无法释放。设置MaxRequestsPerChild后,进程重启动则可以解决。而WDCP中设置的为0,0的意思为,永不退出。

prefork调优,修改为

ServerLimit 128

StartServers 5

MinSpareServers 5

MaxSpareServers 6

MaxClients 128

MaxRequestsPerChild 1000

最大空闲子进程数就是TIME_WAIT的数量,最多可以变成30个TIME_WAIT

修改完成后,保存

百度一下很长知识: http://www.mianfeidianhua.net/wdcp-neicunyouhua.html

1,StartServers 服务器启动时建立的HTTPD进程数量,这个应该属于父进程

2,MinSpareServers 最小HTTPD空闲进程数量,这个虽然是空闲的父进程,但是它是有作用的,它的存在能够减少请求突然到来时,HTTPD进程数量不够,产生新的HTTPD进程的时间。

3,MaxSpareServers 最大HTTPD空闲进程数量,这个用来控制,如果空闲HTTPD进程太多,会占用掉大量内存空间。

4,MaxClients 这个参量最难理解,我个人理解是,每个访客访问网站时,网站的HTTPD进程用来处理和访客的交互操作,而每个HTTPD的大小每个网站应该是有所区别的。这个MaxClients就代表了网站的HTTPD父进程的最大数量。比如每个HTTPD占用20M内存空间,你VPS的剩余内存空间是200M(剩余空间是指总的内存减去系统以及其它服务已经占用的内存),那么你的MaxClients应该只有200M/20M=10个。此时你最多只能设置为10,如果超过,那么VPS会调用硬盘空间作为内存不足的补充部分,但硬盘空间的访问速度实际上是很慢的,这样网站访问起来,就会有部分用户感觉很慢。如果你这个数值设置的很小,也会有问题,比如本来要10个HTTPD才能满足需求,但你设置为了8,那么如果有10人访问,就会有后面的2人访问会比较慢,等到前面的8人链接断开,这2人的访问才会快。(这里理解不清楚,不明白访客访问与HTTPD父进程和子进程之间的关系)

5,MaxRequestsPerChild 每个子进程在其生存期内允许伺服的最大请求数量,默认为0,则子进程不会自动销毁,这样子进程就可能占用内存越来越多,如果设置为1000,那么子进程在处理了1000个请求的时候会 被父进程自动销毁,从而产生新的子进程,这样内存消耗就降低了。(跟上面一样,不明白访客访问与HTTPD父进程和子进程之间的关系),但这里我也不明白怎么看子进程,还有子进程处理请求到底是处理的什么?

按F5刷我监控网页使我数据库挂掉了:

看/var/log/message日志的信息(总日志文件)

搜索Started/etc/rc.d/rc.local Compatibility

StartingMariaDB database server

/var/log/mariadb/mariadb.log是mariadb的日志文件

154321 Jan21 10:42:33 server kernel: [ 3740]0 3740 2697443 11 0 0 sleep

154322 Jan21 10:42:33 server kernel: [ 3746]0 3746 989951579 183 0 0 httpd

154323 Jan21 10:42:33 server kernel: Out of memory: Kill process 3044 (mysqld) score 75or sacrifice child

154324 Jan21 10:42:33 server kernel: Killed process 3044 (mysqld) total-vm:1195936kB,anon-rss:111696kB, file-rss: 0kB,shmem-rss:0kB

154585 Jan21 10:42:46 server kernel: [ 3740]0 3740 2697423 11 0 0 sleep

154586 Jan21 10:42:46 server kernel: [ 3746]0 3746 989951579 184 0 0 httpd

154587 Jan21 10:42:46 server kernel: Out of memory: Kill process 3072 (mysqld) score 77or sacrifice child

154588 Jan21 10:42:46 server kernel: Killed process 3072 (mysqld) total-vm:1195936kB,anon-rss:114124kB, file-rss: 4kB,shmem-rss:0kB

154589 Jan21 10:42:47 server mysqld_safe: /usr/bin/mysqld_safe: 行 183: 3044 已杀死 nohup /usr/libe xec/mysqld --basedir=/usr--datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin--log-error=/var/log/mariadb/mariadb.log --pid-file=/var/run/mariadb/mariadb.pid--socket=/var/lib/mysql/mysql.sock < /dev/null >> /var/log/mariadb/mariadb.log2>&1

154896 Jan21 10:43:18 server kernel: [ 3808]48 3808 990091583 186 0 0 httpd

154897 Jan21 10:43:18 server kernel: [ 3810]0 3810 2881264 12 0 0 ksmtuned

154898 Jan21 10:43:18 server kernel: Out of memory: Kill process 2601 (gnome-shell) score37 or sacrifice child

154899 Jan21 10:43:18 server kernel: Killed process 2664 (ibus-daemon) total-vm:470272kB,anon-rss:2132kB, file-rs s:0kB,shmem-rss:0kB

Jan 2110:43:18 server kernel: [ 3808]48 3808 990091583 186 00 httpd

155201 Jan21 10:43:18 server kernel: [ 3810]0 3810 2881263 12 0 0 ksmtuned

155202 Jan21 10:43:18 server kernel: Out of memory: Kill process 2601 (gnome-shell) score37 or sacrifice child

155203 Jan21 10:43:18 server kernel: Killed process 2601 (gnome-shell)total-vm:1404432kB, anon-rss:54560kB, file- rss:148kB, shmem-rss:8kB

155204 Jan21 10:43:19 server gnome-session[1961]: GnomeDesktop-WARNING: Failed to acquireidle monitor proxy: Time out wasreached

155205 Jan21 10:43:19 server gnome-session: gnome-session[1961]: GnomeDesktop-WARNING:Failed to acquire idle moni torproxy: Timeout was reached

155206 Jan21 10:43:22 server mysqld_safe: 180121 10:43:22 mysqld_safe mysqld from pidfile /var/run/mariadb/mariadb.pid ended

我发现访问量超出内存大小就会杀掉进程

百度一下:out of memory数据库3072kill

my.cnf

/var/log/mariadb/mariadb.log是mariadb的日志文件

解决数据库服务挂掉办法:

只要数据库服务挂了就重启开启数据库服务,写在/etc/crontab里面

if [`systemctl status mariadb | awk 'NR==3{print $2}'` == "inactive"];then systemctl restart mariadb;elif [ `systemctl status mariadb | awk'NR==3{print $2}'` == "failed" ];then systemctl restart mariadb;fi

解决访问量过大出现连接过慢的办法:

zabbix有个配置文件

/etc/httpd/conf.d/zabbix.conf

/usr/share/zabbix/里面才是监控的网页存放点

/usr/bin/mysqld_safe&这个是真正的mysqld服务,如果仅仅用systemctl start mariadb启动数据库服务,在高并发的情况下会导致systemctl statusmariadb发现有已杀死的现象

写在if语句里面&需要替换成&&>/dev/null才可行

if ["`netstat -tanp | grep 3306 | awk '{print $6}'`" != "LISTEN"];then /usr/bin/mysqld_safe & &>/dev/null;fi

特别注意if [ "$a" =="5" ];这个判断符号左右两边一定要有空格才行,判断是否为空要这样写: if ["`...`" == "" ];注意if中字符串要用双引号

特别注意if里面的字符串要用双引号引起来啊

showvariables like '%max_connections%';查看数据库最大连接数

vim/etc/my.cnf [mysqld]里面写max_connections=16000修改数据库最大连接数,试试有没有用,有加速效果

MariaDB[(none)]> show status like 'Threads%';

+-------------------+-------+

|Variable_name | Value |

+-------------------+-------+

|Threads_cached | 0 |

|Threads_connected | 77 |

|Threads_created | 356 |

|Threads_running | 24 |

+-------------------+-------+

+-------------------+-------+

|Variable_name | Value |

+-------------------+-------+

|Threads_cached | 0 |

|Threads_connected | 74 |

|Threads_created | 74 |

|Threads_running | 22 |

+-------------------+-------+数据库此时挂掉了

Threads_created表示创建过的线程数,如果发现Threads_created值过大的话,表明MySQL服务器一直在创建线程,这也是比较耗资源,可以适当增加配置文件中thread_cache_size值,查询服务器

thread_cache_size配置:

1. mysql>show variables like 'thread_cache_size';

2.+-------------------+-------+

3. |Variable_name | Value |

4.+-------------------+-------+

5. |thread_cache_size | 64 |

6.+-------------------+-------+

示例中的服务器还是挺健康的。

使用更多的虚拟机来使用amoeba主从负载均衡对数据库减少压力,但是apache又怎么判断连入哪一个数据库呢?哈哈,安装zabbix的时候会提示让你写哪个数据库ip,你就写amoeba代理机的ip就行了,可是我怎么知道要读还是要写操作呢,而且还要加上端口来指定读还是写啊,加端口是router读写分离呀,amoeba不用加端口

使用加大虚拟机内存的方法也能有用

还有/etc/my.cnf里面的设置能加速

上面查看日志发现原因是超过内存就导致数据库挂掉了

内存总是越来越少,虚拟内存使用越来越多

首先确定到底是什么占用了大量的内存

ps aux可以看到,大部分内存被闲置的httpd进程占用

free -hm也可以看到swap内存没了

total used free sharedbuff/cache available

Mem: 1.4G 1.2G 60M 28M 193M 25M

Swap: 0B 0B 0B

且当我重启mysql服务后,内存没有出现明显变化,mobax还是很卡,但是当我重启apache时,内存占用从2G瞬间下降到300M,就不卡了。由此可见,大量占用内存的就是闲置的httpd进程所致

于是上网查找了原因,原来是wdcp面板的apache配置不合理所致

vim/www/wdlinux/httpd-2.2.22/conf/httpd-wdl.conf或者apache住配置文件里面,实在不知道就百度 看到如下代码

无论采用什么样的方式,一定要把这个zabbix网页F5刷新导致数据库挂掉,超出内存的问题解决并做出来

数据库挂掉的时候重启数据库达不到清理内存的作用,重启httpd才能达到清理内存的作用,但是这样会造成3分钟httpd关闭状态,不合适

* * * * *root for l in `seq 60`;do if [ "`netstat -tanp | grep 3306 | awk '{print$6}'`" != "LISTEN" ];then /usr/bin/mysqld_safe &&>/dev/null;systemctl restart httpd;fi & sleep 1;done

pkill httpd&& systemctl start httpd这样写是错的pkill httpd; systemctl start httpd这样写也是错的,就直接用restart最好

吴振启动不了httpd原因是做了线程模式,解决办法:rm -rf/etc/httpd/conf.d/httpd-mpm.conf,vim/etc/httpd/conf.modules.d/00-mpm.conf改回来

vim/etc/httpd/conf/httpd.conf

#EnableMMAPon

EnableSendfileon

数据库服务启动的时候出现ended是因为my.cnf里面有不该有的东西

free -mh很实用

总结:

防止访问量过大导致mysql挂了,在apache主配置文件里加个模块自动释放内存,在my.cnf里加速,在计划任务里写秒级计划任务重启/usr/bin/mysql_safe,然后就是加内存了,搞一个高内存专门用来做数据库用

apache主配置文件:

# lbx edit 自动释放内存

ServerLimit 128

StartServers 5

MinSpareServers 5

MaxSpareServers 6

MaxClients 128

MaxRequestsPerChild 1000

my.cnf里加速:

key_buffer=16K

max_allowed_packet=1M

thread_stack=64K

table_cache=4

sort_buffer=64K

net_buffer_length=2K

max_connections=16000

thread_cache_size=64

秒级计划任务:加*和seq你懂的

if [`systemctl status mariadb | awk 'NR==3{print $2}'` == "inactive"];then systemctl restart mariadb;elif [ `systemctl status mariadb | awk'NR==3{print $2}'` == "failed" ];then systemctl restart mariadb;fi