rsync命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。 rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面就对它的选项一一进行分析说明。
命令说明地址:http://man.linuxde.net/rsync
官网地址: https://rsync.samba.org/

 1. 源码安装
?
1
2
3
4
5
6
7
8
9
10
11
12
13
  
#下载
wget -c https://download.samba.org/pub/rsync/src/rsync-3.1.3.tar.gz
#解压
tar -xf rsync-3.1.3.tar.gz
#进入
cd rsync-3.1.3
#配置 生成Makefile
./configure
#编译 && 安装
make && make install
 
  

 2. 常用命令选项

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  
-v, --verbose 详细模式输出
-q, --quiet 精简输出模式
-c, --checksum 打开校验开关,强制对文件传输进行校验
-a, --archive 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD
-r, --recursive 对子目录以递归模式处理
-R, --relative 使用相对路径信息
-b, --backup 创建备份,也就是对于目标已经存在有同样的文件名时,将老的文件重新命名为~filename。可以使用--suffix选项来指定不同的备份文件前缀。
--backup-dir=DIR 将备份文件(如~filename)存放在哪个目录下。
--suffix=SUFFIX 定义备份文件前缀
-u, --update 仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件)
-l, --links 保留软链结
-L, --copy-links 像对待常规文件一样处理软链结
--copy-unsafe-links 仅仅拷贝指向SRC路径目录树以外的链结
--safe-links 忽略指向SRC路径目录树以内的链结
-H, --hard-links 保留硬链结
-p, --perms 保持文件权限
-o, --owner 保持文件属主信息
-g, --group 保持文件属组信息
-D, --devices 保持设备文件和特殊文件信息
-t, --times 保持文件时间信息
-S, --sparse 对稀疏文件进行特殊处理以节省DST的空间
-n, --dry-run显示哪些文件将被传输
-W, --whole-file 拷贝文件,不进行增量检测
-X:保留文件的扩展属性(SUID/SGID/SBIT)
-A:保留文件的ACL属性信息。
-x, --one-file-system 不要跨越文件系统边界
-B, --block-size=SIZE 检验算法使用的块尺寸,默认是700字节
-e:指定使用rsh、ssh方式进行数据同步,默认为ssh
--rsync-path=PATH 指定远程服务器上的rsync命令所在路径信息
-C, --cvs-exclude 使用和CVS一样的方法自动忽略文件,用来排除那些不希望传输的文件
--existing 仅仅更新那些已经存在于DST的文件,而不备份那些新创建的文件
--delete 删除那些DST中有而SRC中没有的文件,删除的是DST中的文件,是以SRC为基准的。
--delete-excluded 同样删除接收端那些被该选项指定排除的文件
--delete-after 传输结束以后再删除
--ignore-errors 即使出现IO错误也进行删除
--max-delete=NUM 最多删除NUM个文件
--partial 保留那些因故没有完全传输的文件,以是加快随后的再次传输,支持断点续传。
--min-size:传输文件的最小大小。单位是K/M/G
--max-size:传输文件的最大大小。单位是K/M/G
--force 强制删除目录,即使不为空
--numeric-ids 不将数字的用户和组ID匹配为用户名和组名
--timeout=TIME IP超时时间,单位为秒
-I, --ignore-times 不跳过那些有同样的时间和长度的文件
--size-only 当决定是否要备份文件时,仅仅察看文件大小而不考虑文件时间
--modify-window=NUM 决定文件是否时间相同时使用的时间戳窗口,默认为0
-T --temp-dir=DIR 在DIR中创建临时文件
--compare-dest=DIR 同样比较DIR中的文件来决定是否需要备份
-P 等同于 --partial
-z, --compress 对备份的文件在传输时进行压缩处理
--compress-level=NUM:指定压缩等级
--exclude=PATTERN 指定排除不需要传输的文件模式
--include=PATTERN 指定需要传输的文件模式
--exclude-from=FILE 排除FILE文件中指定模式的文件
--include-from=FILE 不排除FILE文件指定模式匹配的文件
--version 打印版本信息
--blocking-io 对远程shell使用阻塞IO
--stats 给出某些文件的传输状态
-h:以人类可读的方式显示传输信息。
--progress 在传输时显示传输过程
--log-format=formAT 指定日志文件格式
--password-file=FILE 从FILE中得到密码.password文件的权限不能被其他用户读。
 
