php下数据库持久连接,及apache模块下“数据库并发连接数超限”的潜在风险

php下的多个数据库引擎都提供持久连接的特性,实现了“连接池”的作用,让数据库连接“复用”,目的是减少php引擎连接数据库的消耗。这有类似fastCGI协议的设计初衷:让后端进程复用,节省启动关闭CGI进程的性能开锁。

数据库持久连接的实现方式

这需要从php的运行模式说起。典型的php运行模式是传统CGI、fastCGI、web模块三种。

其中CGI模式不支持持久连接,因为php每次处理请求,都是由一个独立的进程(操作系统的进程)处理,请求处理完毕,进程就销毁了,相应的数据连接之类的资源当然也已不存在,所以CGI本身是不支持持久连接的。

fastCGI模式下,php进程由进程管理器所管理。(apache下实现实例,参看这里)。不管哪种fastCGI方案,其背后都是一系列长期运行的进程(操作系统下的进程),进程本身可以保持资源,因此,php脚本引擎可以提供应用的接口,允许程序员将数据库连接保持下来,供下次php处理请求,可以直接复用这个连接。

web模块下,类似fastCGI模式。linux下apache默认prefork下,每个httpd进程在同一时刻只响应一个http请求,每个httpd进程可以看做一个fastCGI进程。

多数据库账号的持久连接

假设一web服务器下的所有应用,都是持久连接,并且使用了惟一的数据库连接账号。假设共开了10个fastCGI进程在运行,每个进程都保持了一个持久连接,如果当前处理请求需要连接数据库,直接使用该持久连接即可,不需要新连接数据库。事实上,运行一段时间后,就是这样状态。

假设该web服务器下的应用,共有10个数据库连接账号。每fastCGI进程,从启动开始,每处理一个新的数据库账号相关的请求,就要多保持一个持久连接。因为不同数据库账号的连接,肯定不能复用的。这样,在运行一段时间后,每个fastCGI进程都要维持10个持久连接,分别对应每个数据库账号。

以apache模块模式下运行的httpd进程,可以等同于一个fastCGI进程,上面讨论同样适用。

进程数及连接数讨论,及apache下的潜在风险!

如果web服务器下的的php应用,分别使用了多个数据库账号,而且全部连到同一台数据库服务器。这样,

该数据库的并发连接数 = fastCGI进程数 * 数据库账号数
如果php在apache模块下运行,使用httpd进程数代替fastCGI进程数

通常,fastCGI进程数量是比较有限的,对于一台web服务器,它接受的请求里,大多数请求都是静态的(想像一下,一个页面里,通常只有主html文档是动态,而里面的js,css,图片等等元素都是静态;这里不考虑“静态内容全部移到CDN上”的极端情况)。fastCGI进程数数,通常会远比http并发数小。

在apache模块运行的php下,所有请求都是由httpd进程处理的,每个httpd进程都有可能维护每个数据库用户相关的持久连接,如果数据库用户量较大,这个对mysql服务器并发的连接数影响非常大。通常mysql服务器都会设置一个最大并发数据,超过限制后,就不再受新连接!

php下持久连接的更多信息,参考官方文档 http://php.net/manual/zh/features.persistent-connections.php

 

mac port 更新报错:Error installing new MacPorts base: command execution failed

核心提示:

回想你是不是更新过xcode,而且更新过后,还没有使用过。如果是,请同意一下命令行版的用户协议,终端里运行

sudo xcodebuild -license

然后按提示输入 agree,完了重试port更新。

如果不是这样,那请转到google搜索,并啃英文资料吧。

其实只需要看到这里就够了,下面是发现这一点的过程,可以认为是废话,不推荐继续阅读;读了也不多,多花费一点时间而已。

继续阅读

使用nginx配置http代理

环境

centos 6.5

有网络连接的正常环境

安装nginx

这里使用nginx官方的yum安装(推荐),其它方式安装类似。

rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm

详细参考nginx官方yum源说明 http://nginx.org/en/linux_packages.html#stable

配置ngix

nginx官方出二进制rpm包,其配置沿用redhat/centos的习惯,很清晰明了,配置文件位于 /etc/nginx 目录下,文件如下

[root@iZ11du3hojgZ ~]# ls -lh /etc/nginx/
total 36K
drwxr-xr-x 2 root root 4.0K Nov 30 14:13 conf.d
-rw-r--r-- 1 root root  964 Apr 21  2015 fastcgi_params
-rw-r--r-- 1 root root 2.8K Apr 21  2015 koi-utf
-rw-r--r-- 1 root root 2.2K Apr 21  2015 koi-win
-rw-r--r-- 1 root root 3.9K Apr 21  2015 mime.types
-rw-r--r-- 1 root root  643 Apr 21  2015 nginx.conf
-rw-r--r-- 1 root root  596 Apr 21  2015 scgi_params
-rw-r--r-- 1 root root  623 Apr 21  2015 uwsgi_params
-rw-r--r-- 1 root root 3.6K Apr 21  2015 win-utf

