• redis cluster 集群 安装 配置 详解


    redis cluster 集群 安装 配置 详解

    张映 发表于 2015-05-01

    分类目录: nosql

    标签:, , , ,

    Redis 集群是一个提供在多个Redis间节点间共享数据的程序集.redis3.0以前,只支持主从同步的,如果主的挂了,写入就成问题了。3.0出来后就可以很好帮我们解决这个问题。

    目前redis 3.0还不稳定,如果要用在生产环境中,要慎重。

    一,redis服务器说明

    1. 192.168.10.219 6379 
    2. 192.168.10.219 6380 
    3. 192.168.10.219 6381 
    4.  
    5. 192.168.10.220 6382 
    6. 192.168.10.220 6383 
    7. 192.168.10.220 6384 
    192.168.10.219 6379
    192.168.10.219 6380
    192.168.10.219 6381
    
    192.168.10.220 6382
    192.168.10.220 6383
    192.168.10.220 6384

    要让集群正常运作至少需要三个主节点,不过在刚开始试用集群功能时, 强烈建议使用六个节点: 其中三个为主节点, 而其余三个则是各个主节点的从节点。所有用二台机器,开6个redis进程,模拟6台机器。

    二,安装ruby,rubygems

    1. # yum -y install gcc openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel gcc-c++ automake autoconf 
    2.  
    3. # yum -y install ruby rubygems   //安装ruby rubygems 
    4.  
    5. //换源 
    6. # gem source -l 
    7. # gem source --remove http://rubygems.org/ 
    8. # gem sources -a http://ruby.taobao.org/ 
    9. # gem source -l 
    10.  
    11. # gem install redis --version 3.0.0  //安装gem_redis 
    12. Successfully installed redis-3.0.0 
    13. 1 gem installed 
    14. Installing ri documentation for redis-3.0.0... 
    15. Installing RDoc documentation for redis-3.0.0... 
    # yum -y install gcc openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel gcc-c++ automake autoconf
    
    # yum -y install ruby rubygems   //安装ruby rubygems
    
    //换源
    # gem source -l
    # gem source --remove http://rubygems.org/
    # gem sources -a http://ruby.taobao.org/
    # gem source -l
    
    # gem install redis --version 3.0.0  //安装gem_redis
    Successfully installed redis-3.0.0
    1 gem installed
    Installing ri documentation for redis-3.0.0...
    Installing RDoc documentation for redis-3.0.0...

    以前写过一篇ruby on rails的文章,请参考:centos ruby on rails apache mysql 安装配置详解

    喜欢手动编译的人,可以参考这篇文章,安装ruby.

    三,安装redis3.0.0

    1,安装redis

    1. # wget http://download.redis.io/releases/redis-3.0.0.tar.gz 
    2. # tar -xvzf redis-3.0.0.tar.gz 
    3. # cd redis-3.0.0 
    4. # make && make install 
    5. # cd src 
    6. # cp redis-trib.rb /usr/local/bin   
    7.  
    8. # mkdir /etc/redis 
    9. # mkdir /var/log/redis 
    # wget http://download.redis.io/releases/redis-3.0.0.tar.gz
    # tar -xvzf redis-3.0.0.tar.gz
    # cd redis-3.0.0
    # make && make install
    # cd src
    # cp redis-trib.rb /usr/local/bin  
    
    # mkdir /etc/redis
    # mkdir /var/log/redis

    上述操作要先在二台机器上面都操作好。

    2,配置redis

    1. [root@slave2 redis-3.0.0]#  vim redis.conf   //解压的根目录,有redis.conf,做以下修改 
    2. port 6379 
    3. pidfile /var/run/redis-6379.pid 
    4. dbfilename dump-6379.rdb 
    5. appendfilename "appendonly-6379.aof" 
    6. cluster-config-file nodes-6379.conf 
    7. cluster-enabled yes 
    8. cluster-node-timeout 5000 
    9. appendonly yes 
    [root@slave2 redis-3.0.0]#  vim redis.conf   //解压的根目录,有redis.conf,做以下修改
    port 6379
    pidfile /var/run/redis-6379.pid
    dbfilename dump-6379.rdb
    appendfilename "appendonly-6379.aof"
    cluster-config-file nodes-6379.conf
    cluster-enabled yes
    cluster-node-timeout 5000
    appendonly yes

    3,copy配置文件,并修改端口

    1. # cp redis.conf /etc/redis/redis-6379.conf 
    2. # cp redis.conf /etc/redis/redis-6380.conf 
    3. # cp redis.conf /etc/redis/redis-6381.conf 
    4.  
    5. # scp redis.conf 192.168.10.220:/etc/redis/redis-6382.conf 
    6. # scp redis.conf 192.168.10.220:/etc/redis/redis-6383.conf 
    7. # scp redis.conf 192.168.10.220:/etc/redis/redis-6384.conf 
    8.  
    9. # sed -i "s/6379/6380/g" /etc/redis/redis-6380.conf 
    10. # sed -i "s/6379/6381/g" /etc/redis/redis-6381.conf 
    11.  
    12. # sed -i "s/6379/6382/g" /etc/redis/redis-6382.conf 
    13. # sed -i "s/6379/6383/g" /etc/redis/redis-6383.conf 
    14. # sed -i "s/6379/6384/g" /etc/redis/redis-6384.conf 
    # cp redis.conf /etc/redis/redis-6379.conf
    # cp redis.conf /etc/redis/redis-6380.conf
    # cp redis.conf /etc/redis/redis-6381.conf
    
    # scp redis.conf 192.168.10.220:/etc/redis/redis-6382.conf
    # scp redis.conf 192.168.10.220:/etc/redis/redis-6383.conf
    # scp redis.conf 192.168.10.220:/etc/redis/redis-6384.conf
    
    # sed -i "s/6379/6380/g" /etc/redis/redis-6380.conf
    # sed -i "s/6379/6381/g" /etc/redis/redis-6381.conf
    
    # sed -i "s/6379/6382/g" /etc/redis/redis-6382.conf
    # sed -i "s/6379/6383/g" /etc/redis/redis-6383.conf
    # sed -i "s/6379/6384/g" /etc/redis/redis-6384.conf

    将配置文件分别copy到二台机器上,并替换端口:

    1. # cat redis-6380.conf |awk '{if($0 !~ /^$/ && $0 !~ /#/) {print $0}}' |grep 6380 
    2. pidfile /var/run/redis-6380.pid 
    3. port 6380 
    4. dbfilename dump-6380.rdb 
    5. appendfilename "appendonly-6380.aof" 
    6. cluster-config-file nodes-6380.conf 
    # cat redis-6380.conf |awk '{if($0 !~ /^$/ && $0 !~ /#/) {print $0}}' |grep 6380
    pidfile /var/run/redis-6380.pid
    port 6380
    dbfilename dump-6380.rdb
    appendfilename "appendonly-6380.aof"
    cluster-config-file nodes-6380.conf

    有5处修改端口的地方

    4,启动并查看redis

    1. # redis-server /etc/redis/redis-6379.conf > /var/log/redis/redis-6379.log 2>&1 & 
    2. # redis-server /etc/redis/redis-6380.conf > /var/log/redis/redis-6380.log 2>&1 & 
    3. # redis-server /etc/redis/redis-6381.conf > /var/log/redis/redis-6381.log 2>&1 & 
    4.  
    5. # redis-server /etc/redis/redis-6382.conf > /var/log/redis/redis-6382.log 2>&1 & 
    6. # redis-server /etc/redis/redis-6383.conf > /var/log/redis/redis-6383.log 2>&1 & 
    7. # redis-server /etc/redis/redis-6384.conf > /var/log/redis/redis-6384.log 2>&1 & 
    8.  
    9. # netstat -tpnl |grep redis 
    10. tcp        0      0 0.0.0.0:6379                0.0.0.0:*                   LISTEN      7298/redis-server * 
    11. tcp        0      0 0.0.0.0:6380                0.0.0.0:*                   LISTEN      7299/redis-server * 
    12. tcp        0      0 0.0.0.0:6381                0.0.0.0:*                   LISTEN      7304/redis-server * 
    13. tcp        0      0 0.0.0.0:16379               0.0.0.0:*                   LISTEN      7298/redis-server * 
    14. tcp        0      0 0.0.0.0:16380               0.0.0.0:*                   LISTEN      7299/redis-server * 
    15. tcp        0      0 0.0.0.0:16381               0.0.0.0:*                   LISTEN      7304/redis-server * 
    16. tcp        0      0 :::6379                     :::*                        LISTEN      7298/redis-server * 
    17. tcp        0      0 :::6380                     :::*                        LISTEN      7299/redis-server * 
    18. tcp        0      0 :::6381                     :::*                        LISTEN      7304/redis-server * 
    19. tcp        0      0 :::16379                    :::*                        LISTEN      7298/redis-server * 
    20. tcp        0      0 :::16380                    :::*                        LISTEN      7299/redis-server * 
    21. tcp        0      0 :::16381                    :::*                        LISTEN      7304/redis-server * 
    22.  
    23. [root@slave2 redis]# ll /etc/redis/ 
    24. 总用量 156 
    25. -rw-r--r-- 1 root root     0 4月  30 23:54 appendonly-6379.aof 
    26. -rw-r--r-- 1 root root     0 5月   1 00:08 appendonly-6380.aof 
    27. -rw-r--r-- 1 root root     0 5月   1 00:08 appendonly-6381.aof 
    28. -rw-r--r-- 1 root root    18 5月   1 00:08 dump-6379.rdb 
    29. -rw-r--r-- 1 root root    18 5月   1 00:08 dump-6380.rdb 
    30. -rw-r--r-- 1 root root    18 5月   1 00:08 dump-6381.rdb 
    31. -rw-r--r-- 1 root root   763 5月   1 00:08 nodes-6379.conf 
    32. -rw-r--r-- 1 root root   763 5月   1 00:08 nodes-6380.conf 
    33. -rw-r--r-- 1 root root   763 5月   1 00:08 nodes-6381.conf 
    34. -rw-r--r-- 1 root root 41412 4月  30 23:30 redis-6379.conf 
    35. -rw-r--r-- 1 root root 41412 4月  30 23:39 redis-6380.conf 
    36. -rw-r--r-- 1 root root 41412 4月  30 23:39 redis-6381.conf 
    # redis-server /etc/redis/redis-6379.conf > /var/log/redis/redis-6379.log 2>&1 &
    # redis-server /etc/redis/redis-6380.conf > /var/log/redis/redis-6380.log 2>&1 &
    # redis-server /etc/redis/redis-6381.conf > /var/log/redis/redis-6381.log 2>&1 &
    
    # redis-server /etc/redis/redis-6382.conf > /var/log/redis/redis-6382.log 2>&1 &
    # redis-server /etc/redis/redis-6383.conf > /var/log/redis/redis-6383.log 2>&1 &
    # redis-server /etc/redis/redis-6384.conf > /var/log/redis/redis-6384.log 2>&1 &
    
    # netstat -tpnl |grep redis
    tcp        0      0 0.0.0.0:6379                0.0.0.0:*                   LISTEN      7298/redis-server *
    tcp        0      0 0.0.0.0:6380                0.0.0.0:*                   LISTEN      7299/redis-server *
    tcp        0      0 0.0.0.0:6381                0.0.0.0:*                   LISTEN      7304/redis-server *
    tcp        0      0 0.0.0.0:16379               0.0.0.0:*                   LISTEN      7298/redis-server *
    tcp        0      0 0.0.0.0:16380               0.0.0.0:*                   LISTEN      7299/redis-server *
    tcp        0      0 0.0.0.0:16381               0.0.0.0:*                   LISTEN      7304/redis-server *
    tcp        0      0 :::6379                     :::*                        LISTEN      7298/redis-server *
    tcp        0      0 :::6380                     :::*                        LISTEN      7299/redis-server *
    tcp        0      0 :::6381                     :::*                        LISTEN      7304/redis-server *
    tcp        0      0 :::16379                    :::*                        LISTEN      7298/redis-server *
    tcp        0      0 :::16380                    :::*                        LISTEN      7299/redis-server *
    tcp        0      0 :::16381                    :::*                        LISTEN      7304/redis-server *
    
    [root@slave2 redis]# ll /etc/redis/
    总用量 156
    -rw-r--r-- 1 root root     0 4月  30 23:54 appendonly-6379.aof
    -rw-r--r-- 1 root root     0 5月   1 00:08 appendonly-6380.aof
    -rw-r--r-- 1 root root     0 5月   1 00:08 appendonly-6381.aof
    -rw-r--r-- 1 root root    18 5月   1 00:08 dump-6379.rdb
    -rw-r--r-- 1 root root    18 5月   1 00:08 dump-6380.rdb
    -rw-r--r-- 1 root root    18 5月   1 00:08 dump-6381.rdb
    -rw-r--r-- 1 root root   763 5月   1 00:08 nodes-6379.conf
    -rw-r--r-- 1 root root   763 5月   1 00:08 nodes-6380.conf
    -rw-r--r-- 1 root root   763 5月   1 00:08 nodes-6381.conf
    -rw-r--r-- 1 root root 41412 4月  30 23:30 redis-6379.conf
    -rw-r--r-- 1 root root 41412 4月  30 23:39 redis-6380.conf
    -rw-r--r-- 1 root root 41412 4月  30 23:39 redis-6381.conf

    所有节点都启动成功,并不代表,他们就是集群了。

    四,创建集群,并查看

    1,创建redis集群

    1. # redis-trib.rb create --replicas 1 192.168.10.219:6379 192.168.10.219:6380 192.168.10.219:6381 192.168.10.220:6382 192.168.10.220:6383 192.168.10.220:6384 
    # redis-trib.rb create --replicas 1 192.168.10.219:6379 192.168.10.219:6380 192.168.10.219:6381 192.168.10.220:6382 192.168.10.220:6383 192.168.10.220:6384

    2,查看redis集群状态

    1. [root@slave2 redis]# redis-trib.rb check 192.168.10.219:6379 
    2. Connecting to node 192.168.10.219:6379: OK 
    3. Connecting to node 192.168.10.220:6384: OK 
    4. Connecting to node 192.168.10.219:6381: OK 
    5. Connecting to node 192.168.10.220:6383: OK 
    6. Connecting to node 192.168.10.220:6382: OK 
    7. Connecting to node 192.168.10.219:6380: OK 
    8. >>> Performing Cluster Check (using node 192.168.10.219:6379) 
    9. M: d40d9a367c24784b0336c7b80fb4c87337e2cba6 192.168.10.219:6379 
    10. slots:5461-10922 (5462 slots) master 
    11. 1 additional replica(s) 
    12. S: 5f00f163d0c0a540ea99daf004f55588a802327b 192.168.10.220:6384 
    13. slots: (0 slots) slave 
    14. replicates d40d9a367c24784b0336c7b80fb4c87337e2cba6 
    15. S: b3b1a848987b5a87a06888e126d5c9b16f871ff5 192.168.10.219:6381 
    16. slots: (0 slots) slave 
    17. replicates d2eb5a8a77f87888792428aed4692dfb907e7a1d 
    18. M: d2eb5a8a77f87888792428aed4692dfb907e7a1d 192.168.10.220:6383 
    19. slots:10923-16383 (5461 slots) master 
    20. 1 additional replica(s) 
    21. M: a8eafe8b19d6a28c034917da13a43ce1230fe870 192.168.10.220:6382 
    22. slots:0-5460 (5461 slots) master 
    23. 1 additional replica(s) 
    24. S: a87d207204a53ab599bf7f6ffb9d679d0eef4f25 192.168.10.219:6380 
    25. slots: (0 slots) slave 
    26. replicates a8eafe8b19d6a28c034917da13a43ce1230fe870 
    27. [OK] All nodes agree about slots configuration. 
    28. >>> Check for open slots... 
    29. >>> Check slots coverage... 
    30. [OK] All 16384 slots covered. 
    [root@slave2 redis]# redis-trib.rb check 192.168.10.219:6379
    Connecting to node 192.168.10.219:6379: OK
    Connecting to node 192.168.10.220:6384: OK
    Connecting to node 192.168.10.219:6381: OK
    Connecting to node 192.168.10.220:6383: OK
    Connecting to node 192.168.10.220:6382: OK
    Connecting to node 192.168.10.219:6380: OK
    >>> Performing Cluster Check (using node 192.168.10.219:6379)
    M: d40d9a367c24784b0336c7b80fb4c87337e2cba6 192.168.10.219:6379
     slots:5461-10922 (5462 slots) master
     1 additional replica(s)
    S: 5f00f163d0c0a540ea99daf004f55588a802327b 192.168.10.220:6384
     slots: (0 slots) slave
     replicates d40d9a367c24784b0336c7b80fb4c87337e2cba6
    S: b3b1a848987b5a87a06888e126d5c9b16f871ff5 192.168.10.219:6381
     slots: (0 slots) slave
     replicates d2eb5a8a77f87888792428aed4692dfb907e7a1d
    M: d2eb5a8a77f87888792428aed4692dfb907e7a1d 192.168.10.220:6383
     slots:10923-16383 (5461 slots) master
     1 additional replica(s)
    M: a8eafe8b19d6a28c034917da13a43ce1230fe870 192.168.10.220:6382
     slots:0-5460 (5461 slots) master
     1 additional replica(s)
    S: a87d207204a53ab599bf7f6ffb9d679d0eef4f25 192.168.10.219:6380
     slots: (0 slots) slave
     replicates a8eafe8b19d6a28c034917da13a43ce1230fe870
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.

    到这儿,redis集群就配置成功了

    五,测试redis集群

    1. # redis-cli -c -p 6379 -h 192.168.10.219   //在219登录 
    2. 192.168.10.219:6379> set tank tank1    //设置测试值 
    3. -> Redirected to slot [4407] located at 192.168.10.220:6382 
    4. OK   //直接转向到220 6382端口,数据存到了220 6382,不过有点奇怪 
    5. 192.168.10.220:6382> get tank   //可以取到值 
    6. "tank1" 
    7.  
    8. [root@manage redis]# redis-cli -c -p 6383 -h 192.168.10.220  //220机器,6383端口 
    9. 192.168.10.220:6383> get tank 
    10. -> Redirected to slot [4407] located at 192.168.10.220:6382  //直接转向220 6382端口 
    11. "tank1" 
    12.  
    13. [root@manage redis]# ps aux |grep redis //查看进程 
    14. root      7310  0.2  0.9 137436  9724 pts/0    Sl   Apr30   0:09 redis-server *:6382 [cluster] 
    15. root      7311  0.2  0.9 137436  9776 pts/0    Sl   Apr30   0:09 redis-server *:6383 [cluster] 
    16. root      7316  0.2  0.9 137436  9944 pts/0    Sl   Apr30   0:10 redis-server *:6384 [cluster] 
    17. root      7478  0.0  0.0 103256   812 pts/0    S+   00:56   0:00 grep redis 
    18.  
    19. [root@manage redis]# kill -9 7310  //关闭220 6382端口,看数据会不会丢失 
    20.  
    21. [root@slave2 redis]# redis-trib.rb check 192.168.10.219:6379  //查看集群情况,任何接口都行 
    22. Connecting to node 192.168.10.219:6379: OK 
    23. Connecting to node 192.168.10.220:6384: OK 
    24. Connecting to node 192.168.10.219:6381: OK 
    25. Connecting to node 192.168.10.220:6383: OK 
    26. Connecting to node 192.168.10.219:6380: OK 
    27. >>> Performing Cluster Check (using node 192.168.10.219:6379) 
    28. M: d40d9a367c24784b0336c7b80fb4c87337e2cba6 192.168.10.219:6379 
    29. slots:5461-10922 (5462 slots) master 
    30. 1 additional replica(s) 
    31. S: 5f00f163d0c0a540ea99daf004f55588a802327b 192.168.10.220:6384 
    32. slots: (0 slots) slave 
    33. replicates d40d9a367c24784b0336c7b80fb4c87337e2cba6 
    34. S: b3b1a848987b5a87a06888e126d5c9b16f871ff5 192.168.10.219:6381 
    35. slots: (0 slots) slave 
    36. replicates d2eb5a8a77f87888792428aed4692dfb907e7a1d 
    37. M: d2eb5a8a77f87888792428aed4692dfb907e7a1d 192.168.10.220:6383 
    38. slots:10923-16383 (5461 slots) master 
    39. 1 additional replica(s) 
    40. M: a87d207204a53ab599bf7f6ffb9d679d0eef4f25 192.168.10.219:6380 
    41. slots:0-5460 (5461 slots) master 
    42. 0 additional replica(s) 
    43. [OK] All nodes agree about slots configuration. 
    44. >>> Check for open slots... 
    45. >>> Check slots coverage... 
    46. [OK] All 16384 slots covered.  //变成,三主二从了 
    47.  
    48. [root@slave2 redis]# redis-cli -c -p 6379 -h 192.168.10.219    //219登录 
    49. 192.168.10.219:6379> get tank 
    50. -> Redirected to slot [4407] located at 192.168.10.219:6380   //数据被转到了6380节点了 
    51. "tank1" 
    # redis-cli -c -p 6379 -h 192.168.10.219   //在219登录
    192.168.10.219:6379> set tank tank1    //设置测试值
    -> Redirected to slot [4407] located at 192.168.10.220:6382
    OK   //直接转向到220 6382端口,数据存到了220 6382,不过有点奇怪
    192.168.10.220:6382> get tank   //可以取到值
    "tank1"
    
    [root@manage redis]# redis-cli -c -p 6383 -h 192.168.10.220  //220机器,6383端口
    192.168.10.220:6383> get tank
    -> Redirected to slot [4407] located at 192.168.10.220:6382  //直接转向220 6382端口
    "tank1"
    
    [root@manage redis]# ps aux |grep redis //查看进程
    root      7310  0.2  0.9 137436  9724 pts/0    Sl   Apr30   0:09 redis-server *:6382 [cluster]
    root      7311  0.2  0.9 137436  9776 pts/0    Sl   Apr30   0:09 redis-server *:6383 [cluster]
    root      7316  0.2  0.9 137436  9944 pts/0    Sl   Apr30   0:10 redis-server *:6384 [cluster]
    root      7478  0.0  0.0 103256   812 pts/0    S+   00:56   0:00 grep redis
    
    [root@manage redis]# kill -9 7310  //关闭220 6382端口,看数据会不会丢失
    
    [root@slave2 redis]# redis-trib.rb check 192.168.10.219:6379  //查看集群情况,任何接口都行
    Connecting to node 192.168.10.219:6379: OK
    Connecting to node 192.168.10.220:6384: OK
    Connecting to node 192.168.10.219:6381: OK
    Connecting to node 192.168.10.220:6383: OK
    Connecting to node 192.168.10.219:6380: OK
    >>> Performing Cluster Check (using node 192.168.10.219:6379)
    M: d40d9a367c24784b0336c7b80fb4c87337e2cba6 192.168.10.219:6379
     slots:5461-10922 (5462 slots) master
     1 additional replica(s)
    S: 5f00f163d0c0a540ea99daf004f55588a802327b 192.168.10.220:6384
     slots: (0 slots) slave
     replicates d40d9a367c24784b0336c7b80fb4c87337e2cba6
    S: b3b1a848987b5a87a06888e126d5c9b16f871ff5 192.168.10.219:6381
     slots: (0 slots) slave
     replicates d2eb5a8a77f87888792428aed4692dfb907e7a1d
    M: d2eb5a8a77f87888792428aed4692dfb907e7a1d 192.168.10.220:6383
     slots:10923-16383 (5461 slots) master
     1 additional replica(s)
    M: a87d207204a53ab599bf7f6ffb9d679d0eef4f25 192.168.10.219:6380
     slots:0-5460 (5461 slots) master
     0 additional replica(s)
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.  //变成,三主二从了
    
    [root@slave2 redis]# redis-cli -c -p 6379 -h 192.168.10.219    //219登录
    192.168.10.219:6379> get tank
    -> Redirected to slot [4407] located at 192.168.10.219:6380   //数据被转到了6380节点了
    "tank1"

    经测试,集群是可用的。

    http://blog.51yip.com/nosql/1725.html

  • 相关阅读:
    简单了解Linux文件目录
    解决GitLab的Forbidden和Nginx启动失败
    浅谈apidoc的使用
    Linux安装apidoc
    DevExpress的GridControl的实时加载数据解决方案(取代分页)
    Devexpress使用经验1
    ajax下载文件
    var str = "1,21,".TrimEnd(',');
    MSSQ调优所需用的语句
    js中替换返回json中的空格为 
  • 原文地址:https://www.cnblogs.com/tianciliangen/p/4988325.html
Copyright © 2020-2023  润新知