DAEMON模式的选项:
--daemon:以daemon的方式启动
--address:绑定到特定的接口地址
--config=FILE 指定其他的配置文件,不使用默认的rsyncd.conf文件
--port=PORT 指定其他的rsync服务端口
--bwlimit=KBPS 限制I/O带宽,KBytes per second
常用的选项为: avz --delete --progress
 
  


 rsync的模式介绍

 1. 本期shell模式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  
#建立测试目录
[root@10-9-116-136 /] mkdir rsync-test
[root@10-9-116-136 /] cd rsync-test/
#建立测试源目录
[root@10-9-116-136 rsync-test] mkdir source
#建立目标目录
[root@10-9-116-136 rsync-test] mkdir target
 
#进入源目录 新建需要同步的测试文件
[root@10-9-116-136 rsync-test] cd source/
[root@10-9-116-136 source] touch demo.txt
 
#执行rsync命令同步文件: rsync [命令选项] 源目录 目标目录
[root@10-9-116-136 rsync-test] rsync -avz /rsync-test/source/ /rsync-test/target/
sending incremental file list
./
demo.txt
 
sent 82 bytes  received 34 bytes  232.00 bytes/sec
total size is 0  speedup is 0.00
 
  

 2. 远程shell模式 (在不同的服务器之间传输数据)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  
将数据push到远端服务器上
 
#客户端建立测试目录
[root@10-9-164-227 local] mkdir /rsync-test/
[root@10-9-164-227 local] mkdir /rsync-test/source/
[root@10-9-164-227 rsync-test] cd /rsync-test/source/
#创建测试文件
[root@10-9-164-227 source] touch push.txt
 
#执行rsync命令同步文件: rsync [命令选项] 源目录 [USER@HOST:]目标目录
[root@10-9-164-227 source] rsync -avz /rsync-test/source/ root@10.9.116.136:/rsync-test/source/
The authenticity of host '10.9.116.136 (10.9.116.136)' can't be established.
RSA key fingerprint is SHA256:d9wv6ioIVsUAfJMQeMBxaPI4jeeejzRiWLIVU0ww6QY.
RSA key fingerprint is MD5:14:21:b6:2a:59:83:45:72:3b:0d:77:4f:1b:49:03:f3.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.9.116.136' (RSA) to the list of known hosts.
root@10.9.116.136's password:
sending incremental file list
./
push.txt
 
sent 94 bytes  received 41 bytes  12.86 bytes/sec
total size is 0  speedup is 0.00
 
 
从远端服务器上pull数据
 
#执行rsync命令同步文件: rsync [命令选项] [USER@HOST:]源目录 目录目录
[root@10-9-164-227 source]# rsync -avz root@10.9.116.136:/rsync-test/source/ /rsync-test/source/
root@10.9.116.136's password:
receiving incremental file list
demo.txt
 
sent 30 bytes  received 101 bytes  15.41 bytes/sec
total size is 0  speedup is 0.00
 
#查看是否成功
[root@10-9-164-227 source]# ls
demo.txt  push.txt
 
  

 3. 列表模式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  
#列出本地目录下的文件
[root@10-9-164-227 source] rsync /rsync-test/source/
drwxr-xr-x             36 2018/05/11 18:03:26 .
-rw-r--r--              0 2018/05/11 17:39:34 demo.txt
-rw-r--r--              0 2018/05/11 18:03:26 push.txt
 
#列出远程服务器上的文件
[root@10-9-164-227 source] rsync root@10.9.116.136:/rsync-test/source/
root@10.9.116.136's password:
drwxr-xr-x          4,096 2018/05/11 18:03:26 .
-rw-r--r--              0 2018/05/11 17:39:34 demo.txt
-rw-r--r--              0 2018/05/11 18:03:26 push.txt
 
  

 4. daemon模式 (守护进程)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
  
服务端配置
 
 
#建立rsync配置目录文件
[root@10-9-116-136 ~] mkdir /etc/rsync
[root@10-9-116-136 rsync] touch /etc/rsync/rsync.conf
 
#编辑配置文件
[root@10-9-116-136 rsync] vim /etc/rsync/rsync.conf
#----------------------------------------文件内容-----------begin
 
## rsyncd config file in daemon mode
pid file = /var/run/rsyncd.pid
lock file = /var/lock/subsys/rsyncd.lock
log file = /var/log/rsyncd.log
port = 873
address = 0.0.0.0
uid = root
gid = root
#开启则记录下载和上传操作
transfer logging = yes
#开启则记录下载和上传操作
log format = [time]:%t [op]:%o [ip]:%a [module]:%m [path]:%P [user]:%u [file]:%f [size]:%l
#关闭额外的安全防护,开启缺点:需要root权限,并且不能备份指向path外部的符号连接所指向的目录文件
use chroot = no
 
