Rootop 服务器运维与web架构

2014-04-28
发表者 Venus
暂无评论

mysql连接类型与socket通信原理说明(转)

原文:http://blog.fity.cn/post/348/

MySQL连接类型中的localhost与127.0.0.1、IP区别:
localhost与127.0.0.1的区别是什么?相信有人会说是本地ip,曾有人说,用127.0.0.1比localhost好,可以减少一次解析。 看来这个入门问题还有人不清楚,其实这两者是有区别的。

NO.1 – 普通接说:
localhost也叫local ,正确的解释是:本地服务器
127.0.0.1在windows等系统的正确解释是:本机地址(本机服务器)

NO.2:
localhost(local)是不经网卡传输!这点很重要,它不受网络防火墙和网卡相关的的限制。
127.0.0.1是通过网卡传输,依赖网卡,并受到网络防火墙和网卡相关的限制。
一般设置程序时本地服务用localhost是最好的,localhost不会解析成ip,也不会占用网卡、网络资源。
有时候用localhost可以,但用127.0.0.1就不可以的情况就是在于此。猜想localhost访问时,系统带的本机当前用户的权限去访问,而用ip的时候,等于本机是通过网络再去访问本机,可能涉及到网络用户的权限。

NO.3 – MySQL被连接时主机类型:
1、 mysql -h 127.0.0.1 的时候,使用TCP/IP连接,
mysql server 认为该连接来自于127.0.0.1或者是”localhost.localdomain”
2、mysql -h localhost 的时候,是不使用TCP/IP连接的,而使用Unix socket;
此时,mysql server则认为该client是来自”localhost”

在mysql权限管理中的”localhost”有特定含义:
—— MySQL手册 5.6.4 ….. A Host value may be a hostname or an IP number, or ‘localhost’ to indicate the local host.

注意:虽然两者连接方式有区别,但当localhost 为默认的127.0.0.1时,两种连接方式使用的权限记录都是以下的记录(因为记录在前,先被匹配)
Host: localhost
User: root

MySQL连接类型证明:

# mysql -h 127.0.0.1  -u root -pfity.cn#123
ERROR 2003 (HY000): Can’t connect to MySQL server on ‘127.0.0.1’ (111)[需要指定端口,反之收到这个错误]

# mysql -h 127.0.0.1 -P 3307 -u root -pfity.cn#123

mysql> status;
————–
mysql  Ver 14.12 Distrib 5.0.95, for redhat-linux-gnu (i686) using readline 5.1

Connection id:          1599
Current database:
Current user:           root@127.0.0.1
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ”
Using delimiter:        ;
Server version:         5.1.48-log Source distribution
Protocol version:       10
Connection:             127.0.0.1 via TCP/IP  //注意这里
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    latin1
Conn.  characterset:    latin1
TCP port:               3307
Uptime:                 5 hours 54 min 48 sec

Threads: 1  Questions: 5432  Slow queries: 1619  Opens: 72  Flush tables: 1  Open tables: 65  Queries per second avg: 0.255
————–

# mysql -h 192.168.1.246  -u root -pfity.cn#123

ERROR 2003 (HY000): Can’t connect to MySQL server on ‘192.168.1.246’ (111)[需要指定端口,反之收到这个错误]

# mysql -h 192.168.1.246 -P 3307 -u root -pfity.cn#123

mysql> status;
————–
mysql  Ver 14.12 Distrib 5.0.95, for redhat-linux-gnu (i686) using readline 5.1

Connection id:          1598
Current database:
Current user:           root@192.168.1.246
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ”
Using delimiter:        ;
Server version:         5.1.48-log Source distribution
Protocol version:       10
Connection:             192.168.1.246 via TCP/IP    //注意这里
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    latin1
Conn.  characterset:    latin1
TCP port:               3307
Uptime:                 5 hours 53 min 54 sec

Threads: 1  Questions: 5428  Slow queries: 1619  Opens: 72  Flush tables: 1  Open tables: 65  Queries per second avg: 0.255
————–

