对于小站长来说,管理自己的服务器最轻松的事情,就是可以自己随便乱搞——装Ubuntu甚至Arch Linux做服务器、十几天就更新重启服务器一回、配上SSL还可以不管兼容性淘汰浏览器……其实我们的任性可以归结到这些:
- 服务器归少数人管理,可以完完全全按照自己的习惯放文件选系统;
- 不列入考核,服务器宕机几天也没人管你;
- 业务特少,基本上可以忽略算法调优。
(如果遇上我们学校某梯那种生成一页要3.2秒的,那还是乖乖优化吧哈哈哈哈哈…)
今天就来讲一下单服务器系统(下称“单机系统”)在各个进程之间协同工作时的一种优化方法——改TCP端口连接为Unix域套接字连接。首先我们来看下这两者有什么异同:
- 网络端口套接字是一种构建于网际协议(IP)的端点,在现今的TCP/IP网络协议下,构建于传输层(本机进程间通信)或网络互连层(非本机进程间通信)。
- Unix域套接字是一种依赖于系统文件路径的端点,一切操作均在本机内核中完成,常用于本机进程间通信。
简单点说,就是网络端口套接字可以经由网络传输,缺点就是要走一次网络架构,速度慢;Unix域套接字交换数据非常快,可以很方便地设置权限,缺点就是范围仅限本机。
讲这些!小小小小小小站长怎么可能会用cluster架自己的Web Server,哪个快换哪个呀!但是,究竟能快成怎样呢?[1]
Communication method | time | Change from previous |
---|---|---|
Unix-domain socket | 0.117 | n/a |
tcp/ip, no ssl | 0.153 | +31% |
tcp/ip, ssl | 0.420 | +175% |
这是在postgresSQL上做的一组实验,里面比较的是使用Unix域套接字和TCP协议连接的传输耗时。显然,经过TCP(没有SSL存在时)消耗的时间比Unix域套接字要多30%左右。其实,我们常见的服务器程序都能使用Unix域套接字代替TCP连接进行通信。
其实,在新版本中,很多连接默认都自动配置了Unix域套接字作为默认的本地连接方式,包括常见的MySQL甚至是系统调度都用了它。查看方法:netstat -ln
。
Nginx与PHP-FPM
常见的HTTP服务器中,Apache2与PHP运行在同一程序下,而Nginx和PHP-FPM是独立的上下游关系,可以选用Unix域套接字进行通信。
- 修改PHP-FPM配置文件中
listen
字段(以PHP7.0的ubuntu软件仓库版为例):listen = /run/php/php7.0-fpm.sock
- 修改Nginx配置文件中PHP处理段:
location ~ \.php$ { fastcgi_pass unix:/run/php/php7.0-fpm.sock; fastcgi_index index.php; include /etc/nginx/fastcgi_params; }
MySQL服务端及各种应用实例
没压岁钱了MySQL是我们用得很广泛的数据库之一,很多情况下,它其实也默认配置了Unix域套接字连接方法,而且命令mysql就是使用Unix域套接字实现连接的。
服务端的修改方法
修改或查看[mysqld]段:
socket = /var/run/mysqld/mysqld.sock
对于PHP-MySQL使用时的修改
(p)connect('localhost', 'username', 'password');
改为
(p)connect('localhost:/var/run/mysqld/mysqld.sock',
'username', 'password');
举个栗子,用面向对象实现时,没有对象的程序员在new完mysql对象后应该要这样子写连接:
$你的对象->(p)connect('localhost:/var/run/mysqld/mysqld.sock', 'username', 'password');
在修改WordPress/Typecho/emlog PHP版本/ownCloud的配置文件时,直接将localhost
换成:
localhost:/var/run/mysqld/mysqld.sock
对于Node.js使用时的修改
- 请先进行安装操作
npm install mysql socket.io
- 修改connection,删除host及port(如果有),增加如下一行:
socketPath: '/var/run/mysqld/mysqld.sock',
Nginx与Ghost博客
Ghost是一个基于Node.js的博客系统,其一种调优方法就是以Unix域套接字代替HTTP作为反代的上游。
- 修改config.js,删除production下server字段中内容,改为:
socket: {
path: '/var/www/ghost/socket.sock',
permissions: '0666'
}
- 在Nginx反代字段中,修改为:
proxy_pass unix:/var/www/ghost/socket.sock;
未完待续……
其实,搞辣么多,还不是为了让服务器提供服务时耗时少那么几个ms而已。不过,对于拥有单机系统的小站长来说,似乎更重要的是提高自己内容的质量。毕竟,自己调得辣么好,有人看么(冷漠脸)~
What’s more,有一种说法说,Unix域套接字在速度上很有优势,但是出错率也会很高。在大量运用的生产力环境中,还是习惯使用能跨机器通信的TCP。不过,这里也可以给出一点灵感供developers参考:
- Keepalive连接的运用;
- TCP Fastopen的应用;
- 建立专门的连接管理池,将开启的连接复用;
- ……
alphaxz@Home