使用Unix域套接字加速单机系统

对于小站长来说,管理自己的服务器最轻松的事情,就是可以自己随便乱搞——装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域套接字进行通信。

  1. 修改PHP-FPM配置文件中listen字段(以PHP7.0的ubuntu软件仓库版为例):
    listen = /run/php/php7.0-fpm.sock
  2. 修改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使用时的修改

  1. 请先进行安装操作
    npm install mysql socket.io
  2. 修改connection,删除host及port(如果有),增加如下一行:
    socketPath: '/var/run/mysqld/mysqld.sock',

Nginx与Ghost博客

Ghost是一个基于Node.js的博客系统,其一种调优方法就是以Unix域套接字代替HTTP作为反代的上游。

  1. 修改config.js,删除production下server字段中内容,改为:
    socket: {
      path: '/var/www/ghost/socket.sock',
      permissions: '0666'
    }
  2. 在Nginx反代字段中,修改为:
    proxy_pass unix:/var/www/ghost/socket.sock;

未完待续……


其实,搞辣么多,还不是为了让服务器提供服务时耗时少那么几个ms而已。不过,对于拥有单机系统的小站长来说,似乎更重要的是提高自己内容的质量。毕竟,自己调得辣么好,有人看么(冷漠脸)~

What’s more,有一种说法说,Unix域套接字在速度上很有优势,但是出错率也会很高。在大量运用的生产力环境中,还是习惯使用能跨机器通信的TCP。不过,这里也可以给出一点灵感供developers参考:

  • Keepalive连接的运用;
  • TCP Fastopen的应用;
  • 建立专门的连接管理池,将开启的连接复用;
  • ……

alphaxz@Home

References

[1]. Bruce Momjian: Postgres Blog

发表评论

电子邮件地址不会被公开。 必填项已用*标注