千家信息网

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

发表于:2024-11-29 作者:千家信息网编辑
千家信息网最后更新 2024年11月29日,这篇文章主要介绍"如何搭建fastdfs服务及单机redis服务",在日常操作中,相信很多人在如何搭建fastdfs服务及单机redis服务问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法
千家信息网最后更新 2024年11月29日如何搭建fastdfs服务及单机redis服务

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

先要安装gcc编译器:

yum -y install gcc-c++

安装lib依赖包

tar -zxvf V1.0.43.tar.gzcd libfastcommon-1.0.43./make.sh./make.sh install

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 -zxvf V6.06.tar.gzcd fastdfs-6.06./make.sh./make.sh install

配置Tracker服务

mkdir -p /data/fastdfs/trackercd /etc/fdfscp tracker.conf.sample  tracker.confvim tracker.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.conf start

查看是否启动

#查看启动端口ss -ant | grep 22122

查看启动日志

#查看启动日志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/fdfscp storage.conf.sample  storage.confvim storage.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.conf start

查看启动端口

#查看启动端口ss -ant | grep 23000

查看启动日志

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

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

[root@localhost /]# /usr/bin/fdfs_monitor /etc/fdfs/storage.conf[2021-09-23 12: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_key length=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s, use_storage_id=0, storage server id count: 0server_count=1, server_index=0tracker server is 172.16.8.11:22122group count: 1Group 1:group name = group1disk total space = 6818 MBdisk free space = 2169 MBtrunk free space = 0 MB……

加入开机启动

vim /etc/rc.d/rc.local

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

/usr/bin/fdfs_storaged /etc/fdfs/storage.conf start

测试验证

[root@localhost ~]# ps -ef|grep fdfsroot     10335 17685  0 23:50 pts/3    00:00:00 grep --color=auto fdfsroot     13335     1  0 13:17 ?        00:00:07 /usr/bin/fdfs_storaged /etc/fdfs/storage.conf startroot     15779     1  0 12: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

1.获取redis资源,并解压

tar xzvf redis-4.0.8.tar.gz

2.安装

cd redis-4.0.8makecd srcmake install PREFIX=/usr/local/redis

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

cd ../mkdir /usr/local/redis/etcmv redis.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密码(可选操作,可以没有)

运行命令:

config get requirepass

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

c.设置redis密码

运行命令:

config set requirepass  *******

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

d.测试连接

重启redis服务

//****为你设置的密码redis-cli -h 127.0.0.1 -p 6379 -a ****

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

9.让外网能够访问redis

a.配置防火墙:

#开放6379端口 firewall-cmd --zone=public --add-port=6379/tcp --permanent#重启防火墙以使配置即时生效systemctl restart firewalld#查看系统所有开放的端口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:

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

报异常,尝试重启

原因: Redis已经启动

解决: 关掉Redis,重启即可

redis-cli shutdown redis-server &

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

客户端检测连接是否正常

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

$redis-cli 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> set key "hello world" OK 127.0.0.1:6379> get key "hello world"

Redis客户端常见操作

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

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

> set server:name "fido"  // 设置键值OK> get server:name  // 获取键值"fido"> setnx connections 10   // set if not existsOK> incr connections   // 原子性增加values值(integer) 11> incr connections(integer) 12> del connections  // 删除key(integer) 1> incr connections(integer) 1

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

> rpush friends "Alice"   // 在末尾追加(integer) 1> rpush friends "Bob"(integer) 2> lpush friends "Sam"    // 插入到开头(integer) 3 > lrange friends 0 -1     // 返回列表的子集,类似切片操作1) "Sam"2) "Alice"3) "Bob"> lrange friends 0 11) "Sam"2) "Alice"> lrange friends 1 21) "Alice"2) "Bob" > llen friends   // 返回列表长度(integer) 3> lpop friends   // 删除并返回列表第一个元素"Sam"> rpop friends   // 删除并返回列表最后一个元素"Bob"> lrange friends 0 -11) "Alice" > del friends    // 删除key(integer) 1     // 1表示成功,0表示失败

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

> sadd superpowers "flight"     // 添加元素(integer) 1> sadd superpowers "x-ray vision"(integer) 1> sadd superpowers "reflexes"(integer) 1> srem superpowers "reflexes"   // 删除元素1 > sismember superpowers "flight"   // 测试元素是否在集合中(integer) 1> sismember superpowers "reflexes"(integer) 0> smembers superpowers    // 返回集合中所有元素1) "x-ray vision"2) "flight" > sadd birdpowers "pecking"(integer) 1> sadd birdpowers "flight"(integer) 1> sunion superpowers birdpowers    // 合并多个set,返回合并后的元素列表1) "x-ray vision"2) "flight"3) "pecking" > del superpowers   // 删除key(integer) 1

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

