坚持#第275天~防止访问量过大导致mysql数据库挂掉了

时间:2022-10-03 11:33:52

不合理的地方在于MaxClients和MaxRequestsPerChild。

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

prefork调优,修改为

<IfModulempm_prefork_module>

    ServerLimit 128

    StartServers 5

    MinSpareServers 5

    MaxSpareServers 6

    MaxClients 128

    MaxRequestsPerChild 1000

</IfModule>

最大空闲子进程数就是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    26974      43      11        0             0 sleep

154322 Jan21 10:42:33 server kernel: [ 3746]    0  3746    98995    1579     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    26974      23      11        0             0 sleep

154586 Jan21 10:42:46 server kernel: [ 3746]    0  3746    98995    1579     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    99009    1583     186        0             0 httpd

154897 Jan21 10:43:18 server kernel: [ 3810]    0  3810    28812      64      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    99009    1583     186        0            0 httpd

155201 Jan21 10:43:18 server kernel: [ 3810]    0  3810    28812      63      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      shared buff/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 自动释放内存

<IfModulempm_prefork_module>

    ServerLimit 128

    StartServers 5

    MinSpareServers 5

    MaxSpareServers 6

    MaxClients 128

    MaxRequestsPerChild 1000

</IfModule>

 

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


现在是2018年3月23日19:30:18,回来一看,呵呵,当初还没有学集群,能用到这中调优真的是自己佩服自己,加上目前学过的高可用集群keepalived+mysql就不会出现mysql挂掉无法访问zabbix监控页面啦,回过头来看,我确实是成长了不少