# mysql -h localhost  -u root -pfity.cn#123[连接OK]

# mysql -h localhost -P 3307 -u root -pfity.cn#123

mysql> status;
————–
mysql  Ver 14.12 Distrib 5.0.95, for redhat-linux-gnu (i686) using readline 5.1

Connection id:          1600
Current database:
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ”
Using delimiter:        ;
Server version:         5.1.48-log Source distribution
Protocol version:       10
Connection:             Localhost via UNIX socket    //注意这里
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    latin1
Conn.  characterset:    latin1
UNIX socket:            /var/lib/mysql/mysql.sock
Uptime:                 5 hours 56 min 18 sec

Threads: 1  Questions: 5436  Slow queries: 1619  Opens: 72  Flush tables: 1  Open tables: 65  Queries per second avg: 0.254
————–

从这里看以看出,通过通过unix domain socket方式连接mysql时,你不需要特意指定端口,按照mysql官方所说通过unix domain socket方式连接mysql较快于TCP/IP方式。不过,如果通过socket方式连接mysql,当mysql.sock文件不再是默认的名称或存放路径时,你将会收到下面这个错误信息,当然,你可以需要在php代码config中声明一个变量指定unix domain socket路径或者在php.ini配置文件中定义也可。错误信息如下:
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2)

默认情况下我们PHP实例和mysql通信是走TCP/IP的,但如果你加载了socket模块,默认会走sock文件连接,但如果你的linux主机上没有指定默认的socket文件,这样如果你使用mysql_connect连接的话,经常我们使用mysql_connect()或socket方式连接mysql时会收到错误:
No such file or directory、Can’t connect to local MySQL server through socket… ,如图:

然而此时mysql客户端可以正常使用,当然此刻你通过mysqli或pdo方式连接一般情况下也是不会有错误的,所以可以确定不是服务器的问题。

简而言之:主要区别是localhost是通过unix domain socket方式来连接,而127.0.0.1则是走的TCP协议方式连接
这是linux套接字网络的特性,win平台不会有这个问题

php.ini文件中如何定义mysql socket路径:
mysql.default_socket = mysql.sock //绝对路径就可以了
或者你可以在my.cnf文件中把mysql.sock路径指向/tmp/mysql.sock也可以

请注意,如果你指定localhost作为一个主机名,mysqladmin默认使用Unix套接字文件连接,而不是TCP/IP。从 MySQL 4.1开始,通过–protocol= TCP | SOCKET | PIPE | MEMORY}选项,你可以显示地指定连接协议。

Socket简要通信机制与原理说明
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。

服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。

客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

2014-04-28
发表者 Venus
暂无评论

测试udp端口

在tcp下可以通过telnet来检测一个目标端口是否开放。
那么对于udp协议来说用telnet方式无法测试。
这里在linux下有一个叫nc的软件,可以检测udp协议端口是否开放。
[root@localhost ~]# yum install nc -y
[root@localhost ~]# nc -vuz 192.168.0.127 123
Connection to 192.168.0.127 123 port [udp/ntp] succeeded!
#检测目标123端口是否开放

nc命令用法:
usage: nc [-46DdhklnrStUuvzC] [-i interval] [-p source_port]
[-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_version]
[-x proxy_address[:port]] [hostname] [port[s]]

2014-04-27
发表者 Venus
暂无评论

fastdfs+nginx配置

这里只是将原先的fastdfs+apache改为nginx,之前的搭建过程可参考 :

https://www.rootop.org/pages/2431.html

接着上次的配置环境,现在将apache改为nginx。

在两台storage服务器上配置nginx和fastdfs-nginx模块:
storage_s1:
下载pcre、nginx、fastdfs的nginx模块,编译:

