如何防止访问量过大导致mysql数据库挂掉了
如何防止访问量过大导致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
上一篇: 小学生当街闹分手
下一篇: 老司机带你学c++之指针二