官方地址:https://github.com/happyfish100/fastdfs
一、先下載個包,然后解壓(自己找個目錄下載即可)
[root@localhost soft]# wget https://github.com/happyfish100/fastdfs/archive/master.zip --2019-09-16 05:26:36-- https://github.com/happyfish100/fastdfs/archive/master.zip Resolving github.com (github.com)... 13.250.177.223 Connecting to github.com (github.com)|13.250.177.223|:443... connected. HTTP request sent, awaiting response... 302 Found Location: https://codeload.github.com/happyfish100/fastdfs/zip/master [following] --2019-09-16 05:26:37-- https://codeload.github.com/happyfish100/fastdfs/zip/master Resolving codeload.github.com (codeload.github.com)... 13.229.189.0 Connecting to codeload.github.com (codeload.github.com)|13.229.189.0|:443... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [application/zip] Saving to: ‘master.zip’ [ <=> ] 482,045 645KB/s in 0.7s 2019-09-16 05:26:38 (645 KB/s) - ‘master.zip’ saved [482045] [root@localhost soft]# unzip master.zip Archive: master.zip 14edb44071b27599a5fc8c818b643eed6fe15e11 creating: fastdfs-master/
....
二、進入fastdfs-master/docker/dockerfile_network目錄,執行打包命令
[root@localhost soft]# cd fastdfs-master/docker/dockerfile_network
[root@localhost dockerfile_network]#
打包(注意,你的宿主機內存至少要2G,不然會報錯如下:)我之前只分配給宿主機1G內存,明顯不夠用。
如果還不行,清理一下yum緩存
# yum clean all Loaded plugins: fastestmirror, langpacks Cleaning repos: base docker-ce-stable extras updates Cleaning up everything Maybe you want: rm -rf /var/cache/yum, to also free up space taken by orphaned data from disabled or removed repos # rm -rf /var/cache/yum
好,執行命令打包:(注意最后有個點)
[root@localhost dockerfile_network]# docker build -t local/fastdfs:latest . Sending build context to Docker daemon 68.1kB Step 1/13 : FROM centos ---> 67fa590cfc1c Step 2/13 : ADD conf/client.conf /etc/fdfs/ ---> Using cache ---> f6d4d01d7cf4 Step 3/13 : ADD conf/http.conf /etc/fdfs/ ---> Using cache ---> 09b5d6e42010 Step 4/13 : ADD conf/mime.types /etc/fdfs/ ---> Using cache ---> 01ba930f4e2a Step 5/13 : ADD conf/storage.conf /etc/fdfs/ ---> Using cache ---> 628d5f17543d Step 6/13 : ADD conf/tracker.conf /etc/fdfs/ ---> Using cache ---> b62b681c8ee8 Step 7/13 : ADD fastdfs.sh /home ---> Using cache ---> 6f0ffb43c5fc Step 8/13 : ADD conf/nginx.conf /etc/fdfs/ ---> Using cache ---> 6e2dded720b5 Step 9/13 : ADD conf/mod_fastdfs.conf /etc/fdfs ---> Using cache ---> 6feff4c6bb23 Step 10/13 : RUN yum install git gcc gcc-c ++ make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl-devel wget vim -y && cd /usr/local/src && git clone https://github.com/happyfish100/libfastcommon.git --depth 1 && git clone https://github.com/happyfish100/fastdfs.git --depth 1 && git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1 && wget http://nginx.org/download/nginx-1.15.4.tar.gz && tar -zxvf nginx-1.15.4.tar.gz && mkdir /home/dfs && cd /usr/local/src/ && cd libfastcommon/ && ./make.sh && ./make.sh install && cd ../ && cd fastdfs/ && ./make.sh && ./make.sh install && cd ../ && cd nginx-1.15.4/ && ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/ && make && make install && chmod +x /home/fastdfs.sh ---> Using cache ---> 59424d66e1a1 Step 11/13 : VOLUME /etc/fdfs ---> Using cache ---> d72d68fd5ebf Step 12/13 : EXPOSE 22122 23000 8888 80 ---> Using cache ---> f0c2d84a954e Step 13/13 : ENTRYPOINT ["/home/fastdfs.sh"] ---> Using cache ---> fc76c652493b Successfully built fc76c652493b Successfully tagged local/fastdfs:latest
(額,這是我第二次打包,我第一次打包輸出好多內容的,你們自行體會,你們應該能看見 ---> Using cache 利用了緩存)
另:網友打包把體積縮小到30M左右,需要修改Dockerfile成如下所示,打包過程不變如上所示(https://github.com/happyfish100/fastdfs/issues/327)
FROM alpine:3.10 RUN set -x \ && echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories \ && echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories \ && apk update \ && apk add --no-cache --virtual .build-deps gcc libc-dev make perl-dev openssl-dev pcre-dev zlib-dev git \ && mkdir -p /usr/local/src \ && cd /usr/local/src \ && git clone https://github.com/happyfish100/libfastcommon.git --depth 1 \ && git clone https://github.com/happyfish100/fastdfs.git --depth 1 \ && git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1 \ && wget http://nginx.org/download/nginx-1.15.4.tar.gz \ && tar -xf nginx-1.15.4.tar.gz \ && cd /usr/local/src/libfastcommon \ && ./make.sh \ && ./make.sh install \ && cd /usr/local/src/fastdfs/ \ && ./make.sh \ && ./make.sh install \ && cd /usr/local/src/nginx-1.15.4/ \ && ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/ \ && make && make install \ && apk del .build-deps \ && apk add --no-cache pcre-dev bash \ && mkdir -p /home/dfs \ && mv /usr/local/src/fastdfs/docker/dockerfile_network/fastdfs.sh /home \ && mv /usr/local/src/fastdfs/docker/dockerfile_network/conf/* /etc/fdfs \ && chmod +x /home/fastdfs.sh \ && rm -rf /usr/local/src* VOLUME /home/dfs EXPOSE 22122 23000 8888 8080 CMD ["/home/fastdfs.sh"]
測試上傳
這里面有個坑。先啟動鏡像
docker run -d -e FASTDFS_IPADDR=[宿主機地址] -p 8888:8888 -p 22122:22122 -p 23000:23000 -p 8011:80 --name test-fast local/fastdfs
然后客戶端上傳,報錯。com.github.tobato.fastdfs.exception.FdfsConnectException: 無法獲取服務端連接資源:can't create connection to/172.17.0.1:23000
為什么呢,首先我們客戶端連接提供了tracker的地址,這個地址可以訪問的,已經將22122端口映射到宿主機上了,而客戶端的storage地址是通過tracker獲取的,而這個地址則是Docker的容器地址,不能直接訪問,所以連接超時。
進入容器能看到storage的地址如下:
你查看容器信息:
$ docker inspect 437c7bde65f8
在最后有地址信息,可見網關地址和實際地址
也就是說,tracker把Docker容器的網關地址當成了storage的地址
思考過程
網上有人說,利用iptables配置轉發規則即可,可是我按照它的方法沒有成功,那么根據轉發這個思路分析一下。
目前我的環境大概是這樣的
首先,Java客戶端根據獲取的storage地址(172.17.0.1:23000)去請求,到底能不能經過網段192.*的虛擬機,我們知道路由表的概念:(引用網友通俗的解釋)
路由表是機器使用網絡時要查找的一個表項,根據路由表來查找發送到特定IP的信息該發送到那個下一跳。
比如你的機子要發送一個信息到192.168.2.8,它就要查路由表到底應該怎么發,假設它查出的結果是可以直接發送,那就直接發送,否則就查出來應該發送到哪個IP,交給那個IP轉發。
那么我們看一下我本機的路由表,執行: route print -4 【-6代表IPv6,不加打印全部】
我在搜索一下172的
沒有,證明什么,憑借172*的地址,我哪也去不了,所以不會到達虛擬機,到達不了虛擬機,網上說的轉發是轉發什么呢?所以根本行不通吧。
我們再來看我虛擬機上的路由表
沒錯,存在172的網段,但是,你要玩172,也要先進入虛擬機才行。而Java客戶端是直接去請求172地址的,那就別想了。哪也去不了。
=====================================================================================================
以下是我查閱的資料:
關於Docker網絡:https://docs.docker.com/network/
Docker網絡模式:https://www.cnblogs.com/yy-cxd/p/6553624.html
iptables的介紹:http://www.zsythink.net/archives/1199
iptables簡單增刪查改:https://www.cnblogs.com/bethal/p/5806525.html
路由表:https://www.cnblogs.com/baiduboy/p/7278715.html
路由尋址過程:https://blog.csdn.net/u011857683/article/details/83795279
后記:仔細想一下,如果你分開容器部署可能也會出現同樣的問題,問題就在於我們無法為storage強制配一個地址,這樣的結果在Docker環境下就成了:tracker獲取到的storage地址永遠都是容器網關地址,而不是映射外網地址。
也有個網友這樣想的,但需要修改代碼:
另外我也明白了那個iptables網友的思路:他覺得是因為在請求tracker,tracker返回storage地址的時候去修改(將返回的172.17.0.1:23000修改為宿主機地址),可是我沒有成功。
最后一種方法,就是使用host網絡模式,這樣就不存在二層網絡了,媽媽再也不用擔心地址錯誤了。
[root@localhost admin]# docker run -d -e FASTDFS_IPADDR=192.168.192.128 --name test-fast --net=host local/fastdfs-2 047250f19cad90af03ae979e8a646fff61349883f7ecdb38f72d063bd93e3f80 [root@localhost admin]#
然后客戶端上傳文件
<dependency> <groupId>com.github.tobato</groupId> <artifactId>fastdfs-client</artifactId> <version>1.26.6</version> </dependency>
application.properties
#連接時間 fdfs.connect-timeout=600 #讀取時間 fdfs.so-timeout=2000 #縮略圖 fdfs.thumb-image.width=96 fdfs.thumb-image.height=128 #tracker列表 fdfs.tracker-list=192.168.192.128:22122 # 自定義屬性,圖片訪問地址 img.host=http://192.168.192.128:8888/
工具類
import com.alibaba.fastjson.JSONObject; import com.github.tobato.fastdfs.domain.fdfs.StorePath; import com.github.tobato.fastdfs.domain.fdfs.ThumbImageConfig; import com.github.tobato.fastdfs.domain.upload.FastFile; import com.github.tobato.fastdfs.service.FastFileStorageClient; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.InputStream; import java.util.HashMap; import java.util.HashSet; import java.util.Map; /** * 不會出現網上說的jmx重復注冊bean的問題,是FastDFS-Client 1.26.4版本以前引入方式 */ @Component @Slf4j public class UploadToFastDFS { @Autowired protected FastFileStorageClient storageClient; @Autowired private ThumbImageConfig thumbImageConfig; @Value("${img.host}") private String imgHost; /** * 上傳文件並生成縮略圖 * @param inputStream * @param fileSize * @param fileExtName * @return */ public Map<String, String> uploadFile(InputStream inputStream, Long fileSize, String fileExtName){ Map<String, String> map = new HashMap<>(); log.info("##上傳文件..."); FastFile fastFile = new FastFile.Builder() .withFile(inputStream, fileSize, fileExtName) .build(); // 上傳文件 StorePath storePath = storageClient.uploadImageAndCrtThumbImage(inputStream, fileSize, fileExtName, new HashSet<>()); log.info("上傳文件結果...{}", storePath); // 帶分組的路徑 String fullPath = storePath.getFullPath(); log.info("帶分組的路徑...{}", fullPath); String path = storePath.getPath(); log.info("路徑...{}", path); // 獲取縮略圖路徑 String thumbImagePath = thumbImageConfig.getThumbImagePath(storePath.getPath()); log.info("縮略圖路徑...{}", thumbImagePath); map.put("fullPath", imgHost + fullPath); map.put("thumbImagePath", imgHost + storePath.getGroup() + "/" + thumbImagePath); log.info("返回結果:{}" + JSONObject.toJSONString(map)); // 返回結果:{}{"fullPath":"http://192.168.192.128:8888/group1/M00/00/00/wKjAgF2C7aqAcJNzAAFRSnsPpGY738.png","thumbImagePath":"http://192.168.192.128:8888/group1/M00/00/00/wKjAgF2C7aqAcJNzAAFRSnsPpGY738_96x128.png"} return map; } }
測試類
@Autowired private UploadToFastDFS uploadToFastDFS; @Test public void contextLoads() throws IOException { FileInputStream in = new FileInputStream("3d4cdbb229559df79d93a30e27f8d521.png"); uploadToFastDFS.uploadFile(in, in.getChannel().size(), "png"); }
瀏覽器訪問
http://192.168.192.128:8888/group1/M00/00/00/wKjAgF2C4zaAEFIXAAFRSnsPpGY325.png