关于 unix socket 的概念与应用
socket通信有以下二种,
-
Internet domain socket
基于网络协议栈的,是网络中不同主机之间的通讯,需要明确IP和端口。 -
unix domain socket
同一台主机内不同应用不同进程间的通讯,不需要基于网络协议,不需要打包拆包、计算校验和、维护序号和应
答等,只是将应用层数据从一个进程拷贝到另一个进程,主要是基于文件系统的,它可以用于同一台主机上两个
没有亲缘关系的进程,并且是全双工的,提供可靠消息传递(消息不丢失、不重复、不错乱)的IPC机制,效率
会远高于tcp短连接。与Internet domain socket类似,需要知道是基于哪一个文件(相同的文件路径)来通
信的。
unix domain socket有2种工作模式一种是SOCK_STREAM,类似于TCP,可靠的字节流。另一种是SOCK_DGRAM,
类似于UDP,不可靠的字节流。
实际上,unix socket 相较于TCP通讯效率要提高不少,建议使用。
1、unix domain socket
工作模型
socket通信有一个服务端,一个客服端
服务端:创建socket—绑定文件(端口)—监听—接受客户端连接—接收/发送数据—…—关闭
客户端:创建socket—绑定文件(端口)—连接—发送/接收数据—…—关闭
绝大部分服务在对外提供了TCP连接的同时,也会提供基于unix socket的连接,比如,我们常用的 php-fpm, redis
, mysql 等,我们只要将服务的监听端口改成监听某个 xxx.sock
文件就可以了,然后客户端的连接也使用socket的
方式(就是将原来的 127.0.0.1:9000
换成 /usr/local/php/php-fpm.sock
即可,因为是本机嘛),其他的不用变。
单机内使用 unix sock 替换掉TCP连接
-
nginx --> php-fpm
1、修改php-fpm配置
vi /etc/php-fpm.d/www.conf
listen = 127.0.0.1:9000 改为 listen = /var/run/unix_sock_file/php-fpm.sock
2、修改nginx转发
vi /etc/nginx/nginx.d/default.conf
fastcgi_pass 127.0.0.1:9000; 改为 fastcgi_pass unix:/var/run/unix_sock_file/php-fpm.sock; -
php --> redis
1、修改redis服务
vi /usr/local/redis/redis.conf
unixsocket /var/run/unix_sock_file/redis.sock
unixsocketperm 777
2、php连接
$redis->connect(’/var/run/unix_sock_file/redis.sock’); -
php --> mysql
mysql5.7
1、修改 my.cnf
vi /etc/my.cnf
socket=/var/run/unix_sock_file/mysql.sock
2、php连接
在PDO的DSN里面:原来写host:xxx,改成 unix_socket:
PDO:改动 $dsn
将 $dsn = ‘mysql:dbname=testdb;host=127.0.0.1;port=3306’;
改成 $dsn = ‘mysql:dbname=testdb;unix_socket=/var/run/unix_sock_file/mysql.sock’;
try{
$dsn = 'mysql:dbname=information_schema;unix_socket=/var/run/unix_sock_file/mysql.sock';
$pdo = new PDO($dsn, 'root', 'Rxy123**');
var_dump($pdo);
}catch(PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}
Mysqli扩展
$db = new mysqli('', 'root', 'Rxy123**', 'information_schema', null, '/var/run/unix_sock_file/mysql.sock');
if($db->connect_error){
die('Connect Error (' . $db->connect_errno . ') ' . $db->connect_error);
}else{
var_dump($db);
}
3、如果连不上,有可能是账号的权限问题,因为用unix socket方式连接mysql,mysql会强制认为用户是来自于localhost,所以一
定要给username@localhost权限,而不是username@’%’