本文共 14562 字,大约阅读时间需要 48 分钟。
我们现在处理MySQL故障时,发现当Open_files大于open_files_limit值时,MySQL数据库就会发生卡住的现象,导致Nginx服务器打不开相应页面。这个问题大家在工作中应注意,我们可以用如下命令查看其具体情况:
show global status like 'open_files'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Open_files | 1481 | +---------------+-------+ mysql> show global status like 'open_files_limit'; +------------------+-------+ | Variable_name | Value | +------------------+--------+ | Open_files_limit | 4509 | +------------------+--------+比较合适的设置是:Open_files / Open_files_limit * 100% < = 75%
很多时候我们会发现,通过参数设置进行性能优化所带来的性能提升,并不如许多人想象的那样会产生质的飞跃,除非是之前的设置存在严重不合理的情况。我们不能将性能调优完全依托与通过DBA在数据库上线后进行参数调整,而应该在系统设计和开发阶段就尽可能减少性能问题。(重点在于前期架构合理的设计及开发的程序合理)。
Zenoss
Zenoss是用Python编写的,拥有基于浏览器的用户界面,并使用了Ajax使操作更加快捷而富有效率。它将监控、报警、趋势显示、图表显示和记录历史数据等功能合成在一个统一的工具里,它还能在网上自动发现资源,在默认情况下,Zenoss使用SNMP从远程机器上收集数据,但它也可以使用SSH,并且支持Nagios插件。
Hyperic HQHyperic HQ是一款基于Java的监控系统,它的目标跟其他同类别的软件不太一样,它要成为企业级的监控系统。跟Zenoss一样,它也能自动发现资源,支持Nagios插件,但是它的逻辑组织和架构很不一样,显得有点庞大。至于它是不是合适你的需求,那要看你的参数设置和监控的方式了。 OpenNMSOpenNMS是由Java编写的,拥有一个活跃的开发者社区。它具备了常规的功能,例如监控和报警,也加入了图表和趋势显示的功能。它的目标是高性能、伸缩性、自动化以及良好的兼容性。跟Hyperic一样,它也企图成为一款企业级的监控软件,可以用于大型的关键系统上。 Groundwork Open SourceGroundwork Open Source实际上是基于Nagios的,它把Nagios和其他几个工具集成为一个系统,并安上一个统一的门户界面。描述它的最好方法可能就是:如果你对Nagios、Cacti及其他工具很熟悉,并且能够花大量的时间把它们无缝地集成在一起的话,你也能在家庭作坊里做一个出来。 ZabbixZabbix是一个开源监控系统,在许多方面跟Nagios很相像,但是也有一些关键的不同点。例如:它把所有配置信息和其他数据都存放在一个数据库里,而不是放在配置文件里;它比Nagios存储了更多类型的数据,这样可以生成更好的趋势图和历史报告。它的网络图表和可视化功能也优于Nagios。很多使用它的人发现它更易配置,更具有兼容性。说起来它也能比Nagios少,它的报警功能也不够高级。1、Mysqlreport
2、Mysqlsla3、Maatkit分析工具注意:
如果用源码安装的话,后面nginx安装的时候需要指定 --with-pcre 对应的压缩包路径,如果用二进制包安装则不需指定依赖包一键安装: yum -y install zlib zlib-devel openssl openssl--devel pcre pcre-devel
openssl: tar -xzvf openssl-1.0.1.tar.gz cd openssl-1.0.1 ./config(注意) && make && make install pcre: tar -xzvf pcre-8.21.tar.gz cd pcre-8.21 ./configure && make && make install zlib: tar -xzvf zlib-1.2.8.tar.gz cd zlib-1.2.8 ./configure && make && make install
./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module --with-pcre=../pcre-8.38 --with-zlib=../zlib-1.2.8 --with-openssl=../openssl-1.0.2g--with-http_stub_status_module --user=nginx --group=nginx
本文主要讲mySQL对于nginx的优化和基本操作不作描述,读者可以自行参考相关文档。
按照上述过程nginx会被安装在 /usr/local/nginx目录。因此在更改了nginx的核心配置文件nginx.conf后可以使用如下命令进行启动
/usr/local/nginx/nginx –c /usr/local/nignx/nginx.conf
yum install –y spawn-fcgi fcgi-devel fcgi以上步骤执行完毕后,我们安装了:
spawn-fcgi
这个东西特别有意思,因为nginx默认是不支持cgi的,而gitweb是用cgi写的,因此我们才安装fastcgi,而fastcgi又要通过spawn-fcgi来启动。。。因此。。。必须要装spawn-fcgi。
fcgi-devel 和 fcgi它们都属于fastcgi运行时的lib库。从以下网址下载该组件:
运行以下命令cd fcgiwrapautoreconf –I configuremakemake install全部安装完后注意检查以下必要文件是否存在
# You must set some working options before the "spawn-fcgi" service will work.# If SOCKET points to a file, then this file is cleaned up by the init script.## See spawn-fcgi(1) for all possible options.## Example :#SOCKET=/var/run/php-fcgi.sock#OPTIONS="-u apache -g apache -s $SOCKET -S -M 0600 -C 32 -F 1 -P /var/run/spawn-fcgi.pid -- /usr/bin/php-cgi"
以上是原来文件的内容
修改后的内容如下显示:# You must set some working options before the "spawn-fcgi" service will work.# If SOCKET points to a file, then this file is cleaned up by the init script.## See spawn-fcgi(1) for all possible options.## Example :#SOCKET=/var/run/php-fcgi.sock#OPTIONS="-u apache -g apache -s $SOCKET -S -M 0600 -C 32 -F 1 -P /var/run/spawn-fcgi.pid -- /usr/bin/php-cgi"FCGI_SOCKET=/var/run/fcgiwrap.socketFCGI_PROGRAM=/usr/local/sbin/fcgiwrapFCGI_USER=nginxFCGI_GROUP=nginxFCGI_EXTRA_OPTIONS="-M 0700"OPTIONS="-u $FCGI_USER -g $FCGI_GROUP -s $FCGI_SOCKET -S $FCGI_EXTRA_OPTIONS -F 1 -P /var/run/spawn-fcgi.pid -- $FCGI_PROGRAM"
chkconfig --levels 2345 spawn-fcgi onchkconfig --levels 2345 php-fpm on/etc/init.d/spawn-fcgi startservice php-fpm start
把spawn-fcgi设为开机启动,并启动该服务,该服务成功启动后会在:
/var/run目录下生成一个fcgiwrap.socket文件。wget http://cn2.php.net/distributions/php-5.6.2.tar.gz
yum install php-mcrypt libmcrypt libmcrypt-devel
./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --enable-fpm --with-fpm-user=php-fpm --with-fpm-group=php-fpm --with-mysql=mysqlnd --with-mysql-sock=/var/lib/mysql/mysql.sock --with-libxml-dir --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --with-iconv-dir --with-zlib-dir --with-mcrypt --enable-soap --enable-gd-native-ttf --enable-ftp --enable-mbstring --enable-exif --disable-ipv6 --with-pear --with-curl --with-opensslMake && make install
编写一个测试php文件为test.php,内容如下:
把它放于/var/www.php目录内
server { error_log logs/php.error.log; access_log logs/php.access.log; listen 82; server_name 192.168.0.101; root /var/www/php; index index.php; location ~ .php$ { gzip off; #fastcgi_pass unix:/var/run/fcgiwrap.socket; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; } location = /favicon.ico { log_not_found off; access_log off; } location ~ /\.ht { deny all; } }
我们打开一个ie使用如:http://192.168.0.101:82/test.php来访问我们的测试页,如果你得到下面类似的界面,那就说明你的php已经和nginx结合成功了,如果你遇到下面这几个错误,本文将给出解决方法(网上的基本都是不对的)。
nginx出现502有很多原因,但大部分原因可以归结为资源数量不够用,也就是说后端php-fpm处理有问题,nginx将正确的客户端请求发给了后端的php-fpm进程,但是因为php-fpm进程的问题导致不能正确解析php代码,最终返回给了客户端502错误。
服务器出现502的原因是连接超时 我们向服务器发送请求 由于服务器当前链接太多,导致服务器方面无法给于正常的响应,产生此类报错因此如果你服务器并发量非常大,那只能先增加机器,然后按以下方式优化会取得更好效果;但如果你并发不大却出现502,一般都可以归结为配置问题,脚本超时问题。php-fpm进程数不够用
使用 netstat -napo |grep "php-fpm" | wc -l 查看一下当前fastcgi进程个数,如果个数接近conf里配置的上限,就需要调高进程数。
但也不能无休止调高,可以根据服务器内存情况,可以把php-fpm子进程数调到100或以上,在4G内存的服务器上200就可以。我们的php是安装在/usr/local/php目录下,更改/usr/local/php/php-fpm.conf文件,找到下面这一行。pm.max_children = 10也有可能这一行是被注释掉的,把它放开后改动如下:
pm.max_children = 100调高调高linux内核打开文件数量
echo 'ulimit -HSn 65536' >> /etc/profileecho 'ulimit -HSn 65536' >> /etc/rc.localsource /etc/profile脚本执行时间超时
如果脚本因为某种原因长时间等待不返回 ,导致新来的请求不能得到处理,可以适当调小如下配置。
nginx.conf里面主要是如下fastcgi_connect_timeout 300;fastcgi_send_timeout 300;fastcgi_read_timeout 300;php-fpm.conf里如要是如下
request_terminate_timeout = 10s缓存设置比较小 修改或增加配置到nginx.conf
proxy_buffer_size 64k;proxy_buffers 512k;proxy_busy_buffers_size 128k;
修改php的配制文件(此例我们在/usr/local/php/etc/目录下的php-fpm.conf文件)
user = php-fpmgroup = php-fpm在文件中加入上述两行,同时在centos中加入相应的用户和组重启php-fpm服务即可。
注:
phpMyAdmin版本和mySql版本有对应关系,目前较高版的phpMyAdmin支持的是mySql5.x及以上版本。因为我安装的是mySQL5.1.x,因此我只能用phpMyAdmin4.0.x。我们把phpMyAdmin-4.0.4.2-all-languages.zip解压后的内容全部copy进/var/www/php/目录下的/myadmin目录内。$cfg['Servers'][$i]['host'] $cfg['Servers'][$i]['port'] $cfg['Servers'][$i]['user'] $cfg['Servers'][$i]['password']把这些值按照你需要管理的mysql的主机信息一一填写完整,user和password你可以使用mysql的root用户信息。
$cfg['blowfish_secret'] = '';
如果认证方法设置为cookie,就需要设置短语密码,置于设置为什么密码,由您自己决定 ,但是不能留空,否则会在登录phpmyadmin时提示错误,如:我设置的就是secret。一切就绪后你可以使用http://192.168.0.101:82/myadmin/这样的网址登录你的phpMyAdmin了,第一次登录会要求你输入“短语密码”,我们输入事先配置好的secret,然后在用户名和密码处输入你要管理的mysql实例的root用户名和密码即可以通过phpMyAdmin来管理你的mySQL实例了。
通过phpMyAdmin你可以感受到相当强大的图形化mySQL管理功能。
使用 jdbc的批量操作,就是PreparedStatement 类上的addBatch(),executeBatch()方法。
在这里要提醒一下大家,MySql的JDBC驱动,是不支持批量操作的,就算你在代码中调用了批量操作的方法,MySql的JDBC驱动,也是按一般insert操作来处理的。 同样Fetch Size特性MySql的JDBC驱动也不支持。而Oracle的JDBC驱动是都支持的。 如果你以前使用的是Mysql数据库, 不要指望通过批处理来提高性能了。因此这才有了rewriteBatchedStatements参数的用法。MySql的JDBC连接的url中要加rewriteBatchedStatements参数,并保证5.1.13以上版本的驱动,才能实现高性能的批量插入。
例如:String connectionUrl="jdbc:mysql://192.168.1.100:3306/test?rewriteBatchedStatements=true" ;还要保证Mysql JDBC驱的版本相匹配。
try { PreparedStatement prest = conn.prepareStatement(sql); long a=System.currentTimeMillis(); for(int x = 1; x <= count; x++){ prest.setInt(1, x); prest.setString(2, "张三"); prest.execute(); if(x%point==0){ conn.commit(); } } long b=System.currentTimeMillis(); print("MySql非批量插入10万条记录",a,b,point); } catch (Exception ex) { ex.printStackTrace(); }finally{ close(conn); }
try { PreparedStatement prest = conn.prepareStatement(sql); long a=System.currentTimeMillis(); for(int x = 1; x <= count; x++){ prest.setInt(1, x); prest.setString(2, "张三"); prest.addBatch(); if(x%point==0){ prest.executeBatch(); conn.commit(); } } long b=System.currentTimeMillis(); print("MySql批量插入10万条记录",a,b,point); } catch (Exception ex) { ex.printStackTrace(); }finally{ close(conn); }
这里通过一个点也可以看出来:
String connectionUrl="jdbc:mysql://192.168.1.100:3306/test?rewriteBatchedStatements=true" ;笔者在使用mysql jdbc驱动5.1.13版的基础上 加了rewriteBatchedStatements参数, 并配合使用addBatch方法,10万条记录的一次性插入速度提高到了1.6秒左右。 以下是使用了rewriteBatchedStatements后再配合使用addBatch的统计结果,供对比: