如何搭建fastdfs服务及单机redis服务

如何搭建fastdfs服务及单机redis服务

这篇文章主要介绍“如何搭建fastdfs服务及单机redis服务”,在日常操作中,相信很多人在如何搭建fastdfs服务及单机redis服务问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何搭建fastdfs服务及单机redis服务”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

fastdfs服务搭建

先要安装gcc编译器:

yum-yinstallgcc-c++

安装lib依赖包

tar-zxvfV1.0.43.tar.gzcdlibfastcommon-1.0.43./make.sh./make.shinstall

ln-s/usr/lib64/libfastcommon.so/usr/local/lib/libfastcommon.soln-s/usr/lib64/libfastcommon.so/usr/lib/libfastcommon.soln-s/usr/lib64/libfdfsclient.so/usr/local/lib/libfdfsclient.soln-s/usr/lib64/libfdfsclient.so/usr/lib/libfdfsclient.so

安装fastdfs服务

tar-zxvfV6.06.tar.gzcdfastdfs-6.06./make.sh./make.shinstall

配置Tracker服务

mkdir-p/data/fastdfs/trackercd/etc/fdfscptracker.conf.sampletracker.confvimtracker.conf

要修改的内容为

#启用配置文件(默认启用)disabled=false#设置tracker的端口号,通常采用22122这个默认端口port=22122#设置tracker的数据文件和日志目录base_path=/data/fastdfs/tracker#设置http端口号,默认为8080http.server_port=80

启动服务

#启动/usr/bin/fdfs_trackerd/etc/fdfs/tracker.confstart

查看是否启动

#查看启动端口ss-ant|grep22122

查看启动日志

#查看启动日志tail-f/data/fastdfs/tracker/logs/trackerd.log


加入开机启动

vim/etc/rc.d/rc.local

在加入启动命令


如果重启后发现未能自动启动则通过命令

ll/etc/rc.d/rc.local

检查一下rc.local是否具备可执行权限,若是无可执行权限则通过命令进行授权

chmod+x/etc/rc.d/rc.local

配置Storage服务

mkdir-p/data/fastdfs/storagemkdir-p/data/fastdfs/storage/filecd/etc/fdfscpstorage.conf.samplestorage.confvimstorage.conf

要修改的内容为

#启用配置文件(默认启用)disabled=false#组名,根据实际情况修改group_name=group1#设置storage的端口号,默认是23000,同一个组的storage端口号必须一致port=23000#设置storage数据文件和日志目录base_path=/data/fastdfs/storage#存储路径个数,需要和store_path个数匹配store_path_count=1#实际文件存储路径store_path0=/data/fastdfs/storage/file#tracker服务器的IP地址和端口号,如果是单机搭建,IP不要写127.0.0.1,否则启动不成功(此处的ip是我的CentOS虚拟机ip)tracker_server=172.16.6.50:22122#设置http端口号http.server_port=8888

启动服务

#启动/usr/bin/fdfs_storaged/etc/fdfs/storage.confstart

查看启动端口

#查看启动端口ss-ant|grep23000

查看启动日志

#查看启动日志tail-f/data/fastdfs/storage/logs/storaged.log

通过monitor查看storage是否绑定成功

[root@localhost/]#/usr/bin/fdfs_monitor/etc/fdfs/storage.conf[2021-09-2312:59:26]DEBUG-base_path=/opt/fastdfs_storage,connect_timeout=30,network_timeout=60,tracker_server_count=1,anti_steal_token=0,anti_steal_secret_keylength=0,use_connection_pool=0,g_connection_pool_max_idle_time=3600s,use_storage_id=0,storageserveridcount:0server_count=1,server_index=0trackerserveris172.16.8.11:22122groupcount:1Group1:groupname=group1disktotalspace=6818MBdiskfreespace=2169MBtrunkfreespace=0MB……

加入开机启动

vim/etc/rc.d/rc.local

在该文件中,加入启动命令

/usr/bin/fdfs_storaged/etc/fdfs/storage.confstart

测试验证

[root@localhost~]#ps-ef|grepfdfsroot1033517685023:50pts/300:00:00grep--color=autofdfsroot133351013:17?00:00:07/usr/bin/fdfs_storaged/etc/fdfs/storage.confstartroot157791012:59?00:00:04/usr/bin/fdfs_trackerd/etc/fdfs/tracker.conf