[root@centos-6.5-x64 ~]#wget -c http://fastdfs.googlecode.com/files/fastdfs-nginx-module_v1.15.tar.gz
[root@centos-6.5-x64 ~]#tar zxvf fastdfs-nginx-module_v1.15.tar.gz
[root@centos-6.5-x64 ~]#tar zxvf pcre-8.12.tar.gz
[root@centos-6.5-x64 ~]#tar zxvf nginx-1.5.10.tar.gz
[root@centos-6.5-x64 ~]#cd pcre-8.12
[root@centos-6.5-x64 pcre-8.12]#./configure --prefix=/usr/
[root@centos-6.5-x64 pcre-8.12]#make && make install
[root@centos-6.5-x64 pcre-8.12]#cd ..
[root@centos-6.5-x64 ~]#cd nginx-1.5.10
[root@centos-6.5-x64 nginx-1.5.10]#useradd www -s /sbin/nologin
[root@centos-6.5-x64 nginx-1.5.10]#yum install zlib zlib-devel -y
[root@centos-6.5-x64 nginx-1.5.10]#./configure --prefix=/usr/local/nginx --user=www --group=www --add-module=../fastdfs-nginx-module/src/
[root@centos-6.5-x64 nginx-1.5.10]#make && make install

配置nginx:
[root@centos-6.5-x64 ~]#vi /usr/local/nginx/conf/nginx.conf
在server段中添加:

location /group1/M00 {
 root /mnt/fastdfs_storage_data/data;
 ngx_fastdfs_module;
 }

配置etc/fdfs/mod_fastdfs.conf配置文件(编译时会自动拷贝过去)
[root@centos-6.5-x64 fdfs]#grep -v “#” mod_fastdfs.conf | grep -v “^$”
connect_timeout=2
network_timeout=30
base_path=/tmp
load_fdfs_parameters_from_tracker=true
storage_sync_file_max_delay = 86400
use_storage_id = false
storage_ids_filename = storage_ids.conf
tracker_server=192.168.1.60:22122
storage_server_port=23000
group_name=group1
url_have_group_name = true
store_path_count=1
store_path0=/mnt/fastdfs_storage_data
log_level=info
log_filename=
response_mode=proxy
if_alias_prefix=
http.need_find_content_type=false
flv_support = true
flv_extension = flv
group_count = 0

启动nginx:
[root@centos-6.5-x64 conf]#/usr/local/nginx/sbin/nginx &
[1] 9358
[root@centos-6.5-x64 conf]#ngx_http_fastdfs_set pid=9358
[1]+ Done /usr/local/nginx/sbin/nginx
[root@centos-6.5-x64 ~]#lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 10240 root 6u IPv4 21835 0t0 TCP *:http (LISTEN)
nginx 10241 nobody 6u IPv4 21835 0t0 TCP *:http (LISTEN)
[1]+ Done /usr/local/nginx/sbin/nginx

完成

storage_s2:
配置跟storage_s1完全一样,过程略。

在客户端上传文件,访问文件的web路径,测试storage_s1、storage_s2通过。
停掉storage_s2的storage服务,客户端上传一个新文件,根据提示得知:
group_name=group1, remote_filename=M00/00/00/wKgBPVNb4hOAM7lhAAAADw_r4o417.html
source ip address: 192.168.1.61
文件上传到storage_s1服务器,现在访问storage_s2服务器的文件url。发现正常访问,表明fastdfs-nginx-module起作用了。

PS:
查看已有的nginx编译参数:
[root@centos-6.5-x64 nginx-1.5.10]#/usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.5.10
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
configure arguments: –prefix=/usr/local/nginx –user=www –group=www
nginx不像apache一样可以通过 apxs -i -a -c mod_rewrite.c 这种方式单独安装模块,需要重新编译。
所以需要知道之前nginx的编译参数。

2014-04-26
发表者 Venus
暂无评论

一次mfs恢复数据

今天web服务器发现挂载的分布式文件系统mfs无法访问,去mfsmaster检查发现服务器没有启动。
启动服务器,登陆,查看没有mfs进程,端口都没启动,手动启动服务,提示错误:
[root@centos-6.5-x64 ~]#/usr/local/mfs/sbin/mfsmaster start
working directory: /usr/local/mfs/var/mfs
lockfile created and locked
initializing mfsmaster modules …
loading sessions … ok
sessions file has been loaded
exports file has been loaded
loading metadata …
can’t open metadata file
if this is new instalation then rename metadata.mfs.empty as metadata.mfs
init: file system manager failed !!!
error occured during initialization – exiting
根据提示判断为mfs启动时认为这是一台新的mfsmaster,需要rename metadata.mfs.empty as metadata.mfs

