分布式文件系統(tǒng)
1.簡介
通過先前的例子我們發(fā)現(xiàn)普通的方式安裝及其麻煩铃芦,假如我們需要搭建集群,那更加麻煩襟雷。所以在安裝軟件時并不推薦使用常規(guī)的方式去安裝刃滓,而是推薦使用基于Docker方式去安裝
2.鏡像選擇
要想基于Dokcer的方式去安裝,那么我們就需要選擇合適的鏡像耸弄。為了更好的安裝咧虎,我更換了一臺計算機(jī),其IP地址為172.16.0.4
并安裝了docker计呈,搭建了私服砰诵。如果不知道安裝,可以參考《Docker 使用系列》
-
搜索鏡像
docker search fastdfs
發(fā)現(xiàn)雖然鏡像有很多震叮,但是并沒有官方所提供的胧砰。同時其他的鏡像我們也不清楚別人構(gòu)建的過程。因此我們可以自己制作一個鏡像苇瓣。
3. 制作鏡像
3.1 鏡像文件解釋
我們可以從github來拉取一個制作鏡像的Dockerfile
.
-
地址
-
目錄結(jié)構(gòu)
-
關(guān)于文件解釋
所需的軟件
-
Dockerfile解釋
#基礎(chǔ)鏡像 FROM centos:7 #作者信息 MAINTAINER liujun "1747441374@qq.com" #安裝所需的依賴 RUN yum install -y zlib zlib-devel pcre pcre-devel gcc gcc-c++ openssl openssl-devel libevent libevent-devel perl unzip #安裝 libfastcommon #將libfastcommon-1.0.35.zip 復(fù)制到 /usr/local/src/ ADD libfastcommon-1.0.35.zip /usr/local/src/ # 進(jìn)入到 /usr/local/src 并解壓,同時還編譯和運(yùn)行 RUN cd /usr/local/src \ && unzip /usr/local/src/libfastcommon-1.0.35.zip \ && cd libfastcommon-1.0.35 \ && ./make.sh \ && ./make.sh install #安裝 fastdfs # 將fastdfs-5.11.zip 復(fù)制到 /usr/local/src/下 ADD fastdfs-5.11.zip /usr/local/src/ # 解壓 RUN cd /usr/local/src/ && unzip fastdfs-5.11.zip # 編譯安裝偿乖,同時將配置復(fù)制到 /etc/fdfs下 RUN cd /usr/local/src/fastdfs-5.11 \ && ./make.sh \ && ./make.sh install \ && cp conf/*.conf /etc/fdfs \ && cd /etc/fdfs/ \ && rm -rf *.sample #安裝nginx #將fastdfs-nginx-module_v1.16.tar.gz 復(fù)制 /usr/local/src/ ADD fastdfs-nginx-module_v1.16.tar.gz /usr/local/src/ #ADD fastdfs-nginx-module-1.20.zip /usr/local/src/ #run cd /usr/local/src/ && unzip fastdfs-nginx-module-1.20.zip && ln -s fastdfs-nginx-module-1.20 fastdfs-nginx-module #將nginx-1.7.8.tar.gz 復(fù)制 /usr/local/src/ ADD nginx-1.7.8.tar.gz /usr/local/src/ # 添加模塊击罪,編譯安裝nginx RUN cd /usr/local/src/ \ && cd nginx-1.7.8 \ && ./configure --prefix=/usr/local/nginx --add-module=/usr/local/src/fastdfs-nginx-module/src \ && make \ && make install \ && cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/ # 復(fù)制 nginx.conf 到 /usr/local/nginx/conf/ ADD nginx.conf /usr/local/nginx/conf/ #創(chuàng)建 storage和tracker 存儲日志和數(shù)據(jù)目錄 RUN mkdir -p /export/fastdfs/{storage,tracker} # 將腳本復(fù)制到 /usr/local/src/ ADD tracker.sh /usr/local/src/ ADD storage.sh /usr/local/src/
-
nginx.conf解釋
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { # 默認(rèn)監(jiān)聽 8080,這個在創(chuàng)建容器時可以更換 listen 8080; # 監(jiān)聽域名為本機(jī) server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; # 如果發(fā)送的請求中,包含group 交給ngx_fastdfs_module 處理 location ~/group[1-9]/M00 { root /export/fastdfs/storage/data; ngx_fastdfs_module; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # # 錯誤頁面 error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443 ssl; # server_name localhost; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} }
-
tracker.sh解釋
#!/bin/sh if [ ! -f /initialized ]; then { touch /initialized #TRACKER_PORT 創(chuàng)建容器時需要手動指贪薪,如果采用默認(rèn)的話媳禁,可以把這行刪掉 sed -i "s#\(port\).*#\1=$TRACKER_PORT#" /etc/fdfs/tracker.conf #TRACKER_BASE_PATH 創(chuàng)建容器時需要手動指定 sed -i "s#\(base_path\).*#\1=$TRACKER_BASE_PATH#" /etc/fdfs/tracker.conf } fi # 重啟 tracker /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart # 展示日志 tail -f /export/fastdfs/tracker/logs/trackerd.log
-
storage.sh 解釋
#!/bin/sh if [ ! -f /initialized ]; then { touch /initialized # STORAGE_PORT 創(chuàng)建容器時需要手動指定,如果采用默認(rèn)的話画切,可以把這行刪掉 sed -i "s#\(port\).*#\1=$STORAGE_PORT#" /etc/fdfs/storage.conf # GROUP_NAME 創(chuàng)建容器時需要手動指定組名竣稽,如果采用默認(rèn)的話,可以把這行刪掉 sed -i "s#\(group_name\).*#\1=$GROUP_NAME#" /etc/fdfs/storage.conf # STORAGE_BASE_PATH 創(chuàng)建容器時需要手動指定存儲日志和數(shù)據(jù)的目錄 sed -i "s#\(base_path\).*#\1=$STORAGE_BASE_PATH#" /etc/fdfs/storage.conf # STORAGE_BASE_PATH 創(chuàng)建容器時需要手動指定文件上傳的存儲目錄 sed -i "s#\(store_path0\).*#\1=$STORAGE_PATH0#" /etc/fdfs/storage.conf # 創(chuàng)建容器時手動指定tracker_server sed -i "s#\(tracker_server\).*##" /etc/fdfs/storage.conf #HTTP_SERVER_PORT 創(chuàng)建容器時手動指定 sed -i "s#\(http.server_port\).*#\1=$HTTP_SERVER_PORT#" /etc/fdfs/storage.conf # STORAGE_BASE_PATH 創(chuàng)建容器時 指定 STORAGE_BASE_PATH 的值是mod_fastdfs.conf存儲日志和數(shù)據(jù)的目錄 sed -i "s#\(base_path\).*#\1=$STORAGE_BASE_PATH#" /etc/fdfs/mod_fastdfs.conf # STORAGE_PATH0 創(chuàng)建容器時 指定 STORAGE_PATH0文件上傳的存儲路徑 sed -i "s#\(store_path0\).*#\1=$STORAGE_PATH0#" /etc/fdfs/mod_fastdfs.conf # STORAGE_PORT 手動指定端口,想要默認(rèn)可以直接刪掉 sed -i "s#\(storage_server_port\).*#\1=$STORAGE_PORT#" /etc/fdfs/mod_fastdfs.conf # 設(shè)置 mod_fastdfs 的 tracker_server sed -i "s#\(tracker_server\).*##" /etc/fdfs/mod_fastdfs.conf # GROUP_NAME 設(shè)置組名 sed -i "s#\(group_name\).*#\1=$GROUP_NAME#" /etc/fdfs/mod_fastdfs.conf # GROUP_COUNT 設(shè)置組的數(shù)量 sed -i "s#\(group_count\).*#\1=$GROUP_COUNT#" /etc/fdfs/mod_fastdfs.conf # 設(shè)置 HTTP_SERVER_PORT 端口 sed -i "s#\(http.server_port\).*#\1=$HTTP_SERVER_PORT#" /etc/fdfs/mod_fastdfs.conf #設(shè)置組名 sed -i "s#\(url_have_group_name\).*#\1=true#" /etc/fdfs/mod_fastdfs.conf # 這個非常重要毫别,將HTTP_SERVER_PORT 的值設(shè)置為Nginx的監(jiān)聽端口 sed -i "s#listen 8080#listen $HTTP_SERVER_PORT#g" /usr/local/nginx/conf/nginx.conf for i in $( echo $TRACKER_SERVER | awk -v FS="," '{for(i=1;i<=NF;i++)print $i}' );do echo "tracker_server=$i" >> /etc/fdfs/storage.conf;done for i in $( echo $TRACKER_SERVER | awk -v FS="," '{for(i=1;i<=NF;i++)print $i}' );do echo "tracker_server=$i" >> /etc/fdfs/mod_fastdfs.conf;done #add groups 添加組 i=1 while(( $i<=$GROUP_COUNT )) do # 設(shè)置組信息 echo "[group$i]" >> /etc/fdfs/mod_fastdfs.conf # 設(shè)置組名 echo "group_name=group$i" >> /etc/fdfs/mod_fastdfs.conf # 設(shè)置組的端口 echo "storage_server_port=$STORAGE_PORT" >> /etc/fdfs/mod_fastdfs.conf # 設(shè)置組的存儲路徑數(shù)量 echo "store_path_count=1" >> /etc/fdfs/mod_fastdfs.conf # 設(shè)置組的文件存儲路徑 echo "store_path0=$STORAGE_PATH0" >> /etc/fdfs/mod_fastdfs.conf let "i++" done } fi cd /etc/fdfs touch mime.types /usr/local/nginx/sbin/nginx -t /usr/local/nginx/sbin/nginx # 啟動storage /usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart #展示日志 tail -f /export/fastdfs/storage/logs/storaged.log
3.2 鏡像制作
-
根據(jù)上述中的 liujun 給我們提供的制作鏡像的文件下載下來娃弓,并上傳到 計算機(jī)上
-
下載 unzip 并解壓
-
進(jìn)入解壓好的目錄下,進(jìn)行構(gòu)建
docker build -t 宿主機(jī)Ip:私服端口/fastdfs:5.11 . 這個格式的鏡像可以直接推送到私服岛宦,不用起別名
鏡像構(gòu)建成功
-
上傳到私服
docker push 172.16.0.47:5000/fastdfs:5.11
成功后訪問私服:
上傳成功台丛。
3.3 創(chuàng)建容器
這里我們創(chuàng)建一個tracker容器和一個storage容器,當(dāng)然可以創(chuàng)建集群砾肺,無非是多創(chuàng)建幾個容器挽霉。
但是我們在一臺宿主機(jī)搭建集群意義也不大,如果多臺機(jī)器的話变汪,都是重復(fù)工作侠坎。如果有實(shí)際需求可以自己動手搭建∪苟埽可以參考上述文件中的
READ ME.md
3.3.1 創(chuàng)建并運(yùn)行容器
-
創(chuàng)建并運(yùn)行容器(tracker)
docker run -di --name=fdfs_tracker -v /var/fdfs/tracker:/export/fastdfs/tracker --net=host -e TRACKER_BASE_PATH=/export/fastdfs/tracker -e TRACKER_PORT=22123 172.16.0.47:5000/fastdfs:5.11 sh /usr/local/src/tracker.sh
-v /var/fdfs/tracker
將track容器存儲數(shù)據(jù)的目錄映射到宿主機(jī)上--net=host
網(wǎng)絡(luò)模式实胸,映射容器上所有端口-e TRACKER_BASE_PATH=/export/fastdfs/tracker
設(shè)置tracker容器內(nèi)存儲日志和數(shù)據(jù)的目錄,不要改-e TRACKER_PORT=22123
設(shè)置track的端口sh /usr/local/src/tracker.sh
執(zhí)行容器里面的腳本 -
創(chuàng)建并運(yùn)行容器(storage)
docker run -di --name=fdfs_storage -v /var/fastdfs/storage:/export/fastdfs/storage --net=host -e STORAGE_PORT=23001 -e STORAGE_BASE_PATH=/export/fastdfs/storage -e STORAGE_PATH0=/export/fastdfs/storage -e TRACKER_SERVER=172.16.0.47:22123 -e GROUP_COUNT=1 -e HTTP_SERVER_PORT=8081 -e GROUP_NAME=group1 172.16.0.47:5000/fastdfs:5.11 sh /usr/local/src/storage.sh
-v /var/fdfs/tracker
將track容器存儲數(shù)據(jù)的目錄映射到宿主機(jī)上--net=host
網(wǎng)絡(luò)模式闷煤,映射容器上所有端口-e STORAGE_PORT=23001
設(shè)置storage的端口-e STORAGE_BASE_PATH=/export/fastdfs/storage
設(shè)置 storage容器內(nèi)存儲日志和數(shù)據(jù)的位置,不要改-e STORAGE_PATH0 =/export/fastdfs/storage
設(shè)置文件上傳的存儲路徑-e TRACKER_SERVER=172.16.0.47:22123
設(shè)置tracker_server設(shè)置地址-e GROUP_COUNT=1
設(shè)置組的數(shù)量為1-e HTTP_SERVER_POR=8081
設(shè)置storage的http端口和nginx的監(jiān)聽端口-e GROUP_NAME=group1
設(shè)置組名sh /usr/local/src/storage.sh
執(zhí)行storage腳本
3.3.2 測試
進(jìn)入storage容器中童芹,測試是否與tracker進(jìn)行了連接
docker exec -it fdfs_storage /bin/bash
測試命令
/usr/bin/fdfs_monitor /etc/fdfs/storage.conf
連接成功。
通過瀏覽器訪問鲤拿,也可以看到nginx
4.Java客戶端連接
4.1 簡介
FastDFS的作者余慶先生也給我們提供一個java客戶端用來連接 FastDFS假褪,但是已經(jīng)很久不維護(hù)了。但是在GitHub上有一款開源的FastDFS客戶端近顷。 這個客戶端得到了在原來余慶先生提供的客戶端基礎(chǔ)上進(jìn)行大量的重構(gòu)
配置及其簡單生音,支持連接池,支持自動生成縮略圖窒升,同時還支持SpringBoot 2.x
地址:https://github.com/tobato/FastDFS_Client
4.2 編碼
4.2.1 上傳普通文件
-
創(chuàng)建SpringBoot項(xiàng)目并導(dǎo)入依賴(springboot 版本:2.1.13.RELEASE)
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.27.2</version>
</dependency>
-
修改
application.yml
文件缀遍,增加配置fdfs: connect-timeout: 600 so-timeout: 1501 tracker-list: # tracker地址 - 172.16.0.47:22123
-
增加配置類
package com.wangzh.fastdfs.config; import com.github.tobato.fastdfs.FdfsClientConfig; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableMBeanExport; import org.springframework.context.annotation.Import; import org.springframework.jmx.support.RegistrationPolicy; @Configuration @Import(FdfsClientConfig.class) // 解決jmx重復(fù)注冊問題 @EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING) public class FastDFSClientConfig { }
-
測試上傳普通文件
package com.wangzh.fastdfs; import com.github.tobato.fastdfs.domain.fdfs.StorePath; import com.github.tobato.fastdfs.service.FastFileStorageClient; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @RunWith(SpringRunner.class) @SpringBootTest public class FastdfsApplicationTests { /** * * 注入上傳的客戶端對象 */ @Autowired private FastFileStorageClient storageClient; @Test public void upload() throws FileNotFoundException { File file = new File("C:\\Users\\wangzh\\Desktop\\html.pdf"); /* * 第一個參數(shù) 為組名,不寫 默認(rèn)group1 * 第二個參數(shù)為文件流 * 第三個參數(shù)為上傳文件的大小 * 第四個參數(shù)為 文件后綴名 * */ StorePath storePath = storageClient.uploadFile("group1", new FileInputStream(file), file.length(), "pdf"); /* * 打印文件名Id 包含組名 * 執(zhí)行后的結(jié)果為: group1/M00/00/00/rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf * group1 組名 * M00 代表設(shè)置的 storage_path0 00/00 存儲的具體磁盤目錄 * rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf */ System.out.println(storePath.getFullPath()); /* * 打印文件名饱须,不包含組名 * 執(zhí)行后的結(jié)果為: M00/00/00/rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf * */ System.out.println(storePath.getPath()); } }
訪問:
http://172.16.0.47:8081/group1/M00/00/00/rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf
文件上傳成功域醇。
4.2.2 上傳圖片
上傳圖片并自動創(chuàng)建縮略圖
-
增加縮略圖配置
fdfs: connect-timeout: 600 so-timeout: 1501 tracker-list: # tracker地址 - 172.16.0.47:22123 thumb-image: width: 70 height: 70
-
編碼
package com.wangzh.fastdfs; import com.github.tobato.fastdfs.domain.fdfs.StorePath; import com.github.tobato.fastdfs.domain.fdfs.ThumbImageConfig; import com.github.tobato.fastdfs.service.FastFileStorageClient; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @RunWith(SpringRunner.class) @SpringBootTest public class FastdfsApplicationTests { /** * * 注入上傳的客戶端對象 */ @Autowired private FastFileStorageClient storageClient; /** * 注入縮略圖配置對象 */ @Autowired private ThumbImageConfig thumbImageConfig; @Test public void testUpload() throws FileNotFoundException { File file = new File("D:\\1_soft\\1.jpg"); StorePath storePath = storageClient.uploadImageAndCrtThumbImage(new FileInputStream(file), file.length(), "jpg", null); System.out.println("帶分組路徑:" + storePath.getFullPath()); System.out.println("不帶分組路徑:" + storePath.getPath()); System.out.println("獲取縮略圖路徑:" + thumbImageConfig.getThumbImagePath(storePath.getPath())); } }
結(jié)果:
帶分組路徑:group1/M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269.jpg 不帶分組路徑:M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269.jpg 獲取縮略圖路徑:M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269_70x70.jpg
我們通過瀏覽器訪問一下:
http://172.16.0.47:8081/group1/M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269_70x70.jpg
http://172.16.0.47:8081/group1/M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269.jpg