用fdfs客户端进行测试

cp/etc/fdfs/client.conf.sample/etc/fdfs/client.conf

测试时需要设置客户端的配置文件

vim/etc/fdfs/client.conf

打开文件后依次做以下修改:

#tracker服务器文件路径base_path=/data/fastdfs/tracker#tracker服务器IP地址和端口号tracker_server=172.16.7.50:22122#tracker服务器的http端口号,必须和tracker的设置对应起来http.tracker_server_port=80

配置完成后就可以模拟文件上传了,先给/data目录下放一文件test.txt,然后通过执行客户端上传命令尝试上传:

/usr/bin/fdfs_upload_file/etc/fdfs/client.conf/data/test.txt

单机redis服务搭建

1.获取redis资源,并解压

tarxzvfredis-4.0.8.tar.gz

2.安装

cdredis-4.0.8makecdsrcmakeinstallPREFIX=/usr/local/redis

3.移动配置文件到安装目录下

cd../mkdir/usr/local/redis/etcmvredis.conf/usr/local/redis/etc

4.配置redis为后台启动

vim/usr/local/redis/etc/redis.conf

注意,将daemonize no 改成daemonize yes,及注释掉bind 127.0.0.1,可以远程访问

5.将redis加入到开机启动 

vim/etc/rc.d/rc.local

在里面添加内容:

/usr/local/redis/bin/redis-server/usr/local/redis/etc/redis.conf

意思就是开机调用这段开启redis的命令.

6.启动redis

/usr/local/redis/bin/redis-server/usr/local/redis/etc/redis.conf

7.将redis-cli,redis-server拷贝到bin下,让redis-cli指令可以在任意目录下直接使用

cp/usr/local/redis/bin/redis-server/usr/local/bin/cp/usr/local/redis/bin/redis-cli/usr/local/bin/

8.设置redis密码

a.运行命令:

redis-cli

b.查看现有的redis密码(可选操作,可以没有)

运行命令:

configgetrequirepass

如果没有设置过密码的话运行结果会如下图所示

c.设置redis密码

运行命令:

configsetrequirepass*******

(******为你要设置的密码),设置成功的话会返回‘OK’字样

d.测试连接

重启redis服务

//****为你设置的密码redis-cli-h127.0.0.1-p6379-a****

也可以,输入 redis-cli 进入命令模式,使用 auth '*****' (****为你设置的密码)登陆     

9.让外网能够访问redis

a.配置防火墙:

#开放6379端口firewall-cmd--zone=public--add-port=6379/tcp--permanent#重启防火墙以使配置即时生效systemctlrestartfirewalld#查看系统所有开放的端口firewall-cmd--zone=public--list-ports

b.若是仍不可远程访问:

此时 虽然防火墙开放了6379端口,但是外网还是无法访问的,因为redis监听的是127.0.0.1:6379,并不监听外网的请求。

  1. 把文件夹目录里的redis.conf配置文件里的bind 127.0.0.1前面加#注释掉

  2. 命令:redis-cli连接到redis后,通过 config get daemonize和config get protected-mode 是不是都为no,如果不是,就用config set 配置名 属性 改为no。

其他redis相关常用命令  

卸载redis:

#停止redispkillredis  #删除安装目录rm-rf/usr/local/redis#删除所有redis相关命令脚本rm-rf/usr/bin/redis-*#删除redis解压文件夹rm-rf/root/download/redis-4.0.4

报异常,尝试重启

原因: Redis已经启动

解决: 关掉Redis,重启即可

redis-clishutdownredis-server&

然后你就能看到Redis愉快的运行了.

客户端检测连接是否正常

使用redis-cli客户端检测连接是否正常

$redis-cli127.0.0.1:6379>keys*(emptylistorset)127.0.0.1:6379>setkey"helloworld"OK127.0.0.1:6379>getkey"helloworld"

Redis客户端常见操作

Redis是key-value数据库,支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

当value是string类型,命令包括set get setnx incr del 等。

>setserver:name"fido"//设置键值OK>getserver:name//获取键值"fido">setnxconnections10//setifnotexistsOK>incrconnections//原子性增加values值(integer)11>incrconnections(integer)12>delconnections//删除key(integer)1>incrconnections(integer)1