这完全不是新服务器,赶紧恢复日志:                                                                     [root@centos-6.5-x64 var]#tar zcvf mfs.tar.gz mfs/  #防止意外,把整个数据日志信息目录备份
[root@centos-6.5-x64 mfs]#/usr/local/mfs/sbin/mfsmetarestore -m metadata.mfs.back -o metadata.mfs changelog.*.mfs
loading objects (files,directories,etc.) … loading node: read error: Success
error
can’t read metadata from file: metadata.mfs.back
看样子metadata.mfs.back文件损坏。
赶紧查资料:http://blog.ztrix.me/blog/2012/05/13/restore-mfs-metadata/
根据资料查看我本地linux文件系统确实是ext4,可以判断跟资料上的情况一样了,可是我不会像文章写的一样会编程寻找数据。

遂再次检查:
[root@centos-6.5-x64 mfs]#ll
总用量 1724
-rw-r—– 1 mfs mfs 8543 4月 26 11:09 changelog.0.mfs
-rw-r—– 1 mfs mfs 4246 4月 26 11:09 changelog.10.mfs
-rw-r—– 1 mfs mfs 3368 4月 26 11:09 changelog.11.mfs
-rw-r—– 1 mfs mfs 8543 4月 26 11:09 changelog.1.mfs
-rw-r—– 1 mfs mfs 51757 4月 26 11:09 changelog.2.mfs
-rw-r—– 1 mfs mfs 183976 4月 26 11:09 changelog.3.mfs
-rw-r—– 1 mfs mfs 4901 4月 26 11:09 changelog.4.mfs
-rw-r—– 1 mfs mfs 1796 4月 26 11:09 changelog.5.mfs
-rw-r—– 1 mfs mfs 1502 4月 26 11:09 changelog.6.mfs
-rw-r—– 1 mfs mfs 599839 4月 26 11:09 changelog.7.mfs
-rw-r—– 1 mfs mfs 4383 4月 26 11:09 changelog.8.mfs
-rw-r—– 1 mfs mfs 4988 4月 26 11:09 changelog.9.mfs
-rw-r—– 1 mfs mfs 81920 4月 26 11:09 metadata.mfs.back
-rw-r—– 1 mfs mfs 147081 4月 26 11:09 metadata.mfs.back.tmp
-rw-r–r– 1 root root 8 4月 26 11:09 metadata.mfs.empty
-rw-r—– 1 mfs mfs 10541 4月 26 11:09 sessions.mfs
-rw-r—– 1 mfs mfs 610016 4月 26 11:09 stats.mfs
[root@centos-6.5-x64 mfs]#rm -f metadata.mfs.back
[root@centos-6.5-x64 mfs]#mv metadata.mfs.back.tmp metadata.mfs.back
发现有个metadata.mfs.back.tmp文件,把之前的metadata.mfs.back删掉,metadata.mfs.back.tmp改名metadata.mfs.back
恢复日志:
[root@centos-6.5-x64 mfs]#/usr/local/mfs/sbin/mfsmetarestore -m metadata.mfs.back -o metadata.mfs changelog.*.mfs
loading objects (files,directories,etc.) … ok
loading names … ok
loading deletion timestamps … ok
checking filesystem consistency … ok
loading chunks data … ok
connecting files and chunks … ok
applying changes from file: changelog.0.mfs
meta data version: 22443
version after applying changelog: 22698
applying changes from file: changelog.10.mfs
meta data version: 22698
version after applying changelog: 22698
applying changes from file: changelog.11.mfs
meta data version: 22698
version after applying changelog: 22698
applying changes from file: changelog.1.mfs
meta data version: 22698
version after applying changelog: 22698
applying changes from file: changelog.2.mfs
meta data version: 22698
version after applying changelog: 22698
applying changes from file: changelog.3.mfs
meta data version: 22698
version after applying changelog: 22698
applying changes from file: changelog.4.mfs
meta data version: 22698
version after applying changelog: 22698
applying changes from file: changelog.5.mfs
meta data version: 22698
version after applying changelog: 22698
applying changes from file: changelog.6.mfs
meta data version: 22698
version after applying changelog: 22698
applying changes from file: changelog.7.mfs
meta data version: 22698
version after applying changelog: 22698
applying changes from file: changelog.8.mfs
meta data version: 22698
version after applying changelog: 22698
applying changes from file: changelog.9.mfs
meta data version: 22698
version after applying changelog: 22698
store metadata into file: metadata.mfs