> zadd hacker 1940 "Alan Kay"     // 给value指定一个编号,比如以年份1940作为编号(integer) 1> zadd hacker 1906 "Grace Hopper"(integer) 1> zadd hacker 1953 "Richard Stallman"(integer) 1> zadd hacker 1965 "Yukihiro Matsumoto"(integer) 1> zadd hacker 1916 "Claude Shannon"(integer) 1> zadd hacker 1969 "Linux Torvalds"(integer) 1> zadd hacker 1957 "Sophie Wilson"(integer) 1> zadd hacker 1912 "Alan Turing"(integer) 1 > zrange hacker 2 4    // 切片返回有序集合中元素1) "Claude Shannon"2) "Alan Kay"3) "Richard Stallman" > del hacker    // 删除key(integer) 1

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

> hset user:1000 name "John Smith"   // 给value指定一个field,比如name(integer) 1> hset user:1000 email "john.smith@example.com"(integer) 1> hset user:1000 password "s3cret"(integer) 1> hgetall user:1000   // 获得hash表中所有成员,包括field和value1) "name"2) "John Smith"3) "email"4) "john.smith@example.com"5) "password"6) "s3cret" > hmset user:1001 name "Mary Jones" password "hidden" email"mjones@example.com"   // 设置多个field和valueOK> hget user:1001 name   // 根据field获取value"Mary Jones"  > hset user:1000 visits 10    // field可以映射到数字值(integer) 1> hincrby user:1000 visits 1    // 原子性增加value的值,增加1(integer) 11> hincrby user:1000 visits 10    // 增加10(integer) 21> hdel user:1000 visits      // 删除field及其value(integer) 1> hincrby user:1000 visits 1(integer) 1 > del user:1000     // 删除key(integer) 1

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

> set resource:lock "Redis Demo"OK> expire resource:lock 120   // 设置生命周期为120s(integer) 1> ttl resource:lock   // 查看当前生命周期还剩多少时间(integer) 109> ttl resource:lock   // 120s后查看,返回-2表示已过期或不存在(integer) -2 > set resource:lock "Redis Demo 2"OK> ttl resource:lock    // 返回-1表示永不过期(integer) -1

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

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

改回upload_list

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

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

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

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

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