其中主配置文件是 /etc/nginx/nginx.conf,站点配置位于conf.d/ 子目录,每个站点一个文件(默认只有一个default.conf)

直接在default.conf配置文件上修改(改之前可以做个备份,如果就地备份在/etc/nginx/conf.d/目录里,文件名后缀不要是 .conf,否则会被nginx当配置文件加载)

设置站点监听及dns服务器

server{...}节点里,

  1. 修改listen指令,改一下端口,并增加 default 参数,设置成默认nginx站点
  2. 增加resolver 指令,设置域名解析服务器。这里使用dnspod的公共dns服务器如果;国外服务器可以使用google的8.8.8.8等。

location{...}子节点里,

  1. 注释掉root及index两行,当然删除也可以。
  2. 添加一系列proxy_xxx指令。最主要是proxy_pass及proxy_set_header 设置Host头两项,其它是一些参数优化。

设置允许使用代理服务的ip地址。虽然这一步不是必须,但强烈建议配置,避免代理服务器被别人冒用,带宽是宝贵的。不要以为你没公开代理就没人知道,要知道互联网上有无数个代理扫描时刻在偷偷运行着!

 

  1. 设置allow地址白名单。
  2. deny all禁止掉其它所有地址。

 

全部相关配置如下:

server {
    listen       8080 default;
    server_name  localhost;
    resolver 119.29.29.29;
    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;
    .....[略]
    location / {
        #root   /usr/share/nginx/html;
        #index  index.html index.htm;
        proxy_pass $scheme://$host$request_uri;
        proxy_set_header Host $http_host;

        proxy_buffers 256 4k;
        proxy_max_temp_file_size 0;
        proxy_connect_timeout 30;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 301 1h;
        proxy_cache_valid any 1m;
    }
    .....[略]
    allow 100.200.100.0/24;
    deny all;
}

已知缺陷

不支持https,虽然配置文件里proxy_pass指令使用了可以支持非http协议的通用的形式。事实上这里直接写成http://也是可以的。

参考

nginx proxy模块文档

nginx http access模块文档

使用stat命令在shell中读取文件状态(修改时间,大小,权限模式,磁盘占用)

通常我们通过ls 命令显示文件信息,查看目录信息时,再加上参数 -d 。这没有错,看总觉得不方便,尤其是不能显示文件修改时间,访问时间什么的,时间一列显示有时并不方便阅读。这种情况下,你需要的是stat命令,尤其适合查阅单个文件信息。

尤其是,在编写shell脚本时,stat绝对比从ls里面截取方便得多,而且更高的自由度!

stat命令简单示例

列表出文件的一系列摘要信息:

[root@localhost ~]# stat install.log
  File: "install.log"
  Size: 7730            Blocks: 16         IO Block: 4096   普通文件
Device: fd00h/64768d    Inode: 1048578     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-10-20 10:21:05.473712000 +0800
Modify: 2015-10-20 10:23:50.061712001 +0800
Change: 2015-10-20 10:23:56.028712002 +0800
[root@localhost ~]#

很自然,它不包含任何文件内容,事实上该命令读不出文件内容,它也不会去读。

查看指定目录的stat

[root@localhost ~]# stat .
  File: "."
  Size: 4096            Blocks: 8          IO Block: 4096   目录
Device: fd00h/64768d    Inode: 1048577     Links: 5
Access: (0550/dr-xr-x---)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-10-27 13:35:30.473108443 +0800
Modify: 2015-10-21 18:54:30.420109149 +0800
Change: 2015-10-21 18:54:30.420109149 +0800
[root@localhost ~]#

玩点高级一点的

上次访问时间:

[root@localhost ~]# stat -c %x install.log
2015-10-20 10:21:05.473712000 +0800

文件大小

[root@localhost ~]# stat -c %s install.log
7730

同时并格式化输出多个参数

$ stat --printf="%n %X %s" plan.jpg
plan.jpg 1445912536 197196

更多使用方法,参考联机帮助或手册

联机帮助:

[root@localhost ~]# stat --help
用法:stat [选项]... 文件...
Display file or file system status.

-L, --dereference     follow links
-Z, --context         print the SELinux security context
-f, --file-system     display file system status instead of file status
-c --format=格式      使用指定输出格式代替默认值,每用一次指定格式换一新行
--printf=格式     类似 --format,但是会解释反斜杠转义符,不使用换行作
输出结尾。如果您仍希望使用换行,可以在格式中
加入"\n"
-t, --terse           使用简洁格式输出
--help            显示此帮助信息并退出
--version         显示版本信息并退出