#设置一个模板:backup
[backup]
#模板描述
comment = This is Backup
#模块所映射的目录路径
path = /data/rsync-backup
#允许链接的ip,多个ip用逗号分隔
hosts allow = 10.9.164.227
#拒绝链接的ip(hosts allow优先于hosts deny)
hosts deny = *
#是否允许客户端上传:yes表示不允许上传,no表示允许上传
read only = no
#是否允许客户端下载:yes表示不允许上传,no表示允许上传
write only = no
#是否允许客户端列出该模块下的内容:yes允许,no不允许
list = yes
#指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块
auth users = admin
#指定是否检测口令文件的权限
strict modes = yes
#用户名和口令以明文方式存放在 secrets file 参数指定的文件中
secrets file = /etc/rsync/rsyncd.pass
#通过该选项可以覆盖客户指定的IP超时时间,单位为秒,这里我们设置120秒
timeout = 120
#模块所允许的最大连接数
max connections = 20
#忽略一些无关的IO错误
ignore errors
 
#----------------------------------------文件内容-----------end
 
#创建存放用户跟口令的文件
[root@10-9-116-136 rsync-backup] touch /etc/rsync/rsyncd.pass
#设置权限范围
[root@10-9-116-136 rsync] chmod 600 rsyncd.pass
#编辑文件
[root@10-9-116-136 rsync-backup] vim /etc/rsync/rsyncd.pass
#----------------------------------------文件内容-----------begin
 
admin:123456
 
#----------------------------------------文件内容-----------end
 
 
 
#根据配置指定的模块建立目录
[root@10-9-116-136 rsync-backup] mkdir /data/rsync-backup
 
#启动rsync服务
[root@10-9-116-136 rsync-backup] rsync --daemon --config /etc/rsync/rsync.conf
#检查是否启动
[root@10-9-116-136 rsync-backup] ps aux | grep rsync
root     25390  0.0  0.0 107632   668 ?        Ss   10:45   0:00 rsync --daemon --config /etc/rsync/rsync.conf
root     25392  0.0  0.0 103316   896 pts/4    S+   10:45   0:00 grep rsync
#检查端口号
[root@10-9-116-136 rsync-backup] netstat -tunlp | grep rsync
tcp        0      0 0.0.0.0:873                 0.0.0.0:*                   LISTEN      25390/rsync
 
另.补充:关闭rsync服务器命令
[root@10-9-116-136 rsync] kill $(cat /var/run/rsyncd.pid)
 
 
客户端配置
 
 
#创建rsync用户口令存放文件
[root@10-9-164-227 rsync-test] touch /etc/rsync/rsync.pass
#设置权限
[root@10-9-164-227 rsync-test] chmod 600 /etc/rsync/rsync.pass
 
#编辑内容
[root@10-9-164-227 rsync-test] vim /etc/rsync/rsync.pass
#----------------------------------------文件内容-----------begin
 
123456
 
#----------------------------------------文件内容-----------end
 
#列出服务器端模块: rsync -avz --password-file=用户口令文件url [USER@HOST::]
[root@10-9-164-227 ~] rsync -avz --password-file=/etc/rsync/rsync.pass admin@10.9.116.136::
backup             this is backup
 
#上传到服务器-push: rsync -avz 源目录 --password-file=用户口令文件url [USER@HOST::]模块名称
[root@10-9-164-227 source] rsync -avz /rsync-test/ --password-file=/etc/rsync/rsync.pass rsync@10.9.116.136::backup
sending incremental file list
./
source/
source/demo.txt
source/push.txt
 
sent 188 bytes  received 68 bytes  170.67 bytes/sec
total size is 0  speedup is 0.00
 