当value是list类型,命令包括rpush lpush llen lrange lpop rpop del 等。

>rpushfriends"Alice"//在末尾追加(integer)1>rpushfriends"Bob"(integer)2>lpushfriends"Sam"//插入到开头(integer)3>lrangefriends0-1//返回列表的子集,类似切片操作1)"Sam"2)"Alice"3)"Bob">lrangefriends011)"Sam"2)"Alice">lrangefriends121)"Alice"2)"Bob">llenfriends//返回列表长度(integer)3>lpopfriends//删除并返回列表第一个元素"Sam">rpopfriends//删除并返回列表最后一个元素"Bob">lrangefriends0-11)"Alice">delfriends//删除key(integer)1//1表示成功,0表示失败

当value是set类型,命令包括sadd srem sismember smembers sunion del等。

>saddsuperpowers"flight"//添加元素(integer)1>saddsuperpowers"x-rayvision"(integer)1>saddsuperpowers"reflexes"(integer)1>sremsuperpowers"reflexes"//删除元素1>sismembersuperpowers"flight"//测试元素是否在集合中(integer)1>sismembersuperpowers"reflexes"(integer)0>smemberssuperpowers//返回集合中所有元素1)"x-rayvision"2)"flight">saddbirdpowers"pecking"(integer)1>saddbirdpowers"flight"(integer)1>sunionsuperpowersbirdpowers//合并多个set,返回合并后的元素列表1)"x-rayvision"2)"flight"3)"pecking">delsuperpowers//删除key(integer)1

当value是zset类型,命令包括 zadd zrange del等,注意给value一个编号用于排序。

>zaddhacker1940"AlanKay"//给value指定一个编号,比如以年份1940作为编号(integer)1>zaddhacker1906"GraceHopper"(integer)1>zaddhacker1953"RichardStallman"(integer)1>zaddhacker1965"YukihiroMatsumoto"(integer)1>zaddhacker1916"ClaudeShannon"(integer)1>zaddhacker1969"LinuxTorvalds"(integer)1>zaddhacker1957"SophieWilson"(integer)1>zaddhacker1912"AlanTuring"(integer)1>zrangehacker24//切片返回有序集合中元素1)"ClaudeShannon"2)"AlanKay"3)"RichardStallman">delhacker//删除key(integer)1

当value是hash类型,hash类型可以理解为字典,需要给value指定一个field用于映射,命令包括hset hmset hget hgetall hdel hincrby del 等。

>hsetuser:1000name"JohnSmith"//给value指定一个field,比如name(integer)1>hsetuser:1000email"john.smith@example.com"(integer)1>hsetuser:1000password"s3cret"(integer)1>hgetalluser:1000//获得hash表中所有成员,包括field和value1)"name"2)"JohnSmith"3)"email"4)"john.smith@example.com"5)"password"6)"s3cret">hmsetuser:1001name"MaryJones"password"hidden"email"mjones@example.com"//设置多个field和valueOK>hgetuser:1001name//根据field获取value"MaryJones">hsetuser:1000visits10//field可以映射到数字值(integer)1>hincrbyuser:1000visits1//原子性增加value的值,增加1(integer)11>hincrbyuser:1000visits10//增加10(integer)21>hdeluser:1000visits//删除field及其value(integer)1>hincrbyuser:1000visits1(integer)1>deluser:1000//删除key(integer)1

设置和查看key的生命周期,key过期会被自动删除,命令包括expire ttl 等。

>setresource:lock"RedisDemo"OK>expireresource:lock120//设置生命周期为120s(integer)1>ttlresource:lock//查看当前生命周期还剩多少时间(integer)109>ttlresource:lock//120s后查看,返回-2表示已过期或不存在(integer)-2>setresource:lock"RedisDemo2"OK>ttlresource:lock//返回-1表示永不过期(integer)-1

springboot实现h5与fastdfs之间的断点续传,大文件上传,秒传文件和批量上传

对比,只是单纯返回一个String类型?

改为upload_list8888,页面调用是失败的

改回upload_list

ThreadLocal与redis秒配,解决了redis线程池在被共享访问时带来的线程安全问题