有效的文件格式序列(不使用 --file-system):

%a    八进制权限
%A   用可读性较好的方式输出权限
%b   计算已分配块数(参见%B)
%B   以字节为单位输出%b 所报告的每个块的大小
%C   SELinux 安全环境字符串
%d    十进制设备编号
%D    十六进制设备编号
%f    十六进制原始模式
%F    文件类型
%g    文件的属组ID
%G    文件的属组组名
%h    硬链接数量
%i    Inode 编号
%n    文件名
%N    如果对象是一个符号链接,显示引用到的其它文件名
%o    I/O 块大小
%s    总计大小,以字节为单位
%t    十六进制主设备类型
%T    十六进制子设备类型
%u    文件的属主ID
%U    文件的属主用户名
%x    上次访问时间
%X    从UNIX 元年起计的上次访问时间
%y    上次修改时间
%Y    从UNIX 元年起计的上次修改时间
%z    上次更改时间
%Z    从UNIX 元年起计的上次更改时间

有效的文件系统格式序列:

%a    非超级用户可用的剩余块数
%b    文件系统的总数据块数
%c    文件系统中文件节点总数
%d    文件系统中空闲文件节点数
%f    文件系统中空闲块数
%C    SELinux 安全环境字符串
%i    十六进制文件系统ID
%I    允许的文件名最大长度
%n    文件名
%s    块大小(用于快速传输)
%S    基本块大小(用于块计数)
%t    十六进制类型描述
%T    可读性较好的类型描述

注意:您的shell 内含自己的stat 程序版本,它会覆盖这里所提及的相应
版本。请查阅您的shell 文档获知它所支持的选项。

请向bug-coreutils@gnu.org 报告stat 的错误
GNU coreutils 项目主页:<http://www.gnu.org/software/coreutils/>
GNU 软件一般性帮助:<http://www.gnu.org/gethelp/>
请向<http://translationproject.org/team/zh_CN.html> 报告stat 的翻译错误
要获取完整文档,请运行:info coreutils 'stat invocation'

linux下tar命令的奇葩用法(可用来保留目录修改时间的复制整个目录)

linux下tar命令的奇葩用法:
tar -cvf - /etc | tar -xvf -

其中 /etc 可以改成任何需要备份的目录
以前在鸟哥linux里 http://linux.vbird.org/linux_basic/0240tarcompress.php#tar 见到的,当时不知道有什么用:这不就是cp -r,干吗写这么啰嗦。原来它可“原封不动”的备份,包括文件目录的修改时间;cp -r复制出来的目录修改时间是当前时间。要将一个目录复制一下,可又想保留目录修改时间(这是时间非常有用),之前是tar打包的,用的时候再解开(或当场就解开,并删除tar包);突然意识到,tar的这个奇葩用户正是所需!

 

linux bash下find命令之-exec参数多次使用{}处理匹配到文件

问题:

使用find命令查询旧文件文件,并删除,但又想在删除前看一下文件名,大致监测一下进度。不过在exec参数里直接使用两次{}会报错,google后,找到方法,使用sh "代理"一下,直接上代码:

find . -atime +150 -exec sh -c 'ls -lh {} ; rm {}' \;

注意加粗着色部分及其单引号。

特殊字符比较多,转载时容易出问题,再截张图,对照参考

bash_find_match_multi_use

参考:http://blog.csdn.net/duanlove/article/details/8261677
该文还介绍了其它可选方案。

后记:前面例子,只为演示功能,事实上只要给rm 带上  -v 参数即可,感谢sdfsaf指正,如下

find . -atime +150 -exec rm -v {} \;

java jdk下载-通过海外vps快速下载jdk的方法及/抓包wget

我朝网络真牛x,连接海外很多站点速度都奇慢。印象中以前从java/oracle下载jdk还不算是太慢。今天下载macintosh os x版的jdk,竟然几乎不会动,要10个小时,这还是30M企业版电信光纤吗!找了几个国内的下载站,竟然没有,难道是oracle不让做镜像下载所致?

有个海外vps,就是本站所在的服务器,平时下载海外的东西,如果太慢,通常就使用百度网盘,或vps上下载,做个中转;有时甚至会两个一起用。

但jkd的下载链接不行,下载链接带授权参数的。

想起live http headers,抓包,看看请求里是什么东西,wget模拟请求,理论上只要参数齐就可以的。wgtet一下,发现是三次请求,通过302转向到一个带AuthParm的get参数的地址上,那就直接在vp上wget它,看行不行;如果不行,再带其它参数,反正wget 有随便加http参数的功能。竟然果然是可以下载的,省事,连其它参数都不用加了!

ok,中转下载成功。

vps速度不稳,也要20多分钟的样子,但总比10个小时强得多了,慢慢等吧,还有10M

继续阅读