#从服务器上下载-pull: rsync -avz --progress --password-file=用户口令文件url [USER@HOST::]模块名称 本地目录(本机的存放服务器文件的url)
[root@10-9-164-227 source] rsync -avz --progress --password-file=/etc/rsync/rsync.pass admin@10.9.116.136::backup /rsync-test/source/
receiving incremental file list
./
demo/
demo/pull.txt
0 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=2/6)
source/
source/demo.txt
0 100%    0.00kB/s    0:00:00 (xfr#2, to-chk=1/6)
source/push.txt
0 100%    0.00kB/s    0:00:00 (xfr#3, to-chk=0/6)
 
sent 125 bytes  received 319 bytes  888.00 bytes/sec
total size is 0  speedup is 0.00
 
 
rsync服务器控制脚本[启动|停止]
----------------------------------文件内容----------------begin
#停止标志
STOP="[\033[5;31m停止\033[0m]"
#警告标志
WARM="[\033[5;31m警告\033[0m]"
#启动标志
START="[\033[5;32m启动\033[0m]"
 
if [ ! -n "$1" ];then
echo -e "缺少参数:start|stop $WARM"
exit
fi
 
pid=`ps -ef | grep rsync | grep -v 'grep'| awk '{print $2}'| wc -l`
if "$1" "start" ];then
if [ $pid -gt 0 ];then
echo -e "rsync is running... $WARM"
else
rsync --daemon --config /etc/rsync/rsync.conf
echo -e 'rsync' $START
fi
elif [ "$1" "stop" ];then
echo -e "rsync $STOP"
kill $(cat /var/run/rsyncd.pid)
else
echo -e "Please input like this:"./rsync.sh start" or "./rsync stop" " $WARM
fi
----------------------------------文件内容----------------end
 
 
rsync客户端控制脚本[运行脚本,自动执行pull,拉取服务器端数据]
----------------------------------文件内容----------------begin
PASSWORD="/etc/rsync/rsync.pass"
USER='rsync'
HOST='88.88.66.66'
#需要同步的模块=>本地路径
MODULE[0]="LiveMeetingServer=>/data/rsync/LiveMeetingServer/"
MODULE[1]="nginx-vhost=>/data/rsync/nginx-vhost/"
 
 
#----------------------------日志处理 begin
#获取当前时间
DT=`date +"%Y%m%d"`
TIME=`date +"%Y-%m-%d %H:%M:%S"`
#判断日志文件是否存在
if [ ! -f /data/rsync/log/${DT}.log ]; then
#创建日志文件
touch /data/rsync/log/${DT}.log
#设置权限
chmod 600 /data/rsync/log/*log
 
fi
#引入日志文件
export LOGFILE="/data/rsync/log/${DT}.log"
#----------------------------日志处理 end
 
#打印数组长度
#echo ${#arrayWen[@]}
 
#while循环遍历
i=0
while [[ i -lt ${#MODULE[@]} ]]; do
 
#要将$a分割开,先存储旧的分隔符
OLD_IFS="$IFS"
#设置分隔符
IFS="=>"
#如下会自动分隔
arr=(${MODULE[i]})
#恢复原来的分隔符
IFS="$OLD_IFS"
 
#echo ${arr[0]}
#echo ${arr[1]}
#echo ${MODULE[i]}
 
LOG=`rsync -avz --progress --password-file=${PASSWORD} ${USER}@${HOST}::${arr[0]} ${arr[2]}`
 
#操作记录写入日志
echo -e "${TIME} ${LOG} \n-------------------------------------------\n" >> $LOGFILE
 
let i++
done
 
echo -e "++++++++++++++++++++++++++++++++++++++++++\n" >> $LOGFILE
 
##特殊情况下,我们如果需要每五秒执行一次数据同步,但是crontab最小的单位是每分钟执行,那么,我们需要在我们的脚本内处理,例如[在脚本外套一层for循环,sleep单位为5s]
#例: 
#============================================ bengin
#step=5
#for (( l = 0; l < 60; l=(l+step+1) )); do
 
#echo $step
#echo $l
 
#sleep $step
#done
#exit
#============================================ end
----------------------------------文件内容----------------end
 
  


 另.附上:守护进程参考选项说明

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  
参数
 
motd file:指定motd(message of the day)的位置。当客户端每一次连接时都会显示该文件中的内容,没有默认值。
pid file:指定rsync的pid文件存储位置。
lock file:指定rsync的lock文件存储位置。
log file:指定rsync的log文件存储位置。
port:指定rsync监听的端口。默认为873.
address:指定rsync监听的地址。address = 0.0.0.0表示监听在本机上的所有地址。
syslog facility:指定rsync将log发送到syslog时的log级别。
模块选项如下(G/M表示也可以用于全局)
 
comment:指定模块的描述信息。(G/M)
path:指定模块所映射的目录路径
max connections:模块所允许的最大连接数。如果是0则表示没有限制,如果是负值则表示关闭该模块。(G/M)。如果用于全局,则表示所有模块的最大连接数。
log file:指定存放日志信息的文件名。(G/M)
lock file:指定lock文件的位置,确保不会达到最大连接数。默认为/var/run/rsyncd.lock。(G/M)
read only:是否允许客户端上传。yes表示不允许上传,no表示允许上传。默认为yes。如果设置为yes,则表示只能下载。
write only:是否允许客户端下载。yes表示不允许客户端下载,no允许客户端下载。默认为no。如果设置为yes,表示只能上传。
list:是否允许客户端列出该模块下的内容。yes允许,no不允许。
uid:username或user ID。指定该模块传输文件时(上传或下载),守护进程应该具有的UID权限,默认为nobody。当以root权限启动服务时,uid和gid则表示修改上传的文件的uid和gid。
gid:groupname或group ID。指定该模块传输文件时(上传或下载),守护进程应该具有的GID权限,默认为nobody。
exclude:指定多个文件或目录(相对路径)不被同步,并将其添加到 exclude 列表中.多个文件(目录)用空格分隔.作用等同于在客户端命令中使用–exclude来指定模式.
include:该选项针对于exclude,即同步exclude中的哪个文件(目录),并将其添加到include列表中,覆盖了exclude指定的文件或目录。多个文件(目录)用空格分隔.作用等同于在客户端命令中使用–include来指定模式.
exclude from:和exclude的作用一样,只不过是exclude是将排除的文件或目录作为value的,而exclude from则是将排除的文件和目录写在文件中的,一行一个文件或目录。
include from:和include的作用一样,将包括的文件写在文件中。
 
incoming chmod:修改服务器收到的文件的权限。如:incoming chmod = D2775,F664。(D表示目录,F表示文件)
outcoming chmod:修改服务器发送的文件的权限。
auth users与secrets file:这两个选项只能组合使用
auth users指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块,这里的用户和系统用户没有任何关系,用户名和口令以明文方式存放在 secrets file 参数指定的文件中,格式为username:password,常用的文件名为:/etc/rsyncd.secrets,password不能超过8个字符。
注意:secrets file文件的权限只能是启动rsyncd服务的用户具有rw权限,其他用户不能具有任何权限,即600.
示例:
auth users = joe:deny @guest:deny admin:rw @rsync:ro susan joe sam
说明:用户joe以及在guest组中的任何用户将不能访问指定的模块。admin用户将具有rw的权限(会忽略read only和write only的设置),rsync组中的用户将具有ro的权限,以及susan、joe和sam将会获取read only和write only的设置的权限。
timeout:通过该选项可以覆盖客户指定的IP超时时间。通过该选项可以确保rsync服务器不会永远等待一个崩溃的客户端。超时单位为秒,0表示没有超时定义,这也是默认值。对于匿名rsync服务器来说,一个理想的数字是600。
strict modes:指定是否检测口令文件的权限.若为 yes 则口令文件只能被 rsync 服务器运行身份的用户访问,其他任何用户不可以访问该文件,默认为yes。也就是该文件的权限为600或400。
hosts allow:用一个主机列表指定哪些主机客户允许连接该模块.不匹配主机列表的主机将被拒绝.也就是说如果指定hosts allow那么不在hosts allow指定中的主机都将都拒绝.
hosts deny:用一个主机列表指定哪些主机不能连接rsync模块.如果hosts allow和hosts deny同时指定一台主机,则以hosts allow为准.hosts allow和hosts deny的格式可以是x.x.x.x或x.x.x.x/n 或x.x.x.x/x.x.x.x或*的形式,也可以是主机名,要求能够被解析。
ignore errors :可以忽略一些无关的IO错误
use chroot(G/M):若为 true,则 rsync 在传输文件之前首先 chroot 到 path 参数所指定的目录下.这样做的原因是实现额外的安全防护,但是缺点是需要 root 权限,并且不能备份指向 path 外部的符号连接所指向的目录文件。
transfer logging:该选项开启则记录下载和上传操作。如果不配置该选项,则即使配置了log format时,也不会生效。
log format通过该选项用户在使用transfer logging可以自己定制日志文件的字段.
其格式是一个包含格式定义符的字符串,但要注意log format使用要在transfer logging选项开启的时候才可以.
常用的如下:
%o表示服务端提供什么操作,比如是接收send还是发送recv
%a表示客户端的IP地址.
%m表示服务端的模块名称
%P表示服务端模块指定的路径.
%t 当前时间
%u 认证的用户名(匿名时是null)
%b 实际传输的字节数
%f表示同步的文件.
%l表示同步文件的大小.
如:log format = [op]:%o [ip]:%a [module]:%m [path]:%P [file]:%f [size]:%l
 
  

 

---------------------------------------------------------------------------------------------
不忘初心 方得始终!

唯有志存高远,方能风行天下。

道之所存,虽千万人吾往矣! 情之所钟,虽千万里吾念矣~

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。