太好了,没报错,启动服务:
[root@centos-6.5-x64 mfs]#/usr/local/mfs/sbin/mfsmaster start

working directory: /usr/local/mfs/var/mfs
lockfile created and locked
initializing mfsmaster modules …
loading sessions … ok
sessions file has been loaded
exports file has been loaded
loading metadata …
loading objects (files,directories,etc.) … ok
loading names … ok
loading deletion timestamps … ok
checking filesystem consistency … ok
loading chunks data … ok
connecting files and chunks … ok
all inodes: 1622
directory inodes: 124
file inodes: 1498
chunks: 1485
metadata file has been loaded
stats file has been loaded
master <-> metaloggers module: listen on *:9419
master <-> chunkservers module: listen on *:9420
main master server module: listen on *:9421
mfsmaster daemon initialized properly
[root@centos-6.5-x64 mfs]#
[root@centos-6.5-x64 mfs]#ps aux | grep mfs
root 1556 0.0 0.4 170416 460 ? S 10:51 0:00 python /usr/local/mfs/sbin/mfscgiserv start
mfs 1946 6.2 43.1 82056 46196 ? S< 11:16 0:00 /usr/local/mfs/sbin/mfsmaster start
root 1948 2.0 0.7 103256 844 pts/0 S+ 11:17 0:00 grep mfs
服务启动,去web服务器查看,数据出来了。

转来的丢失原因:

ext4 文件系统的 delay allocation 导致的。moosefs 在持久化 metadata 信息的时候,会重写整个文件。他会首先把之前的 metadata.mfs.back 文件重命名成 metadaba.mfs.back.tmp,然后开始写 metadata.mfs.back 文件,写完了 fclose 之后,删除 metadata.mfs.back.tmp。如果断电的时候,正常在进行这么一个过程,那么有可能 fclose 之后,metadata.mfs.back.tmp 也删除了,但是 ext4 的 delay allocation 特性导致文件还没有真正写入到磁盘。(也有可能文件写入了磁盘 block,但是文件 inode 还没有更新)。我们在网上发现有不少人也遇到过同样的断电之后文件大小变成 0 的问题,如这个:http://www.symantec.com/connect/blogs/ext4-data-recovery-how-recovery-lost-files-ext4-file-system-linux
有可能是 moosefs 写 metadata 失败导致的。阅读了相关源代码之后,我们发现 moosefs 写文件和 fclose 的时候居然从来不判断返回值!有些地方有判断返回值,但是也仅仅打印一句 log,既不做相应错误处理,也不停止。于是就有可能是写文件失败,fclose 也失败,但是它不查返回值,所以又把之前的 metadata.mfs.back.tmp 删除了。
有可能是 ext4 修复导致的。断电造成文件系统出现不一致,然后自动修复之后造成了数据丢失。

这样一来,强烈建议将mfs的文件系统改为ext3上运行。

PS:

环境中有一台mfs slave机器做备份机,发现备份机也出问题,当我加电给master时,任务计划每个一分钟同步数据日志到备机,导致备机的日志也出错。

考虑到的方案:

在一台chunkserver中添加mfslog服务,每1小时获取一次master日志,定时备份数据日志目录。把损失降到最小。