阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

通过tfs-nginx进行图片压缩过程

121次阅读
没有评论

共计 4349 个字符,预计需要花费 11 分钟才能阅读完成。

TFS 是一个高可扩展、高可用、高性能、面向互联网服务的分布式文件系统,主要针对海量的非结构化数据,它构筑在普通的 Linux 机器 集群上,可为外部提供高可靠和高并发的存储访问。TFS 为淘宝提供海量小文件存储,通常文件大小不超过 1M,满足了淘宝对小文件存储的需求,被广泛地应用 在淘宝各项应用中。它采用了 HA 架构和平滑扩容,保证了整个文件系统的可用性和扩展性。同时扁平化的数据组织结构,可将文件名映射到文件的物理地址,简化了文件的访问流程,一定程度上为 TFS 提供了良好的读写性能。

NameServer 主要功能是: 管理维护 Block 和 DataServer 相关信息, 包括 DataServer 加入,退出, 心跳信息, block 和 DataServer 的对应关系建立,解除。正常情况下,一个块会在 DataServer 上存在,主 NameServer 负责 Block 的创建,删除,复制,均衡,整理,NameServer 不负责实际数据的读写,实际数据的读写由 DataServer 完成。

DataServer 主要功能是: 负责实际数据的存储和读写。

当客户端要上传一个图片,通过 nameserver 将图片写入 dataserver 中,在 nameserver 中保留文件的名字;当客户端需要下载图片时,通过访问 tfs-nginx 去 nameserver 中找到该图片,然后再去 dataserver 中下载。

在三台虚拟机上分别安装 tfs-ns、tfs-ds、tfs-nginx

在 nameserver,dataserver,nginx 三部分都安装好后,来研究一下将图片进行压缩的代码过程,下面是项目真实环境,可以直接访问图片并压缩到对应的大小格式

在 tfs-nginx 安装了 lua 模块,在 tfs-nginx 中添加配置文件 lua.conf。在主配置文件中加载 lua.conf

下面是 lua.conf 文件中的一部分内容,编写了将图片压缩的过程

