• Lnmp技术手册


     

     

     

                            

     Php篇

    配置

    1) Php.ini

    display_errors=(boolen) 错误信息是否显示到屏幕 生产环境必须关闭

    output_buffering = On  设一个输出处理器自动地打开输出缓冲

    register_globals=off 开启全局变量(安全问题 做关闭操作)

    max_execution_time 每个脚本运行的最长时间

    memory_limit  脚本运行最大消耗的内存

    magic_quotes_gpc 字符串的转义 一般防止出错 不建议开启 建议程序自己处理

    如果有上传文件的需要考虑:

    一般考虑时间超长和默认资源限制

     upload_max_filesize 10M    //所上传的文件的最大大小
     post_max_size 10M   //设定 POST 数据所允许的最大大小 若果超过内存限制 memory_limit 也会影响上传 通常memory_limit 应该比 post_max_size 要大
    max_input_time 300   //脚本等待输入数据的时间
    max_execution_time 300 //设置PHP 脚本的最大执行时间(进程的CPU时间)  {php-cgi(php-fpm) 中,该参数不会起效需要配置 php-fpm.conf中request_terminate_timeout 替代此函数}

    另外也要考虑webserver 的资源限制

    2) php-fpm

    pm = static|dynamic(如果是大内存服务器的话 建议开启静态 每个干净的php进程一般6M左右)

    pm.max_children 子进程的数量 根据应用场景 如果次数太小 会出现502

    pm.max_requests 设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的

    request_terminate_timeout 设置单个请求的超时中止时间. 该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止运行的脚本有用

    pm.max_requestsrequest_terminate_timeout的设置 对于一些异常进程非常重要 咱们多个系统出现过此类问题

    Php调试

    1) 内置api基本调试

    Echo、 print _r 、var_dump(var_export)、debug_zval_dump 。

    2) 错误控制和日志记录

    display_errors  error_reporting  log_errors log_errors

    详见:http://cn2.php.net/manual/zh/errorfunc.configuration.php#ini.display-errors

     

    3) 错误抛出和处理

    Try  catch截取异常  throw抛出异常

     错误抛出和处理主要是说我们在程序中,能够自己触发错误,或者是自己截获处理错误,类似于面向对 象编程里的异常处理 throw 抛出异常,catch  截获异常一个思路。

    trigger_error 、set_error_handler、set_exception_handler  这三个api 主要就是处理错误抛出和处理内置函数。

    使用 trgger_error 可以触发一个错误,触发级别跟上文的 error_reporting      的设定级别一致,主要是能够触 发的是 E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE  三种级别的错误,如果不做处理,那么 在程序执行就会报错,错误提示跟上文描述差不多,会出现 Fatal Error 、Warning 、Notice三种错误显示。

    trigger_error 是一个抛出错误的函数,可以抛出任何用户级别错误,在非面向对象时代的编里,可以作 为一个提示错误的一种方式。

    详见:http://www.php.net/manual/zh/language.exceptions.php

    4) 第三方工具

    Xdebug、、firebug、firephp、 xhprof apd(Advanced PHP debugge)等

    1)Xdebug

    重点说一下Xdebug

    实例:

    团购抓取增加了很多功能 抓取速度骤然变慢 要确定是什么拉慢了系统

    安装xdebug

    [root@localhost zhangminsong]# wget http://xdebug.org/files/xdebug-2.2.1.tgz

    [root@localhost zhangminsong]# tar xvf xdebug-2.2.1.tgz

    [root@localhost zhangminsong]# cd xdebug-2.2.1

    [root@localhost xdebug-2.2.1]# /usr/local/php/bin/phpize

    Configuring for:

    PHP Api Version:         20090626

    Zend Module Api No:      20090626

    Zend Extension Api No:   220090626

    [root@localhost xdebug-2.2.1]# ./configure --with-php-config=/usr/local/php/bin/php-config

    [root@localhost xdebug-2.2.1]# make

    [root@localhost xdebug-2.2.1]# make install

    Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/

    修改 php.ini 增加

    [Xdebug]

    zend_extension="/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/xdebug.so"

    xdebug.auto_trace = on

    xdebug.auto_profile = on

    xdebug.collect_params = on

    xdebug.collect_return = on

    xdebug.profiler_enable = on

    xdebug.trace_output_dir="/tmp/xdebug"

    xdebug.profiler_output_dir="/tmp/xdebug"

    xdebug.profiler_output_name="script"

    Mkdir /tmp/xdebug

    重启php 查看phpinfo

    跑一下抓取脚本 会在/tmp/xdebug中产生如下文件

    [root@localhost xdebug-2.2.1]# ll /tmp/xdebug/

    总用量 904

    -rw-r--r-- 1 www www 234232 2月   1 23:46 script

    -rw-r--r-- 1 www www 686293 2月   1 23:46 trace.619174344.xt

    Sz /tmp/xdebug/script 到本地分析这个文件 分析这个文件需要下载一个工具

    WinCacheGrind(http://sourceforge.net/projects/wincachegrind/ )

    一目了然 

    跑到这个函数 浪费了这么时间(1600个商品)居然调用了17w次的redis 平均一次0.2

    Ms,问题找到了  然后修改了代码逻辑 ok 速度变快了.

    详情:http://xdebug.org/

     

    2)APD(Advanced PHP Debugger)

    高级 PHP  调试器。是用来给 PHP  代码提供规划与纠错的能力, 以及提供了显示整个堆栈追踪的能力。支持交互式纠错,但默认是将数据写入跟踪文件。它还提供了 基于事件的日志,因此不同级别的信息(包括函数调用,参数传递,计时等)可以对个别的脚本打开或关闭。

    详情:http://cn2.php.net/manual/zh/intro.apd.php

    3)Xhprof

    它是个轻量级的性能监测工具,安装部署简单,占用系统资源更少, Xhprof 不是通过配置来启用监测,是否启用你直接在代码里启用,你需要监测哪个文件就在该文件启 用监测,这样不会像Xdebug 一样每个执行的文件都会记录下性能情况,Xhprof 自带Web 断的结果查看页面,不需要像Xdebug 另外安装 。

    详情:http://cn2.php.net/manual/zh/intro.xhprof.php

    5)php单元测试

      Phpuint

     PHPUnit  是一个轻量级的PHP  测试框架。它是在PHP5  下面对JUnit3  系列版本的完整移植,是xUnit 测试框架家族的一员(它们都基于模式先锋Kent Beck 的设计) 。

    单元测试是几个现代敏捷开发方法的基础,使得PHPUnit 成为许多大型PHP 项目的关键工具。这个工 具也可以被 Xdebug  扩展用来生成代码覆盖率报告 ,并且可以与phing  集成来自动测试,最后它还可以和 Selenium 整合来完成大型的自动化集成测试。 

     

    详见:http://pear.phpunit.de/

     

    Php加速优化工具(主要是优化php opcode)

    APC xcache 、eacceleratorZend Optimize

    建议做个必须条件安装到线上

    php扩展安装

     

    1)安装php扩展

    进行PHP的扩展开发有两种方式 ,第一种是从PHP源码进行,第二种是从PHP提供的独立的工具进行 第一种少了灵活性 所以我们一般选择第二种方式。

    PHP的核心(core)有两部分组成最底层的Zend引擎和他上面的phpcode,所以扩展类型又有两种:

    extension意为基于php(core)的扩展

    zend_extension意为基于zend引擎的扩展

    我们常用第二种方式进行扩展即外部加载

    php的扩展包 大部分在/php源码/ext 下  如果没有可以单独下载

    步骤

     /usr/local/php/bin/phpize

     

      ./configure --help

      ./configure --with-php-config=/usr/local/php/bin/php-config

      make

      make test #就算这里提示出错,不要理它!

      make install

    注:phpize 是属于 php-devel 中的东西,主要是设定 php 外挂模块的一些设定(一般存在于php-devel

    make install会生成xxx.so  然后在php.ini中手动加载进去。

    2)编写php扩展

    1 获取php源码包解压

    wget http://

    tar

    2 进入php源码包ext 目录

    cd php-5.2.14/ext

    3 生成扩展框架

    ./ext_skel --extname=zhang

    实例:

    --------------

    [root@domain09 ext]# ./ext_skel --extname=zhang

    Creating directory zhang

    Creating basic files: config.m4 config.w32 .cvsignore zhang.c php_zhang.h CREDITS EXPERIMENTAL tests/001.phpt zhang.php [done].

    To use your new extension, you will have to execute the following steps:

    1.  $ cd ..

    2.  $ vi ext/zhang/config.m4

    3.  $ ./buildconf

    4.  $ ./configure --[with|enable]-zhang

    5.  $ make

    6.  $ ./php -f ext/zhang/zhang.php

    7.  $ vi ext/zhang/zhang.c

    8.  $ make

    Repeat steps 3-6 until you are satisfied with ext/zhang/config.m4 and

    step 6 confirms that your module is compiled into PHP. Then, start writing

    code and repeat the last two steps as often as necessary.

    ------------------------------------------------------------------

    这个命令会在php-5.2.14/ext目录里面生成 zhang目录 并在该目录生成一些文件 其中用到的 是3个文件  一个是config.m4 一个是php_zhang.h  一个是 zhang.c

    实例:

    ------------------------------------------------------

    [root@domain09 zhang]# ll

    total 64

    -rw-r--r-- 1 root root 1975 Jan 20 09:59 config.m4

    -rw-r--r-- 1 root root  282 Jan 20 09:59 config.w32

    -rw-r--r-- 1 root root    4 Jan 20 09:59 CREDITS

    -rw-r--r-- 1 root root    0 Jan 20 09:59 EXPERIMENTAL

    -rw-r--r-- 1 root root 2666 Jan 20 09:59 php_zhang.h

    drwxr-xr-x 2 root root 4096 Jan 20 09:59 tests

    -rw-r--r-- 1 root root 5133 Jan 20 09:59 zhang.c

    -rw-r--r-- 1 root root  496 Jan 20 09:59 zhang.php

    ------------------------------------------------------------

    编辑 这三个文件

    vi config.m4

    把下面这两句前面的的dnl去掉,保存

    dnl PHP_ARG_ENABLE(zhang, whether to enable zhang support,

    dnl [  --enable-zhang           Enable zhang support])

     vi php_zhang.h

    找到PHP_FUNCTION(confirm_zhang_compiled);    /* For testing, remove later. */

    ,新增一行:

    PHP_FUNCTION(zhang_test);

    保存

    vi zhang.c

    代码后面加上你的c代码

    比如

    PHP_FUNCTION(zhang){

    RETURN_STRING("hello world! zhangminsong",1);

    }

    然后开始编译

    [root@domain09 zhang]# phpize

    [root@domain09 zhang]# ./configure --with-php-config=/usr/local/ku6/php/bin/php-config

    [root@domain09 zhang]# make

    然后 zhang/modules/下会生成一个zhang.so

    cp 到php的extensions目录  然后 vi php.ini 加上

    extension = zhang.so

    重启php

    <?php

    phpinfo();

    echo zhang();

    ?>

    php程序安全

    1 是命令注入攻击 主要通过system eval passthru等这些函数 执行外部提交过来的命令

    2 客户端脚本注入攻击(注意过滤提交数据)

    3 跨站脚本攻击(注意过滤提交数据)

    4 sql 注入攻击(注意过滤特殊字符)

    5 跨站伪造请求攻击 (检查页面来源)

    6 session 劫持攻击(注意session id 的安全 如封装 更改名称等)

    7 session固定攻击(不要get post获取 重新生成新的seesion id 检查来源等)

    8 HTTP响应拆分攻击(使用最新版的php 就行了 或者检查http头或者sessionid)

    9 文件上传攻击(限制上传条件)

    10 目录穿越攻击(检查目录字符)

    11 远程文件引入攻击(检查目录字符)

    12 变量指定攻击 (注意检查变量)


    基本就这些了 括号里面我粗略的注释了防范的方法 总的来说就要不要信任站外提交一切数据 必须按照规则检查过滤

     附录 php一些常见错误

    1 语法构造错误 

    This is a syntax error

    2 头出输出错误 

    Warning: Cannot add header information - headers already sent by

    Warning: Cannot send session cache limiter - headers already sent in somefile.php on line

    3 mySql 资源错误

    Warning: Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in…

    SQL查询语句错误(但错误没有被抛出)

    4 Sessions 不能被创建或者被修改维护

    Sessions are not being created or maintained

    5文件流错误

    Warning: failed to open stream…

    6文件没有权限被读取

     Warning: fopen(…): failed to open stream: Permission denied in…

    7 空白页面

    8 乱码

    9 最大执行时间错误

    Max Execution Time Error

    10 打开基目录错误

    warning: Unknown(): open_basedir restriction in effect.

    Mysql 篇

    1)mysql安全

     

    1 mysql目录文件的权限设置

    MySQL所在的主机的安全性是最首要的问题,如果主机不安全,被攻击者控制,那么MySQL的安全性也无从谈起。其次就是数据目录和数据文件的安全性,也就是权限设置问题

    mysql的运行建立mysql用户和mysql用户组:

    /usr/sbin/groupadd mysql

    /usr/sbin/useradd -g mysql mysql

    chmod +w /usr/local/ku6/mysql/

    chown -R mysql:mysql /usr/local/ku6/mysql/

    chown -R mysql:mysql mysql/

     

    mysql用户帐号的身份建立数据表:

    /usr/local/ku6/mysql/bin/mysql_install_db --

    basedir=/usr/local/ku6/mysql --datadir=/mysql/3306/data --user=mysql

     

     

    2 修改root用户口令,删除空口令

    mysql> use mysql;

    Reading table information for completion of table and column names

    You can turn off this feature to get a quicker startup with -A

    Database changed

    mysql> delete from user where user='';

    Query OK, 0 rows affected (0.00 sec)

    mysql> update user set password=password('testpasswd') where

     

    user='root';

    Query OK, 2 rows affected (0.00 sec)

    Rows matched: 2  Changed: 2  Warnings: 0

     

    mysql> flush privileges;

    Query OK, 0 rows affected (0.00 sec)

     

    3 mysql的访问问题

    避免外部连接

    启动时Skip-networking

    my.cnf bind-address=内网ip

    限定连接IP

    mysql> grant ALL PRIVILEGES on *.* to ktvtest@'%' to

    ktv_user@'x.x.x.x/x.x.x.x' identified by 'passwd';

    4 危险的函数

    LOAD DATA INFILE(只能读全局可读文件)

    SELECT …INTO  OUTFILE(不能覆盖文件)

     

    举例:

    mysql>create table a (cmd text);

    mysql>insert into a values ("<?php" );

    mysql>insert into a values ("phpinfo()" );

    mysql>insert into a values ("<php?>" );

    mysql>select * from a into outfile “/usr/local/ku6/ktv/shell.php";

    5 mysql 启动安全问题

    绝对不要作为使用root用户运行MySQL服务器。应该用普通非特权用户运行mysql

    my.cnf    user=mysql

    6 命令历史记录保护

    # rm .bash_history .mysql_history

    # ln –s /dev/null .bash_history

    # ln –s /dev/null .mysql_history

     

     7 构建choot 环境

    MySQL运行在一个独立的环境下,将其和主系统隔离

     

    2)mysql监控与调优

    1 检查系统的状态

    主要察看 CPU问题 内存问题 磁盘IO问题 网络问题

    命令 top 、vmstat 、sar、iostat等

    1) 用vmstat察看关于内核进程,虚拟内存,磁盘,cpu的的活动状态

    [root@ks01 ~]# vmstat

    procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------

     r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st

     0  0    208 811596 326016 2485004    0    0     0     1    0    0  0  0 100  0  0

    其中:

    kthr--内核进程的状态

    --r 运行队列中的进程数,在一个稳定的工作量下,应该少于5

    --b 等待队列中的进程数(等待I/O),通常情况下是接近0的.

    memory--虚拟和真实内存的使用信息

    --avm 活动虚拟页面,在进程运行中分配到工作段的页面空间数.

    --fre 空闲列表的数量.一般不少于120,当fre少于120时,系统开始自动的kill进程去释放

          free list

    page--页面活动的信息

    --re 页面i/o的列表

    --pi 从页面输入的页(一般不大于5)

    --po 输出到页面的页

    --fr 空闲的页面数(可替换的页面数)

    --sr 通过页面置换算法搜索到的页面数

    --cy 页面置换算法的时钟频率

    faults--在取样间隔中的陷阱及中断数

    --in 设备中断

    --sy 系统调用中断

    --cs 内核进程前后交换中断

    cpu--cpu的使用率

    --us 用户进程的时间

    --sy 系统进程的时间

    --id cpu空闲的时间

    --wa 等待i/o的时间

    一般us+sy 在单用户系统中不大于90,在多用

    2 )sar来检查操作系统是否存在IO问题

    sar可以显示CPU、运行队列、磁盘I/O、分页(交换区)、内存、CPU中断、网络等性能数据

    [root@ks01 ~]# sar

    Linux 2.6.18-194.el5 (ks01.oss.com)     05/03/2011

    12:00:01 AM       CPU     %user     %nice   %system   %iowait    %steal     %idle

    12:10:01 AM       all      0.00      0.00      0.00      0.03      0.00     99.96

    12:20:01 AM       all      0.00      0.00      0.00      0.01      0.00     99.98

    ...

    其中:

    -CPU

     CPU编号

    --%user

     在用户模式中运行进程所花的时间的百分比

    --%nice

     运行正常进程所花的时间的百分比

    --%system

     在内核模式(系统)中运行进程所花的时间的百分比

    --%iowait

     没有进程在该CPU上执行时,处理器等待I/O完成的时间的百分比   --这个值过高,表示硬盘存在I/O瓶颈

    --%idle

     CPU空闲时间百分比 ---如果这个值很高 但是系统响应慢 这时候应该加大内存 如果这个值持续太低 说明系统缺少cpu资源

    附:sar 命令行的常用格式:

    sar -u 是sar的缺省输出 (CPU 使用情况)

    sar [options] [-A] [-o file] t [n]

    在命令行中,n 和t 两个参数组合起来定义采样间隔和次数,t为采样间隔,是必须有

    的参数,n为采样次数,是可选的,默认值是1,-o file表示将命令结果以二进制格式

    存放在文件中,file 在此处不是关键字,是文件名。options 为命令行选项,sar命令

    的选项很多,下面只列出常用选项:

       -A:所有报告的总和。

       -u:CPU利用率

       -v:进程、I节点、文件和锁表状态。

       -d:硬盘使用报告。

       -r:没有使用的内存页面和硬盘块。

       -g:串口I/O的情况。

          -b:缓冲区使用情况。

          -a:文件读写情况。

          -c:系统调用情况。

          -R:进程的活动情况。

          -y:终端设备活动情况。

          -w:系统交换活动。

    比如

    [root@ks01 ~]# sar -u 2 5  每2秒采集一下信息 收集5次

    Linux 2.6.18-194.el5 (ks01.oss.com)     05/03/2011

    03:33:47 PM       CPU     %user     %nice   %system   %iowait    %steal     %idle

    03:33:49 PM       all      0.00      0.00      0.00      0.00      0.00    100.00

    03:33:51 PM       all      0.00      0.00      0.00      0.00      0.00    100.00

    03:33:53 PM       all      0.00      0.00      0.00      0.03      0.00     99.97

    03:33:55 PM       all      0.00      0.00      0.00      0.00      0.00    100.00

    03:33:57 PM       all      0.00      0.00      0.00      0.00      0.00    100.00

    Average:          all      0.00      0.00      0.00      0.01      0.00     99.99

    2 检查mysql状态

    几个命令:

    show status        显示系统状态

    show variables     显示系统变量

    show processlist   显示进程状态

    show profiles;     收集执行查询资源信息 默认是关闭的 开启 set profiling=1;

    ------------------------------------

    常用的衍生命令:

     连接失败情况

    show status like'%aborted%'

    Aborted_clients  客户端非法中断连接次数 如果随时间而增大 看看mysql的链接是否正常 或者检查一下网络 或者检查一下max_allowed_packet  超过此设置的查询会被中断( show variables like'%max%')

    Aborted_connects 连接mysql失败次数  如果指过高 那就该检查一下网络 错误链接失败会在此记录

    mysql> show status like'%aborted%';

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

    | Variable_name    | Value |

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

    | Aborted_clients  | 46    |

    | Aborted_connects | 1     |

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

    2 rows in set (0.00 sec)

    慢查询:

     

    show variables like '%slow%'

    show status like '%slow%';

    默认是关闭的 开启 set global log_slow_queries=ON ;

    Slow_launch_threads 值较大 说明有些东西正在延迟链接的新线程

    mysql> show variables like '%slow%' ;

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

    | Variable_name       | Value                                |

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

    | log_slow_queries    | ON                                   |

    | slow_launch_time    | 1                                    |

    | slow_query_log      | ON                                   |

    | slow_query_log_file | /data0/mysql/3306/data/ks01-slow.log |

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

    4 rows in set (0.00 sec)

    mysql> show status like '%slow%';

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

    | Variable_name       | Value |

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

    | Slow_launch_threads | 0     |

    | Slow_queries        | 0     |

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

    2 rows in set (0.00 sec)

    连接数

     

    show variables like 'max_connections' 最大连接数

    show  status like 'max_used_connections'响应的连接数

    max_used_connections / max_connections * 100% (理想值 ≈ 85%)

    如果max_used_connections跟max_connections相同 那么就是max_connections设置过低或者超过服务器负载上限了

    mysql> show variables like 'max_connections' ;

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

    | Variable_name   | Value |

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

    | max_connections | 5000  |

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

    1 row in set (0.00 sec)

    缓存簇

    show status like 'key_blocks_u%';使用和未使用缓存簇(blocks)数

    show  variables like '%Key_cache%';

    show  variables like '%Key_buffer_size%';

    如果Key_blocks_used * key_cache_block_size  远小于key_buffer_size 那么就意味着内存呗浪费了 应该调大key_buffer_size值

    mysql> show status like 'key_blocks_u%';

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

    | Variable_name     | Value  |

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

    | Key_blocks_unused | 213839 |

    | Key_blocks_used   | 503    |

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

    2 rows in set (0.00 sec)

    mysql> show  variables like '%Key_cache%';

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

    | Variable_name            | Value |

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

    | key_cache_age_threshold  | 300   |

    | key_cache_block_size     | 1024  |

    | key_cache_division_limit | 100   |

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

    3 rows in set (0.00 sec)

    mysql> show  variables like '%Key_buffer_size%';

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

    | Variable_name   | Value     |

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

    | key_buffer_size | 268435456 |

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

    1 row in set (0.00 sec)

    线程使用情况

    show status like 'Thread%';如果发现Threads_created值过大的话,可以适当增加配置文件中thread_cache_size值

    Threads_cached用来缓存线程

    mysql> show status like 'Thread%';

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

    | Variable_name     | Value |

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

    | Threads_cached    | 4     |

    | Threads_connected | 1     |

    | Threads_created   | 5     |

    | Threads_running   | 1     |

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

    4 rows in set (0.00 sec)

    打开的文件数

    show  status like '%open_file%';

    show  variables like '%open_file%';

    如果Open_files和open_files_limit接近 就应该增加open_files_limit的大小

    不过mysql打开的文件描述符限制都是OS的文件描述符限制,和配置文件中open_files_limit的设置没有关系

    mysql> show  status like '%open_file%';

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

    | Variable_name | Value |

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

    | Open_files    | 178   |

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

    1 row in set (0.00 sec)

    mysql> show  variables like '%open_file%';

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

    | Variable_name     | Value |

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

    | innodb_open_files | 300   |

    | open_files_limit  | 25000 |

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

    2 rows in set (0.00 sec)

    全联接

    show  status like '%select_full__%';

    全链接是无索引链接 最好避免

    如果Select_full_range_join过高 说明系统运行了很多范围查询联接表

    mysql> show  status like '%select_full__%';

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

    | Variable_name          | Value |

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

    | Select_full_join       | 0     |

    | Select_full_range_join | 0     |

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

    2 rows in set (0.00 sec)

    打开表情况

    show tatus like 'open%tables%';

    如果open_tables接近table_cache的时候,并且Opened_tables这个值在逐步增加,说明table_cache不够用 表缓存没有完全用上 那就要考虑增加table_cache的大小了。还有就是Table_locks_waited比较高的时候,也需要增加table_cache

    mysql> show status like 'open%tables%';

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

    | Variable_name | Value |

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

    | Open_tables   | 95    |

    | Opened_tables | 0     |

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

    2 rows in set (0.00 sec)

    查询缓存

    show status like 'qcache%';

    show variables like 'query_cache%';察看query_cache的配置

    query_cache_limit:超过此大小的查询将不缓存

    query_cache_min_res_unit:缓存块的最小大小

    query_cache_size:查询缓存大小

    query_cache_type:缓存类型,决定缓存什么样的查询,示例中表示不缓存 select sql_no_cache 查询

    query_cache_wlock_invalidate:当有其他客户端正在对MyISAM表进行写操作时,如果查询在query cache中,是否返回cache结果还是等写操作完成再读表获取结果

    mysql> show status like 'qcache%';

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

    | Variable_name           | Value     |

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

    | Qcache_free_blocks      | 3         |

    | Qcache_free_memory      | 536800368 |

    | Qcache_hits             | 224134    |

    | Qcache_inserts          | 382       |

    | Qcache_lowmem_prunes    | 0         |

    | Qcache_not_cached       | 404       |

    | Qcache_queries_in_cache | 40        |

    | Qcache_total_blocks     | 95        |

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

    8 rows in set (0.00 sec)

    mysql> show variables like 'query_cache%';

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

    | Variable_name                | Value     |

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

    | query_cache_limit            | 2097152   |

    | query_cache_min_res_unit     | 2048      |

    | query_cache_size             | 536870912 |

    | query_cache_type             | ON        |

    | query_cache_wlock_invalidate | OFF       |

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

    5 rows in set (0.00 sec)

    排序情况

    show  status like 'sort%';

    Sort_merge_passes过大 就要增加Sort_buffer_size  但是盲目的增加 Sort_buffer_size 并不一定能提高速度

    mysql> show  status like 'sort%';

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

    | Variable_name     | Value |

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

    | Sort_merge_passes | 0     |

    | Sort_range        | 0     |

    | Sort_rows         | 0     |

    | Sort_scan         | 0     |

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

    4 rows in set (0.00 sec)

    高速缓存

    show variables like 'key_buffer_size';MyISAM 存储引擎键高速缓存 对MyISAM表性能影响很大大

    show  status like 'key_read%';磁盘读取索引的请求次数

    索引未命中缓存的概率=Key_reads / Key_read_requests * 100%

    不能以Key_read_requests / Key_reads原则来设置key_buffer_size

    Key_reads 将这个值和系统的i/o做对比

    mysql> show variables like 'key_buffer_size';

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

    | Variable_name   | Value     |

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

    | key_buffer_size | 268435456 |

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

    1 row in set (0.00 sec)

    mysql> show  status like 'key_read%';

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

    | Variable_name     | Value  |

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

    | Key_read_requests | 115144 |

    | Key_reads         | 1311   |

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

    2 rows in set (0.00 sec)

    mysql>

    表锁情况

    show  status like 'table_locks%';

    Table_locks_waited显示了多少表呗锁住并导致了mysql的锁等待 可以开启慢查询看一下

    mysql> show  status like 'table_locks%';

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

    | Variable_name         | Value |

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

    | Table_locks_immediate | 20370 |

    | Table_locks_waited    | 0     |

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

    2 rows in set (0.00 sec)

    表扫描情况

    show status like 'handler_read%';

    show status like 'com_select';

    如果Handler_read_rnd_next /Handler_read_rnd 的值过大 那么就应该优化索引、查询

     mysql> show status like 'handler_read%';

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

    | Variable_name         | Value |

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

    | Handler_read_first    | 0     |

    | Handler_read_key      | 0     |

    | Handler_read_next     | 0     |

    | Handler_read_prev     | 0     |

    | Handler_read_rnd      | 0     |

    | Handler_read_rnd_next | 20    |

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

    6 rows in set (0.00 sec)

    mysql> show status like 'com_select';

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

    | Variable_name | Value |

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

    | Com_select    | 0     |

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

    1 row in set (0.00 sec)

    临时表情况

     

    show  status like 'created_tmp%';

    show  variables like 'tmp_table%';

    show  variables like 'max_heap%';

    如果Created_tmp_disk_tables值较高 则有可能是因为:tmp_table_size或者max_heap_table_size太小

    或者是选择blob、text属性的时候创建了临时表

    Created_tmp_tables 过高的话 那么就有话查询吧

    mysql>  show  status like 'created_tmp%';

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

    | Variable_name           | Value |

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

    | Created_tmp_disk_tables | 0     |

    | Created_tmp_files       | 5     |

    | Created_tmp_tables      | 0     |

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

    3 rows in set (0.00 sec)

    mysql> show  variables like 'tmp_table%';

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

    | Variable_name  | Value     |

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

    | tmp_table_size | 257949696 |

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

    1 row in set (0.00 sec)

    mysql> show  variables like 'max_heap%';

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

    | Variable_name       | Value     |

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

    | max_heap_table_size | 257949696 |

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

    1 row in set (0.00 sec)

    二进制日志缓存

     

    show status like'%binlog%';

     show variables like'%binlog%';

    如果Binlog_cache_disk_use 和 Binlog_cache_use 比例很大 那么就应该增加binlog_cache_size的值

    mysql> show status like'%binlog%';

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

    | Variable_name          | Value |

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

    | Binlog_cache_disk_use  | 0     |

    | Binlog_cache_use       | 69166 |

    | Com_binlog             | 0     |

    | Com_show_binlog_events | 0     |

    | Com_show_binlogs       | 0     |

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

    5 rows in set (0.00 sec)

    mysql> show variables like'%binlog%';

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

    | Variable_name                           | Value      |

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

    | binlog_cache_size                       | 4194304    |

    | binlog_direct_non_transactional_updates | OFF        |

    | binlog_format                           | MIXED      |

    | innodb_locks_unsafe_for_binlog          | OFF        |

    | max_binlog_cache_size                   | 8388608    |

    | max_binlog_size                         | 1073741824 |

    | sync_binlog                             | 0          |

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

    7 rows in set (0.00 sec)

    附录 mysql 故障

    1 应用获取不到连接池

    2 数据库响应慢

    3 SQL慢

    4 服务器load高

    5 SWAP

    6 表不见了

    7 MySQL crash

    Nginx篇

     

    1)配置

    worker_processes 8
    nginx要开启的进程数 一般等于cpu的总核数 其实一般情况下开4个或8个就可 以了 多了没有太多用
    每个nginx进程消耗的内存10兆的模样

    worker_cpu_affinity
    仅适用于linux,使用该选项可以绑定worker进程和CPU(2.4内核的机器用不

    了)
    假如是8 cpu 分配如下:
    worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000

    00100000 01000000 10000000

    nginx可以使用多个worker进程,原因如下:

    to use SMP
    to decrease latency when workers blockend on disk I/O
    to limit number of connections per process when select()/poll() is

    used
    The worker_processes and worker_connections from the event sections

    allows you to calculate maxclients value: k

    max_clients = worker_processes * worker_connections

    worker_rlimit_nofile 102400;

    每个nginx进程打开文件描述符最大数目 配置要和系统的单进程打开文件数一

    ,linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应

    应该填写65535
    nginx调度时分配请求到进程并不是那么的均衡,假如超过会返回502错误。我

    这里写的大一点

    use epoll

    Nginx使用了最新的epoll(Linux 2.6内核)和kqueue(freebsd)网络I/O模

    型,而Apache则使用的是传统的select模型。
    处理大量的连接的读写,Apache所采用的select网络I/O模型非常低效。
    在高并发服务器中,轮询I/O是最耗时间的操作 目前Linux下能够承受高并发

    访问的Squid、Memcached都采用的是epoll网络I/O模型。

    worker_connections 65535;
    每个工作进程允许最大的同时连接数  Maxclient = work_processes * worker_connections)

    keepalive_timeout 75

    keepalive超时时间

    这里需要注意官方的一句话:
    The parameters can differ from each other. Line Keep-Alive:

    timeout=time understands Mozilla and Konqueror. MSIE itself shuts

    keep-alive connection approximately after 60 seconds.

    client_header_buffer_size 16k
    large_client_header_buffers 4 32k
    客户请求头缓冲大小
    nginx默认会用client_header_buffer_size这个buffer来读取header值,如果

    header过大,它会使用large_client_header_buffers来读取
    如果设置过小HTTP头/Cookie过大 会报400 错误 nginx 400 bad request
    求行如果超过buffer,就会报HTTP 414错误(URI Too Long)
    nginx接受最长的HTTP头部大小必须比其中一个buffer大,否则就会报400的

    HTTP错误(Bad Request)。

    open_file_cache max 102400

    使用字段:http, server, location 这个指令指定缓存是否启用,如果启用,将记录文件以下信息: ·打开的文件描述符,大小信息和修改时间. ·存在的目录信息. ·在搜索文件过程中的错误信息 -- 没有这个文件,无法正确读取,参考open_file_cache_errors 指令选项:
    ·max - 指定缓存的最大数目,如果缓存溢出,最长使用过的文件(LRU)将被移除
    : open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on;

    open_file_cache_errors
    语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件是记录cache错误.

    open_file_cache_min_uses

    语法:open_file_cache_min_uses number 默认值:open_file_cache_min_uses 1 使用字段:http, server, location 这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如 果使用更大的值,文件描述符在cache中总是打开状态.
    open_file_cache_valid

    语法:open_file_cache_valid time 默认值:open_file_cache_valid 60 使用字段:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息.


    开启gzip
    gzip on;
      gzip_min_length  1k;
      gzip_buffers     4 16k;
      gzip_http_version 1.0;
      gzip_comp_level 2;
      gzip_types       text/plain application/x-javascript text/css

    application/xml;
      gzip_vary on;

    缓存静态文件:

      location ~* ^.+\.(swf|gif|png|jpg|js|css)$ {
                    root   /usr/local/ku6/ktv/show.ku6.com/;
                    expires 1m;
            }

    附录:一些错误排查

    502 504错误

     php-cgi进程数不够用、php执行时间长(链接mysql等后端服务慢、异常等)、或者是php-cgi 进程死掉

    ,都会出现502错误

    一般来说Nginx 502 Bad Gateway和php-fpm.conf的设置有关,而Nginx 504 Gateway Time-out则是与nginx.conf(fastcgi_*)的设置有关

      1、查看当前的PHP FastCGI进程数是否够用:

          netstat -anpo | grep "php-cgi" | wc -l

      如果实际使用的“FastCGI进程数”接近预设的“FastCGI进程数”,那么

    ,说明“FastCGI进程数”不够用,需要增大。

      2、部分PHP程序的执行时间超过了Nginx的等待时间,可以适当增加

    nginx.conf配置文件中FastCGI的timeout时间,例如:

    http

    {

    ......

    fastcgi_connect_timeout 300;

    fastcgi_send_timeout 300;

    fastcgi_read_timeout 300;

    ......

    }

    413 Request Entity Too Large

    增大client_max_body_size

    client_max_body_size:指令指定允许客户端连接的最大请求实体大小,它出现在请求头部的Content-Length字段. 如果请求大于指定的值,客户端将收到一个"Request Entity Too Large" (413)错误. 记住,浏览器并不知道怎样显示这个错误.

    php.ini中增大

    post_max_size 和upload_max_filesize

     附录 nginx一些错误

    误信息

    错误说明

    "upstream prematurely(过早的) closed connection"

    请求uri的时候出现的异常,是由于upstream还未返回应答给用户时用户断掉

    连接造成的,对系统没有影响,可以忽略

    "recv() failed (104: Connection reset by peer)"

    (1)服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;

    (2)客户关掉了浏览器,而服务器还在给客户端发送数据;

    (3)浏览器端按了Stop

    "(111: Connection refused) while connecting to upstream"

    用户在连接时,若遇到后端upstream挂掉或者不通,会收到该错误

    "(111: Connection refused) while reading response header from upstream"

    用户在连接成功后读取数据时,若遇到后端upstream挂掉或者不通,

    会收到该错误

    "(111: Connection refused) while sending request to upstream"

    Nginx和upstream连接成功后发送数据时,若遇到后端upstream挂掉或者不通,

    会收到该错误

    "(110: Connection timed out) while connecting to upstream"

    nginx连接后面的upstream时超时

    "(110: Connection timed out) while reading upstream"

    nginx读取来自upstream的响应时超时

    "(110: Connection timed out) while reading response header from upstream"

    nginx读取来自upstream的响应头时超时

    "(110: Connection timed out) while reading upstream"

    nginx读取来自upstream的响应时超时

    "(104: Connection reset by peer) while connecting to upstream"

    upstream发送了RST,将连接重置

    "upstream sent invalid header while reading response header from upstream"

    upstream发送的响应头无效

    "upstream sent no valid HTTP/1.0 header while reading response header from upstream"

    upstream发送的响应头无效

    "client intended to send too large body"

    用于设置允许接受的客户端请求内容的最大值,默认值是1M,

    client发送的body超过了设置值

    "reopening logs"

    用户发送kill  -USR1命令

    "gracefully shutting down",

    用户发送kill  -WINCH命令

    "no servers are inside upstream"

    upstream下未配置server

    "no live upstreams while connecting to upstream"

    upstream下的server全都挂了

    "SSL_do_handshake() failed"

    SSL握手失败

    "SSL_write() failed (SSL:) while sending to client"

    "(13: Permission denied) while reading upstream"

    "(98: Address already in use) while connecting to upstream"

    "(99: Cannot assign requested address) while connecting to upstream"

    "ngx_slab_alloc() failed: no memory in SSL session shared cache"

    ssl_session_cache大小不够等原因造成

    "could not add new SSL session to the session cache while SSL handshaking"

    ssl_session_cache大小不够等原因造成

    "send() failed (111: Connection refused)"

     

    优化Linux内核参数

    vi /etc/sysctl.conf

    这个希望运维给的权威一些

      

    # Add
    net.ipv4.tcp_max_syn_backlog = 65536
    net.core.netdev_max_backlog =  32768
    net.core.somaxconn = 32768

    net.core.wmem_default = 8388608
    net.core.rmem_default = 8388608
    net.core.rmem_max = 16777216
    net.core.wmem_max = 16777216

    net.ipv4.tcp_timestamps = 0
    net.ipv4.tcp_synack_retries = 2
    net.ipv4.tcp_syn_retries = 2

    net.ipv4.tcp_tw_recycle = 1
    #net.ipv4.tcp_tw_len = 1
    net.ipv4.tcp_tw_reuse = 1

    net.ipv4.tcp_mem = 94500000 915000000 927000000
    net.ipv4.tcp_max_orphans = 3276800

    #net.ipv4.tcp_fin_timeout = 30
    #net.ipv4.tcp_keepalive_time = 120
    net.ipv4.ip_local_port_range = 1024  65535
     

    前端篇

    1  组件切分到多个域(垂直切割):

    比如动静分开 图片服务域 (公司图片hash)js服务域 css服务域 静态html服务域等

    作用:分散流量 浏览器的并发 (域名要注意cookies的作用域  不然http头会带上cookies)

    2  减少HTTP请求:

    合并js、css

    CSS Sprites

    Image Map

    Data URI编码图片

    3  浏览器缓存 :

    这个我要重点说一下

    浏览器会在用户的系统创建一个目录 用来存放缓存的内容 并会给他们一些标识 用来区分是否过期

    不同的浏览器采用不同的方式来缓存内容 比如火狐可以用 about:cache?device=disk或者about:cache?device=memory 来看到底放那里了

    注意的几个参数:

    1) Last-Modified 与If-Modified-Since 告诉里浏览器最后修改的时间和这个时间之后是否更新

    我这里是用nginx来自动生成的

    location ~* ^.+\.(swf|gif|png|jpg|js|css)$ {

      root   /usr/local/ku6/ktv/xiu.ku6.com/;

      expires 时间;

     }

    2) etag 打死我都不会用的 用不好 太耗费流量了

    附上http头信息:

    响应头信息:

    Date Mon, 02 May 2011 14:55:07 GMT

    Content-Type text/html; charset=utf-8

    Last-Modified Mon, 25 Apr 2011 07:39:09 GMT

    Vary Accept-Encoding

    Content-Encoding gzip

    X-Cache HIT from cache.fastweb.com.cn

    请求头信息:

    Host xiu.ku6.com

    User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 QQDownload/1.7

    Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

    Accept-Language zh-cn,zh;q=0.5

    Accept-Encoding gzip,deflate

    Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7

    Keep-Alive 115

    Connection keep-alive

    If-Modified-Since Mon, 25 Apr 2011 07:39:09 GMT

    Cache-Control max-age=0

    4  图片优化:

    控制图片大小

    使用png8代替256色的jpg

    Jpeg使用渐变渲染模式 提高载入速度

    使用CSS代替图片

    拼合css sprites图片

    避免img标签缩图 防止内存泄漏

    另:

    压缩inline——css、js  减少加载时间(服务器nginx也开启了gizp 这个后面另说)

    减少嵌套层级 要符合标准

    避免使用iframe标签 Iframe标签相当于新开一个浏览器窗口

    html 去掉注释及空白符

    删除非必要的html属性 防止浏览器回流页面

    内联脚本、外链脚本优化 防止阻塞

    压力测试工具

    Ab、Webbenchloadrunner

     

    Webbench -c 【】 -t 【】  “url”

     

     

     

     

    常见一些线上问题

    1 系统重启 nginx php等服务没有随机启动 解决:/etc/rc.d/rc.local

    2  502等问题 比如php进程100 mysql连接数50 解决:增大mysql连接数

    3  504 413 错误 解决:详见nginx篇

    4  权限问题 比如www用户目录跟root用户执行与写的问题

    5  nginx 110: Connection timed out 防火墙ip_conntrack哈希表满拒绝连接问题 解决:关闭防火墙 或者修改参数

    6  sql 过大 mysql报错  解决:max_allowed_packet 增大

    7  MySQL server has gone away 解决:wait_timeout interactive_timeout 增大值 

    8 端口无法访问 解决:检查防火墙设置

    9 sql 执行效率问题  解决 :explain sql和慢查询日志

    10 CLOSE_WAIT和TIME_WAIT过多  解决:修改系统参数

    11 mysql引擎的选择 (根据应用)

    12 php版本升级 与程序兼容的问题 解决:php版本日志找出差异

    13 告警与容灾处理机制

    14  程序安全(sql注入、test.php与test.php_bak svn文件)

    15 数据库count 过慢 检查引擎是否为myisam

    16 乱码问题 解决:字符集的设定

     

  • 相关阅读:
    vue-cli3中热更新失效,修改完代码之后需要手动刷新页面才能看到改变,解决办法
    数组中的数据项包含逗号则需在首尾拼接中括号[]来区分每一项,最后数组转为字符串,以及数据恢复
    组件之间的拖拽
    工作心得
    Vue重点知识
    vue-router路由
    利用注解和反射,将Bean枚举字段的值填入相应的字段中,并转化为fastjson返回前台
    db2 获取自增主键的方法
    mybatis注解@selectKey对于db2数据库的使用
    @InsertProvider 根据bean属性,自动生成插入sql语句
  • 原文地址:https://www.cnblogs.com/ldms/p/3045311.html
Copyright © 2020-2023  润新知