篇幅較長,乾貨滿滿,需花費較長時間,轉載請註明出處!html
Web服務器:Nginx(本案例使用Nginx,還不會用Nginx的小夥伴,請看我另外一篇博客:點我直達)、Apache等等。java
技術文檔node
連接: https://pan.baidu.com/s/1BpPwJBg2mR8CvqOiKj2rDQ 密碼: ocj5
實際比這複雜的多linux
FastDFS系統有三個角色:跟蹤服務器(Tracker Server)、存儲服務器(Storage Server)和客戶端(Client)。nginx
爲了支持大容量,存儲節點(服務器)採用分卷(或分組)的組織方式。存儲系統由一個或多個卷組成,卷與卷之間的文件是相互獨立的,全部卷的文件容量累加就是整個存儲系統中的文件容量。一個卷能夠由一臺或多臺存儲服務器組成,一個卷下的存儲服務器中的文件都是相同的,卷中的多臺存儲服務器起到了冗餘備份和負載均衡的做用。c++
在卷中增長服務器時,同步已有的文件由系統自動完成,同步完成後,系統自動將新增服務器切換到線上提供服務。當存儲空間不足或即將耗盡時,能夠動態加載卷,只須要增長一臺或多臺服務器,並將它們配置爲一個新的卷,這樣就擴大了存儲系統的容量。git
Storage Server會經過配置鏈接集羣中全部的Tracker Server,定時向他們報告本身的狀態,包括磁盤剩餘空間、文件上傳下載次數等統計信息。github
Storage Server有7個狀態,以下正則表達式
一、Tracker Server收集Storage Server的狀態信息算法
1.一、Storage Server定時向已知的tracker server(能夠是多個)發送磁盤剩餘空間、文件同步狀態、文件上傳下載次數等統計信息
1.二、Storage Server會鏈接整個集羣中全部的Tracker Server,向它們報告本身的狀態
二、選擇Tracker server
2.一、當集羣中不止一個Tracker Server時,因爲Tracker之間是徹底對等的關係,客戶端在upload文件時能夠任意選擇一個Tracker
三、選擇存儲的group
當Tracker接收到upload file的請求時,會爲該文件分配一個可存儲該文件的group,支持以下規則
3.一、Round robin,全部的group間輪詢(默認)
3.二、Specified group,指定某一個肯定的group
3.三、Load balance,剩餘存儲空間多的,group優先
四、選擇Storage Server
當選定group後,Tracker會在group內選擇一個Storage Server給客戶端,支持以下選擇Storage的規則
4.一、Round robin,在group內的全部Storage間輪詢(默認)
4.二、First server ordered by ip,按ip排序
4.三、First server ordered by priority,按優先級排序(優先級在Storage上配置)
五、選擇Storage path
當分配好Storage server後,客戶端將向Storage發送寫文件請求,Storage將會爲文件分配一個數據存儲目錄,支持以下規則(在Storage配置文件中能夠經過store_path*參數來設置,該參數能夠設置多個,經過*來區別)
5.一、Round robin,多個存儲目錄間輪詢
5.二、剩餘存儲空間最多的優先
六、生成fileid
選定存儲目錄以後,Storage會爲文件生一個fileid,由源Storage server ip、文件建立時間、文件大小、文件crc32和一個隨機數拼接而成,而後將這個二進制串進行base64編碼,轉換爲可打印的字符串。
七、選擇兩級目錄
當選定存儲目錄以後,Storage會爲文件分配一個fileid,每一個存儲目錄下有兩級256*256的子目錄,Storage會按文件fileid進行兩次hash,路由到其中一個子目錄,而後將文件以fileid爲文件名存儲到該子目錄下。
八、生成文件名
當文件存儲到某個子目錄後,既認爲該文件存儲成功,接下來會爲該文件生成一個文件名,文件名由group、存儲目錄、兩級子目錄、fileid、文件後綴名(由客戶端指定,主要用於區分文件類型)拼接而成。
寫文件時,客戶端將文件寫至group內一個Storage Server既認爲寫文件成功,Storage Server寫完文件後,會由後臺線程將文件同步至group內其餘的Storage Server。
每一個Storage寫文件後,同時會寫一份binlog,binlog裏不包含文件數據,只包含文件名等元信息,這份binlog用於後臺同步,Storage會記錄向group內其餘Storage同步的進度,以便重啓後能接上次的進度繼續同步;進度以時間戳的方式進行記錄,因此最好能保證集羣內全部Server的時鐘保持同步。
客戶端upload file成功後,會拿到一個Storage生成的文件名,接下來客戶端根據這個文件名便可訪問到該文件。
一、Tracker Server收集Storage Server的狀態信息
1.一、Storage Server定時向已知的Tracker Server(能夠是多個)發送磁盤剩餘空間、文件同步狀態、文件上傳下載次數等統計信息。
1.二、Storage Server會鏈接整個集羣中全部的Tracker Server,向他們報告本身的狀態。
二、選擇Tracker Server
2.一、跟upload file同樣,在download file時客戶端能夠選擇任意Tracker Server
三、選擇可用的Storage Server
3.一、client發送download請求給某個Tracker,必須帶上文件名信息,Tracker從文件名中解析出文件的group、路徑信息、文件大小、建立時間、源Storage Server ip等信息,而後爲該請求選擇一個Storage用來服務讀請求。
3.二、因爲group內的文件同步是在後臺異步進行的,因此有可能出如今讀的時候,文件尚未同步到某些Storage Server上,爲了儘可能避免訪問到這樣的Storage,Tracker按照以下規則選擇group內可讀的Storage
3.2.一、該文件上傳到的源頭Storage - 源頭Storage只要存活着,確定包含這個文件,源頭的地址被編碼在文件名中。
3.2.二、文件建立時間戳 == Storage被同步到時間戳 且(當前時間 - 文件建立時間戳) > 文件同步最大時間 - 文件建立後,認爲通過最大同步時間後,確定已經同步到其餘Storage了。
3.2.三、文件建立時間戳 < Storage被同步到的時間戳。 - 同步時間戳以前的文件肯定已經同步
3.2.四、(當前時間 - 文件建立時間戳) > 同步延遲閾值。 通過同步延遲閾值時間,認爲文件確定已經同步了
注:Tracker和Storage安裝,安裝過程都同樣,配置文件有差別
yum install -y gcc-c++ gcc
FastDFS依賴libevent庫
yum install -y libevent
下載地址:
https://github.com/happyfish100/libfastcommon/releases
補充
也能夠用wget方式聯網下載,這裏我是提早下載到本地客戶端,將包拖進linux中
若wget命令不能使用,請執行:yum install -y wget
wget方式:
wget https://github.com/happyfish100/libfastcommon/archive/V1.0.43.tar.gz
將下載後的包放到該目錄下
cp /usr/lib64/libfastcommon.so /usr/lib/
https://github.com/happyfish100/fastdfs/releases
cp /cyb/soft/fastdfs-6.06/conf/* /etc/fdfs
=========================分割線======================================================
-----------------Tracker和Storage共同安裝步驟結束!!!----------------------------
------------------Tracker和Storage只是配置不一樣!!!!-----------------------------
=========================分割線======================================================
vim /etc/fdfs/tracker.conf
mkdir /cyb/server/fastdfs/tracker -p
vim /etc/fdfs/storage.conf
修改內容模板
# 指定storage的組名
group_name=group1
base_path=/cyb/server/fastdfs/storage
# 若是有多個掛載磁盤則定義多個store_path
store_path0=/cyb/server/fastdfs/storage
# store_path1=.......
# store_path2=.......
# store_path3=.......
# 配置tracker服務器ip和端口
tracker_server=192.168.1.1:22122
# 若果有多個則配置多個tracker
# tracker_server=xxx.xxx.xxx.xxx:xxxx
# tracker_server=xxx.xxx.xxx.xxx:xxxx
# tracker_server=xxx.xxx.xxx.xxx:xxxx
修改:group_name
修改:base_path
修改:store_path*
補充:爲何要設置多個store_path*呢?linux若是磁盤不夠用的話,用戶能夠加硬盤,而後設置多個store_path*
修改:tracker_server
mkdir /cyb/server/fastdfs/storage -p
該步驟用於演示負載均衡,冗餘備份
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf
編輯文件:
vim /etc/rc.d/rc.local
將如下內容添加到該文件中:
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf
編輯文件:
vim /etc/rc.d/rc.local
將如下內容添加到該文件中:
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf
sudo /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
sudo /usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
查看Storage日誌
一、關閉命令: service iptables stop
二、永久關閉防火牆:chkconfig iptables off
三、兩個命令同時運行內,運行完成容後查看防火牆關閉狀態
service iptables status
FastDFS安裝成功後可經過【fdfs_test】命令測試上傳、下載等操做(三臺中的任意一臺測試便可)
vim /etc/fdfs/client.conf
mkdir /cyb/server/fastdfs/client -p
格式:
/usr/bin/fdfs_test /etc/fdfs/client.conf upload 文件路徑
/usr/bin/fdfs_test /etc/fdfs/client.conf upload /home/1.txt
此時這個地址是訪問不到的,須要與Nginx整合使用,方可訪問該文件!
#此配置文件是否已禁用 #false爲啓用 #爲殘疾人士適用 禁用=假 #綁定該主機的地址 #空用於綁定此主機的全部地址 bind_addr = #跟蹤器服務器端口 端口= 22122 #鏈接超時(以秒爲單位) #默認值爲30秒 connect_timeout = 10 #網絡超時(以秒爲單位) #默認值爲30秒 network_timeout = 60 #存儲數據和日誌文件的基本路徑 base_path = / home / yuqing / fastdfs #此服務器支持的最大併發鏈接數 #您應該將此參數設置得更大一些,例如。102400 max_connections = 1024 #接受線程數 #默認值爲1 #自V4.07起 accept_threads = 1 #工做線程數,應<= max_connections #默認值爲4 自V2.00起 work_threads = 4 #最小拋光量 #默認值8KB min_buff_size = 8KB #最大增益 #默認值128KB max_buff_size = 128KB #選擇上傳文件組的方法 #0:循環賽 #1:指定組 #2:負載均衡,選擇最大可用空間組來上傳文件 store_lookup = 2 #上傳文件的組 #當store_lookup設置爲1時,必須將store_group設置爲組名 store_group = group2 #要上傳文件的存儲服務器 #0:循環(默認) #1:第一個服務器按IP地址排序 #2:按優先級排列的第一個服務器順序(最小) #注意:若是use_trunk_file設置爲true,則必須將store_server設置爲1或2 store_server = 0 #存儲服務器上載文件的路徑(表示磁盤或掛載點) #0:循環賽 #2:負載均衡,選擇最大可用空間路徑上傳文件 store_path = 0 #要下載文件的存儲服務器 #0:循環(默認) #1:當前文件上傳到的源存儲服務器 download_server = 0 #爲系統或其餘應用程序保留的存儲空間。 #若是如下任何存儲服務器的可用(可用)空間 #一個組<= reserved_storage_space, #沒有文件能夠上傳到該組。 #字節單位能夠是如下之一: ### G或g表示千兆字節(GB) ### M或m表示兆字節(MB) ### K或k表示千字節(KB) ###無字節單位(B) ### XX.XX%做爲比例,例如reserved_storage_space = 10% reserved_storage_space = 20% #standard日誌級別爲syslog,不區分大小寫,值列表: ###緊急應急 ###警報 ###暴擊 ###錯誤 ###警告警告 ### 注意 ###信息 ###調試 log_level =信息 #unix組名以運行此程序, #未設置(空)表示由當前用戶組運行 run_by_group = #unix用戶名以運行此程序, #未設置(空)表示由當前用戶運行 run_by_user = #allow_hosts能夠屢次出現,host能夠是主機名或IP地址, #「 *」(僅一個星號)表示匹配全部IP地址 #咱們可使用像192.168.5.64/26這樣的CIDR IP #並使用如下範圍:10.0.1。[0-254]和主機[01-08,20-25] .domain.com # 例如: #allow_hosts = 10.0.1。[1-15,20] #allow_hosts = host [01-08,20-25] .domain.com #allow_hosts = 192.168.5.64 / 26 allow_hosts = * #每隔幾秒將日誌buff同步到磁盤 #默認值爲10秒 sync_log_buff_interval = 10 #檢查存儲服務器的活動間隔秒數 check_active_interval = 120 #線程堆棧大小,應> = 64KB #默認值爲256KB thread_stack_size = 256KB #自動調整存儲服務器的IP地址 #默認值爲true storage_ip_changed_auto_adjust = true #存儲同步文件的最大延遲秒數 #默認值爲86400秒(一天) 自V2.00起 storage_sync_file_max_delay = 86400 #存儲文件同步的最長時間 #默認值爲300秒 自V2.00起 storage_sync_file_max_time = 300 #若是使用中繼文件存儲幾個小文件 #默認值爲false #自V3.00起 use_trunk_file =否 #最小插槽大小,應<= 4KB #默認值爲256字節 #自V3.00起 slot_min_size = 256 #最大插槽大小,應> slot_min_size #當上傳文件的大小小於等於此值時,將其存儲到中繼文件 #默認值爲16MB #自V3.00起 slot_max_size = 16MB #中繼文件大小,應> = 4MB #默認值爲64MB #自V3.00起 trunk_file_size = 64MB #若是預先建立中繼文件 #默認值爲false #從V3.06開始 trunk_create_file_advance =否 #建立中繼文件的時基 #時間格式:HH:MM #默認值爲02:00 #從V3.06開始 trunk_create_file_time_base = 02:00 #建立Trunk文件的時間間隔,單位:秒 #默認值爲38400(一天) #從V3.06開始 trunk_create_file_interval = 86400 #建立中繼文件的閾值 #當空閒中繼文件大小小於閾值時,將建立 #中繼文件 #默認值爲0 #從V3.06開始 trunk_create_file_space_threshold = 20G #加載行李箱空閒空間時是否檢查行李箱空間佔用 #佔用的空間將被忽略 #默認值爲false #自V3.09起 #注意:將此參數設置爲true會減慢行李箱空間的加載 #啓動時。您應在必要時將此參數設置爲true。 trunk_init_check_occupying =否 #若是忽略storage_trunk.dat,則從中繼binlog從新加載 #默認值爲false #自V3.10起 #若是版本低於V3.10,則一次設置爲true進行版本升級 trunk_init_reload_from_binlog =否 #壓縮中繼binlog文件的最小間隔 #單位:秒 #默認值爲0,0表示永不壓縮 #在主幹初始化和主幹銷燬時,FastDFS壓縮主幹binlog #從新命令將此參數設置爲86400(一天) #自V5.01起 trunk_compress_binlog_min_interval = 0 #若是使用存儲ID代替IP地址 #默認值爲false #自V4.00起 use_storage_id =假 #指定存儲ID的文件名,可使用相對或絕對路徑 #自V4.00起 storage_ids_filename = storage_ids.conf #文件名中存儲服務器的id類型,值是: ## ip:存儲服務器的IP地址 ## id:存儲服務器的服務器ID #僅當use_storage_id設置爲true時,此參數纔有效 #默認值爲ip 從V4.03開始 id_type_in_filename = id #若是存儲從屬文件使用符號連接 #默認值爲false #自V4.01起 store_slave_file_use_link = false #若是天天旋轉錯誤日誌 #默認值爲false 從V4.02開始 rotation_error_log =否 #旋轉錯誤日誌的時基,時間格式:小時:分鐘 #小時從0到23,分鐘從0到59 #默認值爲00:00 從V4.02開始 error_log_rotate_time = 00:00 #當日志文件超過此大小時旋轉錯誤日誌 #0表示永不按日誌文件大小旋轉日誌文件 #默認值爲0 從V4.02開始 rotation_error_log_size = 0 #保留日誌文件的天數 #0表示不刪除舊的日誌文件 #默認值爲0 log_file_keep_days = 0 #若是使用鏈接池 #默認值爲false #自V4.05起 use_connection_pool =否 #空閒時間超過此時間的鏈接將被關閉 #單位:秒 #默認值爲3600 #自V4.05起 connection_pool_max_idle_time = 3600 #該跟蹤器服務器上的HTTP端口 http.server_port = 8080 #檢查存儲HTTP服務器的活動間隔秒數 #<= 0表示永不檢查 #默認值爲30 http.check_alive_interval = 30 #檢查存儲HTTP服務器的活動類型,值是: #tcp:僅使用HTTP端口鏈接到storge服務器, #不要求得到迴應 #http:存儲檢查有效網址必須返回http狀態200 #默認值爲tcp http.check_alive_type = tcp #檢查存儲HTTP服務器是否存在uri / url #注意:存儲嵌入HTTP服務器支持uri:/status.html http.check_alive_uri = / status.html
Nginx須要安裝在每一臺Storage服務器上,Tracker服務器上不須要安裝!!!!Nginx不明白的童鞋,能夠看我另外一篇博客:從入門到精通-Nginx,圖文並茂、負載均衡、動靜分離、虛擬主機 附案例源碼
上傳文件能夠用:
一、yum install -y lrzsz
二、rz
一、yum install -y gcc-c++ gcc (C語言依賴庫,若安裝過,可不安裝)
pcre-devel:pcre,Perl Compatible Regular Expressions,Perl腳本語言兼容正則表達式,爲Nginx提供正則表達式庫。
openssl-devel:爲Nginx提供SSL(安全套接字層)密碼庫,包含主要的密碼算法,經常使用的密鑰和證書封裝管理功能及SSL協議,並提供豐富的應用程序供測試或其餘目的使用。
二、yum -y install pcre-devel openssl-devel
vim /cyb/server/nginx/conf/nginx.conf
注:個人nginx.conf裏面內容比較少,是由於我把沒用到的東西刪掉了!~
ln -n /cyb/server/nginx/sbin/nginx /usr/local/sbin
注:創建完軟連接以後,就能夠在任意位置執行
注:啓動前,能夠先執行下:nginx -tq,看會不會報錯,沒報錯,說明nginx.conf配置文件,配置的參數是正確的
nginx
到目前爲止,nginx已經能夠正常訪問FastDFS上傳的文件內容了。
nginx若是在原來的基礎模塊上,追加新模塊,從新編譯,原先的不會覆蓋,我不知道是版本的緣由仍是怎麼回事,個人解決方案就是把原先的nginx,先刪掉,在從新一次性編譯與安裝。
rm -rf /etc/nginx/ --nginx的安裝目錄
rm -rf /usr/sbin/nginx
若是創建軟鏈接的話,別忘記一塊刪了哦
rm -rf /usr/local/sbin/nginx
上面示例,FastDFS上傳的文件,已經能夠經過nginx正常訪問了,爲何還要使用Nginx擴展模塊來訪問存儲文件呢?
注:FastDFS的Nginx擴展模塊須要安裝到每一個Storage Server中
github:https://github.com/happyfish100/fastdfs-nginx-module/releases/tag/V1.22
第6行: ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/" 第15行: CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
將/cyb/soft/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf拷貝至/etc/fdfs/下
cp /cyb/soft/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf /etc/fdfs/
vim /etc/fdfs/mod_fastdfs.conf
base_path=/cyb/server/fastdfs/storage # 基礎路徑,存儲日誌文件
tracker_server=192.168.31.220:22122 # tracker服務器的ip
url_have_group_name=true # url中是否包含group名稱
store_path0=/cyb/server/fastdfs/storage # 指定文件存儲路徑,訪問時使用該路徑
cp /usr/lib64/libfdfsclient.so /usr/lib/
注:若/usr/lib/下已存在libfdfsclient.so,則此步驟可忽略!!!
nginx -V --->V是大寫的
顯示--add-module,才表明安裝模塊成功,沒成功的,請看我採坑之路介紹
同樣能夠正常訪問
https://github.com/happyfish100/fastdfs-client-java/releases/tag/V1.26
如何打包,請看:https://www.cnblogs.com/chenyanbin/p/12831553.html
注意修改pom.xml中的<jdk.version>版本
<!--fastdfs依賴--> <dependency> <groupId>org.csource</groupId> <artifactId>fastdfs-client-java</artifactId> <version>1.27-SNAPSHOT</version> </dependency>
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.cyb</groupId> <artifactId>fastdfs-demo</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!--fastdfs依賴--> <dependency> <groupId>org.csource</groupId> <artifactId>fastdfs-client-java</artifactId> <version>1.27-SNAPSHOT</version> </dependency> </dependencies> </project>
tracker_server=192.168.31.220:22122
package com.cyb.fdfs.client; import org.csource.common.NameValuePair; import org.csource.fastdfs.*; import java.net.URLDecoder; public class FastDFSClient { private static TrackerClient trackerClient = null; private static TrackerServer trackerServer = null; private static StorageServer storageServer = null; private static StorageClient1 client = null; // fdfsClient的配置文件路徑 private static String CONF_NAME="/fdfs/fdfs_client.conf"; static { try{ //配置恩建必須制定全路徑 String confName=FastDFSClient.class.getResource(CONF_NAME).getPath(); //配置文件全路徑若是有中文,須要進行utf8轉碼 confName= URLDecoder.decode(confName,"utf8"); ClientGlobal.init(confName); trackerClient=new TrackerClient(); trackerServer=trackerClient.getConnection(); storageServer=null; client=new StorageClient1(trackerServer,storageServer); } catch (Exception e){ e.printStackTrace(); } } /** * 上傳文件方法 * @param fileName 文件全路徑 * @param extName 文件擴展名,不包含(.) * @param metas 文件擴展信息 * @return * @throws Exception */ public static String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception{ String result = client.upload_file1(fileName, extName, metas); System.out.println(result); return result; } public static void main(String[] args) { try { uploadFile("/Users/chenyanbin/Desktop/1.jpg","jpg",null); } catch (Exception e){ e.printStackTrace(); } } }
注:此次我只寫了一個上傳的,他會返回一直String字符串,也就是文件存儲的位置,前面在追加ip,拼成url,直接能夠訪問,這裏的client還有其餘API,自行查閱,client.API
上傳本地的1.jpg,而後經過ip+返回字符串,拼成url訪問
連接: https://pan.baidu.com/s/11kZfO_MRvwErnseWSVgSog 密碼: d0pp
maven源碼包,須要從新編譯
在處理海量小文件問題上,文件系統處理性能會受到顯著的影響,在讀此書(IOPS)與吞吐量(Throughput)這兩個指標上會有很多的降低。主要須要面對以下幾個問題
注:
FastDFS提供的合併存儲功能,默認建立的大文件爲64MB,而後在該大文件中存儲不少小文件。大文件中容納一個小文件的空間稱爲一個Slot,規定Slot最小值爲256字節,最大爲16MB,也就是小於256字節的文件也須要佔用256字節,超過16MB的文件不會合並存儲而是建立獨立的文件。
FastDFS提供了合併存儲功能,全部的配置在tracker.conf文件之中,開啓合併存儲只須要設置比:use_trunk_file=true 和store_server=1
vim /etc/fdfs/tracker.conf
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
使用FastDFS存儲一個圖片的多個分辨率的備份時,但願只記錄源圖的fileid,並能將其分辨率的圖片與源圖關聯。可使用從文件方法
名詞註解:主從文件是指文件ID有關聯的文件,一個主文件能夠對應多個從文件。
一、先上傳主文件(既:源文件,獲得主文件FID)
二、而後上傳從文件(既:縮略圖),指定主文件FID和從文件後綴名,上傳後獲得從文件FID
package com.cyb.fdfs.client;
import com.sun.tools.corba.se.idl.StringGen;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import java.net.URLDecoder;
public class FastDFSClient2 {
private static TrackerClient trackerClient = null;
private static TrackerServer trackerServer = null;
private static StorageServer storageServer = null;
private static StorageClient1 client = null;
// fdfsClient的配置文件路徑
private static String CONF_NAME = "/fdfs/fdfs_client.conf";
static {
try {
//配置恩建必須制定全路徑
String confName = FastDFSClient2.class.getResource(CONF_NAME).getPath();
//配置文件全路徑若是有中文,須要進行utf8轉碼
confName = URLDecoder.decode(confName, "utf8");
ClientGlobal.init(confName);
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageServer = null;
client = new StorageClient1(trackerServer, storageServer);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 上傳主文件
*
* @param filePath
* @return 主文件ID
* @throws Exception
*/
public static String uploadFile(String filePath) throws Exception {
String fileId = "";
String fileExtName = "";
if (filePath.contains(".")) {
fileExtName = filePath.substring(filePath.lastIndexOf(".")+1);
} else {
return fileId;
}
try {
fileId = client.upload_file1(filePath, fileExtName, null);
} catch (Exception e) {
e.printStackTrace();
} finally {
trackerServer.close();
}
return fileId;
}
/**
* 上傳從文件
*
* @param masterFileId FastDFS服務器返回的主文件的fileid
* @param prefixName 從文件後綴名(如:_200*200)
* @param slaveFilePath 從文件所在路徑(主從文件在本地都須要有對應的文件)
* @return
* @throws Exception
*/
public static String uploadSlaveFile(String masterFileId, String prefixName, String slaveFilePath) throws Exception {
String slaveFileId = "";
String slaveFileExtName = "";
if (slaveFilePath.contains(".")) {
slaveFileExtName = slaveFilePath.substring(slaveFilePath.lastIndexOf(".") + 1);
} else {
return slaveFileId;
}
try {
slaveFileId = client.upload_file1(masterFileId, prefixName, slaveFilePath, slaveFileExtName, null);
} catch (Exception e) {
e.printStackTrace();
} finally {
trackerServer.close();
}
return slaveFileId;
}
public static int download(String fileId, String localFile) throws Exception {
int result = 0;
//創建鏈接
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getConnection();
StorageServer storageServer = null;
StorageClient1 client = new StorageClient1(trackerServer, storageServer);
//上傳文件
try {
result = client.download_file1(fileId, localFile);
} catch (Exception e) {
e.printStackTrace();
} finally {
trackerServer.close();
}
return result;
}
public static void main(String[] args) {
try {
//上傳主文件
String masterFileId=uploadFile("/Users/chenyanbin/Desktop/1.jpg");
System.out.println("主文件:"+masterFileId);
//下載上傳成功的主文件
download(masterFileId,"/Users/chenyanbin/Desktop/11.jpg");
//第三個參數:待上傳的從文件(由此可知道,還須要把以前的下載,在本地生成後,在上傳)
String slaveFileId=uploadSlaveFile(masterFileId,"_120x120","/Users/chenyanbin/Desktop/2.jpg");
System.out.println("從文件:"+slaveFileId);
//下載上傳成功的縮略圖
download(slaveFileId,"/Users/chenyanbin/Desktop/22.jpg");
} catch (Exception e) {
e.printStackTrace();
}
}
}
nginx_http_image_filter_module在nginx 0.7.54之後纔出現的,用於對jpeg、gif和png圖片進行轉換處理(壓縮、裁剪、旋轉)。這個模塊默認不被編譯,因此要在編譯nginx源碼的時候,加入相關配置信息
安裝gd,HttpImageFilterModule模塊須要依賴gd-devel的支持
yum -y install gd-devel
--with-http_image_filter_module
需求,假設咱們圖片的真實路徑是在本地/cyb/data/img/1.jpg,下面有狠毒ojpg格式的圖片,咱們但願經過訪問/img/1_100x100.jpg這樣的請求路徑能夠生成寬爲100,高也爲100的小圖,而且請求的寬和高是可變的,那麼這時候須要在nginx模塊中攔截請求並返回轉換後的小圖,在對應server{}段中進行配置。
location ~* /img/(.*)_(\d+)x(\d+)\.(jpg|gif|png)$ {
root /;
set $s $1;
set $w $2;
set $h $3;
set $t $4;
image_filter resize $w $h;
image_filter_buffer 10M;
rewrite ^/img/(.*)$ /cyb/data/img/$s.$t break;
}
旋轉:image_filter_rotate 度數;
image_filter rotate 90; --旋轉90度
image_filter rotate 180; --旋轉180度
裁剪:image_filter crop width height;
image_filter crop 120 60; --裁剪成寬120,高60
注意:該圖片必定要有讀取權限,要否則nginx是讀取不到的!!!
nginx -s stop
nginx
location ~ group1/M00/(.+)_(\d+)x(\d+)\.(jpg|gif|png){
# 設備別名(相似於root的用法)
alias /cyb/server/fastdfs/storage/data/;
# fastdfs中的ngx_fastdfs_module模塊
ngx_fastdfs_module;
set $w $2;
set $h $3;
if ($w != "0"){
rewrite group1/M00(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ group1/M00$1.$4 break;
}
if ($h != "0"){
rewrite group1/M00(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ group1/M00$1.$4 break;
}
# 根據給定長寬生成縮略圖
image_filter resize $w $h;
# 原圖最大2M,要裁剪的圖片超過2M返回415錯誤,須要調節參數image_filter_buffer
image_filter_buffer 2M;
}
編譯nginx前,請確認是否安裝過libcurl-dev libgd2-dev libpcre-dev依賴庫
yum install -y dg-devel pcre-devel libcurl-devel
https://github.com/oupula/ngx_image_thumb/archive/master.zip
tar -zxvf ngx_image_thumb-master.zip
make && make install
location /img/ {
root /cyb/data/;
# 開啓壓縮功能
image on;
# 是否不生成圖片而直接處理後輸出
image_output on;
image_water on;
# 水印類型:0爲圖片水印,1爲文字水印
image_water_type 0;
#水印出現位置
image_water_pos 9;
# 水印透明度
image_water_transparent 80;
# 水印文件
image_water_file "/cyb/data/logo.png";
}
nginx -s stop
nginx
其中c是生成圖片縮略圖的參數,300是生成的縮略圖的寬,200是高
參數說明:
一共能夠生成四種不一樣類型的縮略圖
C:參數按照請求寬高比例從圖片高度 10% 處開始截取圖片,而後縮放/放大指定尺寸(圖片縮略圖大小等於請求的寬高)
m:參數按請求寬高比例居中截取圖片,而後縮放/放大到指定尺寸(圖片縮略圖大小等於請求的寬高)
t:參數按請求寬高比例按比例縮放/放大到指定尺寸(圖片縮略圖大小可能小於請求的寬高)
w:參數按請求寬高比例縮放/放大到指定尺寸,空白處填充白色背景色(圖片縮略圖大小等於請求的寬高)
細心的小夥伴發現,水印沒有出現,術印出沒出來有個閾值:600x600(版本不一樣,閾值可能不一樣)
location /group1/M00/ {
alias /cyb/server/fastdfs/storage/data/;
image on;
image_output on;
image_jpeg_quality 75;
image_water on;
image_water_type 0;
image_water_pos 9;
image_water_transparent 80;
image_water_file "/cyb/data/logo.png";
# 配置一個不存在的圖片地址,防止查看縮略圖時照片不存在,服務器響應慢
# image_backend_server http://www.baidu.com/img/baidu_jpglogo3.gif
}