项目场景:

在远程用docker搭建fastdfs,然后本地用java上传下载文件,此次搭建是单机版本,将storage和tracker放到同一个容器之中。


问题描述

当服务器上用docker搭建好服务器之后,发现本地的Java程序无法上传,从端口映射,docker的host网络等方面考虑解决方式,最终解决。

原因分析:

首先要验证服务器上的端口是否开放,在windows上可以使用

start /min telnet 服务器公网ip 端口

如果可以连上这个端口,就会弹出一个小窗口,如果连不上,这个小窗口过一会就会自己消失。
如果服务器上端口没有开放,需要去安全组里面设置,如果服务器防火墙没有关,可能还需要去服务器上的防火墙上开放端口。

当服务器端口确定开放之后,得先了解fastdfs的原理,如图所示:

群晖 宝塔 搭建 java 群晖部署java_docker

当本地java程序访问fastdfs的时候,先经过公网网关,网关根据nat规则把请求数据给服务器的私网(也就是用ip addr得到的ip地址),如果docker容器使用的network是默认的brige模式,会通过docker的端口映射,找到tracker的地址,然后tracker找到可用的storage,然后storage将自己的地址返回,这里就要注意了,这里返回的地址是docker容器里面通过ip addr得到的地址,并不是服务器公网的地址。为了确认是不是storage返回的地址问题导致的上传文件上传不了问题,需要在本地调试java程序,debug过程中获取返回的storage地址。在这里奉上我用的代码地址:

fastdfs测试 需要debug的位置在TrackerClient.java的如下位置:

群晖 宝塔 搭建 java 群晖部署java_java_02

将断点打到这里,就可以看见storage返回的地址了。

我也是最后通过调试代码发现问题就在storage返回地址的问题。


解决方案:

提示:这里填写该问题的具体解决方案:

首先,由于折腾了很久,尝试了很多方法,我最终的方案中,fastdfs用docker创建容器的时候使用的network是host模式,这样就跟宿主共享ip和端口了,就不需要进行端口映射这个流程,然后,我将nat的规则加了一条,如下:

iptables -t nat -A POSTROUTING -p tcp -m tcp --dport 22122 -d 服务器私网ip -j SNAT --to 服务器公网ip

这条规则的目标是将私网ip的地址通过公网发出去的时候改成公网ip,这样就可以解决storage返回的地址问题了。但是注意,如果这里添加的规则有问题,可能导致服务器上不了网但是外面可以进来的问题,这时候就需要使用下面命令删除特定的nat规则了:

iptables -t nat  -D POSTROUTING  编号

这行命令的参数含义自行百度。

当nat规则添加之后,可以使用下面这命令查看nat规则。

iptables -L -t nat

最后,可以使用命令进入到docker容器内部了,命令如下:

docker exec -it 容器id/name /bin/bash

进入到容器之后,tracker.conf以及storage.conf的tracker_server参数均设置为ip addr得到的ip地址,然后启动或者重启(重启最好将缓存的数据删掉,避免出错),如何配置fastdfs这里不再赘述。当配置完后使用以下命名查看绑定关系:

fdfs_monitor /etc/fdfs/client.conf

会得到下面结果:

server_count=1, server_index=0

tracker server is (ip addr得到的地址):22122

group count: 1

Group 1:
group name = group1
disk total space = 40,188 MB
disk free space = 24,615 MB
trunk free space = 0 MB
storage server count = 1
active server count = 1
storage server port = 23000
storage HTTP port = 8080
store path count = 1
subdir count per path = 256
current write server index = 0
current trunk file id = 0

	Storage 1:
		id = 公网ip
		ip_addr = 公网ip  ACTIVE
		http domain = 
		version = 6.08
		join time = 2022-04-19 04:56:44
		up time = 2022-04-19 04:56:44
		total storage = 40,188 MB
		free storage = 24,615 MB
		upload priority = 10
		store_path_count = 1
		subdir_count_per_path = 256

这样一系列操作之后,我的问题解决了,至于你的问题,可能解决也可能还有,反正出发点是针对storage返回的地址不对造成的上传错误。可以研究的出发点有nat规则,端口映射,防火墙等。