#$filePath /Disk/tfsimage/xxxxxxxx.jpg.20×20.jpg
#$reqPath /xxxxxxxx.jpg.20×20.jpg
#$filename xxxxxxxx.jpg
#$file /Disk/tfsimage/xxxxxxxx.jpg.20×20.jpg
#$fileone  /Disk/tfsimage/xxxxxxxx.jpg
# 定义变量
set $image_root /Disk/tfsimage;
# 这则匹配是否是我们要的格式
if ($uri ~* “/images/([0-9a-zA-Z_!]+).(([^.]+).*)”) {
set $filePath “$image_root/$1.$2”;
set $reqPath  “/$1.$2”;
set $filename “$1.$3”;
}
set $file “$image_root$reqPath”;
set $fileone “$image_root/$filename”;
#lua 语法入口
rewrite_by_lua ‘
# 定义方法 file_exists
function file_exists(name)
# 以只读模式打开一个文件
local f=io.open(name,”r”)
# 打开的文件是否不等于空,如果不等于空证明之前有这个文件,关闭文件并返回真;如果等于空则返回假;
if f~=nil then io.close(f) return true else return false end
end ;
# 定义方法 tfsfile
function  tfsfile(name)
# 把叹号替换成点,并把替换后的字符串复制给 res
local res =string.gsub(name,”!”,”.”);
# 返回 res
return res;
end;
# 首先更改图片名字中的叹号,在判断图片是否存在,如果存在就重定向到 innerImages
if file_exists(tfsfile(ngx.var.file)) then  ngx.req.set_uri(“/innerImages” .. tfsfile(ngx.var.reqPath), true);
else
# 如果不存在,则判断源文件在不在,如果在打印 111
if file_exists(tfsfile(ngx.var.fileone)) then print(“111”) else
# 如果不在,首先把图片名字中的叹号替换,然后把图片名字赋值给 resfile
local resfile = tfsfile(ngx.var.filename);
# 定义命令 command,下载需要的图片
command = string.format(“wget -P /Disk/tfsimage/ http://192.168.1.244:8080/v1/tfs/”..resfile)
# 执行刚才定义的 command 命令
os.execute(command)
# 定义命令 commandt,给下载的图片打水印(/Disk/jinlejia.png 水印图;/Disk/tfsimage/ 原图;/Disk/tfsimage/ 打水印后的图)
commandt = “gm composite -gravity center -dissolve 70 /Disk/jinlejia.png /Disk/tfsimage/”.. ngx.var.filename ..  ” /Disk/tfsimage/”..ngx.var.filename;
# 执行 commandt 命令
os.execute(commandt)
end;
# 定义变量 originalUri,area
local originalUri;
local area;
# 将图片名中叹号替换,在 filepath 中找到 20×20.jpg 的索引位置,并赋值给 index
local index = string.find(tfsfile(ngx.var.filePath), “([0-9]+)x([0-9]+)”);
# 如果 index 为空,则 originalUri= 叹号替换后的 filePath
if index==nil then  originalUri = tfsfile(ngx.var.filePath);
else
# 如果 index 存在,首先把图片名字中的叹号替换,将 filepath 从头截取到 20×20.jpg 的索引位置的前两位,也就是 /Disk/tfsimage/xxxxxxxx.jpg,将值赋给 originalUri
originalUri = string.sub(tfsfile(ngx.var.filePath), 0, index-2);
# 首先把图片名字中的叹号替换,将 filePath 的 20×20.jpg 截取出来并赋给 area
area = string.sub(tfsfile(ngx.var.filePath), index);
# 在 area 中,也就是 20×20.jpg 中找到“.”的索引位置,将索引位置赋值给 index
index = string.find(area, “([.])”);
# 将 area 截取到“.”的前一位,就是 20×20,并赋值给新的 area
area = string.sub(area, 0, index-1);
end
# 定义变量 image_sizes,存放图片的规格
local image_sizes={“100×66″,”105×70″,”1200×125″,”1200×260″,”1200×320″,”130×45″,”140×165″,”185×123″,”190×126″,”200×133″,”205×135″,”210×140″,”214×142″,”220×146″,”220×180″,”290×193″,”395×90″,”400×340″,”595×130″,”60×60″,”600×320″,”650×240″,”912×95″,”105×90″,”130×130″,”360×200″,”200×200″,”370×246″,”600×600″,”250×200″,”600×400″,”670×420″,”100×100″,”160×160″,”80×80″,”200×150″,”80×45″,”138×84″,”820×425″,”290×204″,”810×497″,”90×90″,”260×160″,”290×178″,”450×280″,”380×240″,”596×276″,”292×346″,”292×178″,”292×345″,”294×346″,”294×182″,”294×272″,”290×276″,”320×180″,”620×382″,”120×40″,”300×180″,”80×50″,”360×194″,”550×337″,”800×600”};
# 定义方法,如果得到的 area 与 image_sizes 中的某个大小匹配的话,返回真
function table.contains(table, element)
# 将 table 中的值进行循环,挨个与 element 匹配
for _, value in pairs(table) do
# 如果匹配上则返回真,否则返回假
if value == element then
return true
end
end
return false
end
# 如果 area 与 image_sizes 中的某个大小匹配的话
if table.contains(image_sizes, area) then
# 定义命令 command,将原图压缩成对应的大小 
local command = “gm convert ” ..  originalUri  .. ” -thumbnail ” .. area .. ” -background white -gravity center -extent ” .. area .. ” ” .. tfsfile(ngx.var.file);
# 执行刚才定义的 command 命令
os.execute(command);
# 如果图片没有压缩,执行上面的一系列压缩过程,然后重定向
ngx.req.set_uri(“/innerImages” .. tfsfile(ngx.var.reqPath), true);
else
# 如果能够找到压缩过的图片,直接重定向
ngx.req.set_uri(“/innerImages” .. tfsfile(ngx.var.reqPath), true);
end;
end
‘;
}

浏览器访问路径为 tfs-nginxIP 地址 /image/ 图片名.jpg
若要访问压缩的图片,访问 tfs-nginxIP 地址 /image/ 图片名.jpg.800×600.jpg 即可

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-09/146751.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计4349字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中