import cn.hutool.core.util.StrUtil;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;import java.util.List;public class RedisUtil {    private RedisUtil() {    }    private static Logger _logger = LoggerFactory.getLogger(RedisUtil.class);    ;    protected static final  ThreadLocal threadLocalJedis = new ThreadLocal();    //Redis服务器IP    private static String ADDR_ARRAY = ReadProper.getResourceValue("spring.redis.host");    //Redis的端口号    private static int PORT = Integer.parseInt(ReadProper.getResourceValue("spring.redis.port"));    //访问密码    private static String AUTH = ReadProper.getResourceValue("spring.redis.password");    //可用连接实例的最大数目,默认值为8;    //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。    private static int MAX_ACTIVE = -1;    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。    private static int MAX_IDLE = 16;    //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;    private static int MAX_WAIT = 1000 * 5;    //超时时间    private static int TIMEOUT = 1000 * 5;    //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;    private static boolean TEST_ON_BORROW = true;    private static JedisPool jedisPool ;    //默认的数据库为0    /**     * redis过期时间,以秒为单位     */    public final static int EXRP_HOUR = 60 * 60;          //一小时    public final static int EXRP_DAY = 60 * 60 * 24;        //一天    public final static int EXRP_MONTH = 60 * 60 * 24 * 30;   //一个月    /**     * 初始化Redis连接池,注意一定要在使用前初始化一次,一般在项目启动时初始化就行了     */    public static JedisPool  initialPool() {        JedisPool jp=null;        try {            JedisPoolConfig config = new JedisPoolConfig();            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 = new JedisPool(config, ADDR_ARRAY, PORT, TIMEOUT, AUTH);            jedisPool=jp;            threadLocalJedis.set(getJedis());        } catch (Exception e) {            e.printStackTrace();            _logger.error("redis服务器异常",e);        }        return  jp;    }    public static void close(Jedis jedis) {        if (threadLocalJedis.get() == null && jedis != null){            jedis.close();        }    }//    /**//     * 在多线程环境同步初始化//     *///    private static synchronized void poolInit() {//        if (jedisPool == null) {//            initialPool();//        }//    }    /**     * 获取Jedis实例,一定先初始化     *     * @return Jedis     */    public static Jedis getJedis() {        boolean success = false;        Jedis jedis = null;//        if (jedisPool == null) {//            poolInit();//        }        int i=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");                        return jedis;                    }                }else {                    throw new RuntimeException("redis连接池初始化失败");                }            } catch (Exception e) {               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 (InterruptedException e) {                    e.printStackTrace();                }            }            if (i>=20&&i<30){                try {                    Thread.sleep(2000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            if (i>=30&&i<40){                try {                    Thread.sleep(3000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            if (i>=40){                System.out.println("redis彻底连不上了~~~~(>_<)~~~~");                return null;            }        }        if (threadLocalJedis.get()==null){threadLocalJedis.set(jedis);}        //System.out.println(Thread.currentThread().getName()+":第"+i+"次获取成功@");        return jedis;    }    /**     * 设置 String     *     * @param key     * @param value     */    public static void setString(String key, String value) {        Jedis jo = null;        try {            value = StrUtil.isBlank(value) ? "" : value;            jo = getJedis();            jo.set(key, value);        } catch (Exception e) {            threadLocalJedis.set(null);            _logger.error("redis服务器异常",e);            throw new  RuntimeException("redis服务器异常");        } finally {            if (jo != null) {                close(jo);            }        }    }    /**     * 设置 过期时间     *     * @param key     * @param seconds 以秒为单位     * @param value     */    public static void setString(String key, int seconds, String value) {        Jedis jo = null;        try {            value = StrUtil.isBlank(value) ? "" : value;            jo = getJedis();            jo.setex(key, seconds, value);        } catch (Exception e) {            threadLocalJedis.set(null);            e.printStackTrace();            _logger.error("redis服务器异常",e);            throw new  RuntimeException("redis服务器异常");        } finally {            if (jo != null) {                close(jo);            }        }    }    /**     * 获取String值     *     * @param key     * @return value     */    public static String getString(String key) {        Jedis jo = null;        try {            jo = getJedis();            if (jo == null || !jo.exists(key)) {                return null;            }            return jo.get(key);        } catch (Exception e) {            threadLocalJedis.set(null);            e.printStackTrace();            _logger.error("redis服务器异常",e);            throw new  RuntimeException("redis操作错误");        } finally {            if (jo != null) {                close(jo);            }        }    }    public static long incrBy(String key, long integer) {        Jedis jo = null;        try {            jo = getJedis();            return jo.incrBy(key, integer);        } catch (Exception e) {            threadLocalJedis.set(null);            e.printStackTrace();            _logger.error("redis服务器异常",e);            throw new  RuntimeException("redis操作错误");        } finally {            if (jo != null) {                close(jo);            }        }    }    public static long decrBy(String key, long integer) {        Jedis jo = null;        try {            jo = getJedis();            return jo.decrBy(key, integer);        } catch (Exception e) {            threadLocalJedis.set(null);            e.printStackTrace();            _logger.error("redis服务器异常",e);            throw new  RuntimeException("redis操作错误");        } finally {            if (jo != null) {                close(jo);            }        }    }    //删除多个key    public static  long  delKeys(String [] keys){        Jedis jo = null;        try {            jo = getJedis();            return jo.del(keys);        } catch (Exception e) {            threadLocalJedis.set(null);            e.printStackTrace();            _logger.error("redis服务器异常",e);            throw new  RuntimeException("redis操作错误");        } finally {            if (jo != null) {                close(jo);            }        }    }    //删除单个key    public static  long  delKey(String  key){        Jedis jo = null;        try {            jo = getJedis();            return jo.del(key);        } catch (Exception e) {            threadLocalJedis.set(null);            e.printStackTrace();            _logger.error("redis服务器异常",e);            throw new  RuntimeException("redis操作错误");        } finally {            if (jo != null) {                close(jo);            }        }    }    //添加到队列尾    public static  long  rpush(String  key,String node){        Jedis jo = null;        try {            jo = getJedis();            return jo.rpush(key,node);        } catch (Exception e) {            threadLocalJedis.set(null);            e.printStackTrace();            _logger.error("redis服务器异常",e);            throw new  RuntimeException("redis操作错误");        } finally {            if (jo != null) {                close(jo);            }        }    }    //删除list元素    public static  long  delListNode(String  key,int count,String value){        Jedis jo = null;        try {            jo = getJedis();            return jo.lrem(key,count,value);        } catch (Exception e) {            threadLocalJedis.set(null);            e.printStackTrace();            _logger.error("redis服务器异常",e);            throw new  RuntimeException("redis操作错误");        } finally {            if (jo != null) {                close(jo);            }        }    }    //获取所有list    public static List getListAll(String key){        Jedis jo = null;        List list=null;        try {            jo = getJedis();            list=    jo.lrange(key,0,-1);        } catch (Exception e) {            threadLocalJedis.set(null);            e.printStackTrace();            _logger.error("redis服务器异常",e);            throw new  RuntimeException("redis操作错误");        } finally {            if (jo != null) {                close(jo);            }        }        return  list;    }    //清理缓存redis    public  static  void cleanLoacl(Jedis jo){        threadLocalJedis.set(null);        close(jo);    }static {  initialPool();}}

使用webuploader组件实现大文件分片上传,断点续传

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

前端

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

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

后端

前端,给后端提供封装的chunk,及request

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

如果存在分片,则创建临时目录,存放分片信息;

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

检测完文件,以后,开始上传操作

//上传操作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

    cn.hutool    hutool-all    5.0.6

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

cn.hutool.json.JSONObject与JSONUtil

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

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

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

解析文件的扩展名,来获该文件的类型

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

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

0