打个比方,现在公司所有人都要填写一个表格,但是只有一支笔,这个时候就只能上个人用完了之后,下个人才可以使用,为了保证"笔"这个资源的可用性,只需要保证在接下来每个人的获取顺序就可以了,这就是 lock 的作用,当这支笔被别人用的时候,我就加 lock,你来了那就进入队列排队等待获取资源(非公平方式那就另外说了),这支笔用完之后就释放 lock ,然后按照顺序给下个人使用。

但是完全可以一个人一支笔对不对,这样的话,你填写你的表格,我填写我的表格,咱俩谁都不耽搁谁。这就是 ThreadLocal 在做的事情,因为每个 Thread 都有一个副本,就不存在资源竞争,所以也就不需要加锁,这不就是拿空间去换了时间嘛!

了解决redis线程池对象(笔),不能被多线程(多个人)共享访问的问题,通过 threadLocal.set() 方法,将redis线程池对象实例保存在每个线程,自己所拥有的 threadLocalMap中(生成多个副本)。

这样的话,每个线程都使用自己的redis线程池对象实例,彼此不会影响,从而达到了隔离的作用,这样就解决了redis线程池对象在被共享访问时带来的线程安全问题。

importcn.hutool.core.util.StrUtil;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importredis.clients.jedis.Jedis;importredis.clients.jedis.JedisPool;importredis.clients.jedis.JedisPoolConfig;importjava.util.List;publicclassRedisUtil{privateRedisUtil(){}privatestaticLogger_logger=LoggerFactory.getLogger(RedisUtil.class);;protectedstaticfinalThreadLocal<Jedis>threadLocalJedis=newThreadLocal<Jedis>();//Redis服务器IPprivatestaticStringADDR_ARRAY=ReadProper.getResourceValue("spring.redis.host");//Redis的端口号privatestaticintPORT=Integer.parseInt(ReadProper.getResourceValue("spring.redis.port"));//访问密码privatestaticStringAUTH=ReadProper.getResourceValue("spring.redis.password");//可用连接实例的最大数目&#xff0c;默认值为8&#xff1b;//如果赋值为-1&#xff0c;则表示不限制&#xff1b;如果pool已经分配了maxActive个jedis实例&#xff0c;则此时pool的状态为exhausted(耗尽)。privatestaticintMAX_ACTIVE=-1;//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例&#xff0c;默认值也是8。privatestaticintMAX_IDLE=16;//等待可用连接的最大时间&#xff0c;单位毫秒&#xff0c;默认值为-1&#xff0c;表示永不超时。如果超过等待时间&#xff0c;则直接抛出JedisConnectionException&#xff1b;privatestaticintMAX_WAIT=1000*5;//超时时间privatestaticintTIMEOUT=1000*5;//在borrow一个jedis实例时&#xff0c;是否提前进行validate操作&#xff1b;如果为true&#xff0c;则得到的jedis实例均是可用的&#xff1b;privatestaticbooleanTEST_ON_BORROW=true;privatestaticJedisPooljedisPool;//默认的数据库为0/***redis过期时间,以秒为单位*/publicfinalstaticintEXRP_HOUR=60*60;//一小时publicfinalstaticintEXRP_DAY=60*60*24;//一天publicfinalstaticintEXRP_MONTH=60*60*24*30;//一个月/***初始化Redis连接池,注意一定要在使用前初始化一次,一般在项目启动时初始化就行了*/publicstaticJedisPoolinitialPool(){JedisPooljp=null;try{JedisPoolConfigconfig=newJedisPoolConfig();config.setMaxTotal(MAX_ACTIVE);config.setMaxIdle(MAX_IDLE);config.setMaxWaitMillis(MAX_WAIT);config.setTestOnBorrow(TEST_ON_BORROW);config.setTestOnCreate(true);config.setTestWhileIdle(true);config.setTestOnReturn(true);config.setNumTestsPerEvictionRun(-1);jp=newJedisPool(config,ADDR_ARRAY,PORT,TIMEOUT,AUTH);jedisPool=jp;threadLocalJedis.set(getJedis());}catch(Exceptione){e.printStackTrace();_logger.error("redis服务器异常",e);}returnjp;}publicstaticvoidclose(Jedisjedis){if(threadLocalJedis.get()==null&&jedis!=null){jedis.close();}}///**//*在多线程环境同步初始化//*///privatestaticsynchronizedvoidpoolInit(){//if(jedisPool==null){//initialPool();//}//}/***获取Jedis实例,一定先初始化**@returnJedis*/publicstaticJedisgetJedis(){booleansuccess=false;Jedisjedis=null;//if(jedisPool==null){//poolInit();//}inti=0;while(!success){i++;try{if(jedisPool!=null){jedis=threadLocalJedis.get();if(jedis==null){jedis=jedisPool.getResource();}else{if(!jedis.isConnected()&&!jedis.getClient().isBroken()){threadLocalJedis.set(null);jedis=jedisPool.getResource();}//System.out.println(Thread.currentThread().getName()+":第"+i+"次获取成功#@利用了本地缓存redis");returnjedis;}}else{thrownewRuntimeException("redis连接池初始化失败");}}catch(Exceptione){System.out.println(Thread.currentThread().getName()+":第"+i+"次获取失败!!!");success=false;e.printStackTrace();_logger.error("redis服务器异常",e);}if(jedis!=null){success=true;}if(i>=10&&i<20){try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}}if(i>=20&&i<30){try{Thread.sleep(2000);}catch(InterruptedExceptione){e.printStackTrace();}}if(i>=30&&i<40){try{Thread.sleep(3000);}catch(InterruptedExceptione){e.printStackTrace();}}if(i>=40){System.out.println("redis彻底连不上了~~~~(>_<)~~~~");returnnull;}}if(threadLocalJedis.get()==null){threadLocalJedis.set(jedis);}//System.out.println(Thread.currentThread().getName()+":第"+i+"次获取成功@");returnjedis;}/***设置String**@paramkey*@paramvalue*/publicstaticvoidsetString(Stringkey,Stringvalue){Jedisjo=null;try{value=StrUtil.isBlank(value)?"":value;jo=getJedis();jo.set(key,value);}catch(Exceptione){threadLocalJedis.set(null);_logger.error("redis服务器异常",e);thrownewRuntimeException("redis服务器异常");}finally{if(jo!=null){close(jo);}}}/***设置过期时间**@paramkey*@paramseconds以秒为单位*@paramvalue*/publicstaticvoidsetString(Stringkey,intseconds,Stringvalue){Jedisjo=null;try{value=StrUtil.isBlank(value)?"":value;jo=getJedis();jo.setex(key,seconds,value);}catch(Exceptione){threadLocalJedis.set(null);e.printStackTrace();_logger.error("redis服务器异常",e);thrownewRuntimeException("redis服务器异常");}finally{if(jo!=null){close(jo);}}}/***获取String值**@paramkey*@returnvalue*/publicstaticStringgetString(Stringkey){Jedisjo=null;try{jo=getJedis();if(jo==null||!jo.exists(key)){returnnull;}returnjo.get(key);}catch(Exceptione){threadLocalJedis.set(null);e.printStackTrace();_logger.error("redis服务器异常",e);thrownewRuntimeException("redis操作错误");}finally{if(jo!=null){close(jo);}}}publicstaticlongincrBy(Stringkey,longinteger){Jedisjo=null;try{jo=getJedis();returnjo.incrBy(key,integer);}catch(Exceptione){threadLocalJedis.set(null);e.printStackTrace();_logger.error("redis服务器异常",e);thrownewRuntimeException("redis操作错误");}finally{if(jo!=null){close(jo);}}}publicstaticlongdecrBy(Stringkey,longinteger){Jedisjo=null;try{jo=getJedis();returnjo.decrBy(key,integer);}catch(Exceptione){threadLocalJedis.set(null);e.printStackTrace();_logger.error("redis服务器异常",e);thrownewRuntimeException("redis操作错误");}finally{if(jo!=null){close(jo);}}}//删除多个keypublicstaticlongdelKeys(String[]keys){Jedisjo=null;try{jo=getJedis();returnjo.del(keys);}catch(Exceptione){threadLocalJedis.set(null);e.printStackTrace();_logger.error("redis服务器异常",e);thrownewRuntimeException("redis操作错误");}finally{if(jo!=null){close(jo);}}}//删除单个keypublicstaticlongdelKey(Stringkey){Jedisjo=null;try{jo=getJedis();returnjo.del(key);}catch(Exceptione){threadLocalJedis.set(null);e.printStackTrace();_logger.error("redis服务器异常",e);thrownewRuntimeException("redis操作错误");}finally{if(jo!=null){close(jo);}}}//添加到队列尾publicstaticlongrpush(Stringkey,Stringnode){Jedisjo=null;try{jo=getJedis();returnjo.rpush(key,node);}catch(Exceptione){threadLocalJedis.set(null);e.printStackTrace();_logger.error("redis服务器异常",e);thrownewRuntimeException("redis操作错误");}finally{if(jo!=null){close(jo);}}}//删除list元素publicstaticlongdelListNode(Stringkey,intcount,Stringvalue){Jedisjo=null;try{jo=getJedis();returnjo.lrem(key,count,value);}catch(Exceptione){threadLocalJedis.set(null);e.printStackTrace();_logger.error("redis服务器异常",e);thrownewRuntimeException("redis操作错误");}finally{if(jo!=null){close(jo);}}}//获取所有listpublicstaticListgetListAll(Stringkey){Jedisjo=null;Listlist=null;try{jo=getJedis();list=jo.lrange(key,0,-1);}catch(Exceptione){threadLocalJedis.set(null);e.printStackTrace();_logger.error("redis服务器异常",e);thrownewRuntimeException("redis操作错误");}finally{if(jo!=null){close(jo);}}returnlist;}//清理缓存redispublicstaticvoidcleanLoacl(Jedisjo){threadLocalJedis.set(null);close(jo);}static{initialPool();}}

使用webuploader组件实现大文件分片上传&#xff0c;断点续传

webuploader&#xff1a;是一个以HTML5为主&#xff0c; Flash为辅的文件上传组件&#xff0c;采用大文件分片/并发上传的方式&#xff0c;极大地提高了文件上传的效率&#xff0c;同时兼容多种浏览器版本&#xff1b;

前端

引入百度Webuploader组件&#xff0c;需要注意标签的id/nama属性&#xff0c;这些将在后面的JavaScript中使用到进行文件切分、验证。

以上js组件&#xff0c;将完成文件上传、MD5验证、删除、切片、上传进度条显示、暂停、继续上传及上传成功/失败时候的回调。

后端

前端&#xff0c;给后端提供封装的chunk,及request

后端&#xff0c;主要是判断文件是否有分片&#xff0c;如果没有&#xff0c;则直接存放到目的目录&#xff1b;

如果存在分片&#xff0c;则创建临时目录&#xff0c;存放分片信息&#xff1b;

之后判断当前分片所属的文件的所有分片是否已经传输完毕&#xff0c;如果当前分片数==所属文件总分片数&#xff0c;则开始合并文件并转移完整文件到目的目录&#xff0c;并且删除临时目录

检测完文件&#xff0c;以后&#xff0c;开始上传操作

//上传操作path=appendFileStorageClient.uploadAppenderFile(UpLoadConstant.DEFAULT_GROUP,file.getInputStream(),file.getSize(),FileUtil.extName((String)paramMap.get("name")));//更新操作appendFileStorageClient.modifyFile(UpLoadConstant.DEFAULT_GROUP,noGroupPath,file.getInputStream(),file.getSize(),historyUpload);

hutool工具的巧妙运用

可参考hutool资料http://www.mianshigee.com/tutorial/hutool/26e24c7a37d93249.md

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.0.6</version></dependency>

cn.hutool.core.collection.CollUtil判断非空

cn.hutool.json.JSONObject与JSONUtil

if(CollUtil.isNotEmpty(fileList)){for(Stringe:fileList){JSONObjectjsonObject=JSONUtil.parseObj(e);jsonObjects.add(jsonObject);}}

cn.hutool.core.convert.Convert类型转换

cn.hutool.core.util.RandomUtil生成随机字符串及StrUtil判断字符为空

解析文件的扩展名&#xff0c;来获该文件的类型

importcn.hutool.core.io.FileUtil;FileUtil.extName((String)paramMap.get("name")));

到此,关于“如何搭建fastdfs服务及单机redis服务”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注恰卡编程网网站,小编会继续努力为大家带来更多实用的文章!

发布于 2022-03-29 22:28:51
收藏
分享
海报
0 条评论
25
上一篇:Redis分布式锁实例分析 下一篇:SpringBoot整合redis报错怎么办
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码