学习淘淘商城第三十六课(Solr集群搭建)

关于SolrCloud的基本知识,大家可以参考http://www.cnblogs.com/saratearing/p/5690476.html这篇博客进行学习。

      下面我们来搭建SolrCloud集群,先来看下我们要搭建的集群图,如下图所示,可以看到Solr集群由三台注册中心(Zookeeper集群)和四台部署有Solr的设备组成。我们采用七台虚拟机来搭建Solr集群。

      下面一步一步来进行搭建。

第一步:新建三台虚拟机(如果有现成的设备,不需要新建)注意:大家最好不要用克隆的方式,因为据我的试验,用克隆的方式搭建的Solr集群在重启后原来的库会消失,而且会出现各种各样的问题。

       大家可以参考Vmware12最小化安装CentOS6.8这篇博客进行搭建。

第二步:安装单机版Zookeeper

       大家可以参考淘淘商城第十一课(dubbo入门及单机版zookeeper安装)这篇博客进行安装

第三步:搭建Zookeeper集群

       首先,为zookeeper1(itcast04)配置一下IP和主机名的映射关系,如下所示。

 

[root@itcast04 ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6i

192.168.117.103 itcast04
192.168.117.104 itcast05
192.168.117.105 itcast06

        接着修改zookeeper1(itcast04)的配置文件,先进入到conf目录下,找到我们搭建单机版zookeeper时配置的zoo.cfg文件,在文件的最后添加上三行配置,如下所示。我们以server.1=itcast04:2888:3888为例,server.1代表服务的编号,itcast04代表服务的地址,2888代表通信端口,3888代表选举端口。

[root@itcast04 conf]# pwd
/itcast/zookeeper-3.4.5/conf

#autopurge.purgeInterval=1

tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
#LF初始化通信时间
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
#LF同步通信时限
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
#数据文件目录
#dataDir=/tmp/zookeeper
dataDir=/itcast/zookeeper-3.4.5/data
# the port at which the clients will connect
#客户端连接端口
clientPort=2181
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain indataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
#服务器名称与地址:集群信息(服务器编号,服务器地址,LF通信端口,选举端口)
server.1=itcast04:2888:3888
server.2=itcast05:2888:3888
server.3=itcast06:2888:3888

       我们到配置文件中dataDir指定的/itcast/zookeeper-3.4.5/data目录下,如果看到该目录下已经有文件的话,我们一定要删除掉,否则zookeeper启动不了,如下所示,我们看到有一个文件夹version-2和一个zookeeper_server.pid(该文件会导致zookeeper启动不了),我们把它们都删除掉,只剩个空目录就行

[root@itcast04 zookeeper-3.4.5]# cd data/
You have new mail in /var/spool/mail/root
[root@itcast04 data]# ll
total 12
-rw-r--r-- 1 root root    2 Jun 19 03:47 myid
drwxr-xr-x 2 root root 4096 Jul 12 03:16 version-2
-rw-r--r-- 1 root root    4 Aug  7 23:04 zookeeper_server.pid
[root@itcast04 data]# 

        在空目录下使用命令vim myid新建一个myid文件并在里面输入1(这个数字1就代表我们上面配置文件中server.1的这个数字1),输入完1后保存退出(这时data目录下只有myid这么一个文件)。

[root@itcast04 data]# vim myid

1

       这样我们便配置完了一台zookeeper,由于另外两台设备的相关配置一样(除myid文件之外),因此我们把zookeeper1上的相关配置复制到其它两台设备上。我们先把/etc/目录下的hosts文件复制到其它两台zookeeper上,如下所示。

 

[root@itcast04 data]# scp /etc/hosts root@itcast05:/etc/
hosts                                                                                                                      100%  359     0.4KB/s   00:00    
[root@itcast04 data]# scp /etc/hosts root@itcast06:/etc/
hosts                                                                                                                      100%  359     0.4KB/s   00:00    
[root@itcast04 data]# 


         拷贝完之后,我们到zookeeper2(itcast05)和zookeeper3(itcast06)这两台设备上查看下原文件是否已经被覆盖,我们以zookeeper2(itcast05)为例,可以看到已经成功被覆盖了(另一台我就不粘贴了)。

[root@itcast05 ~]# more /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6i
192.168.117.100 itcast01
192.168.117.101 itcast02
192.168.117.102 itcast03
192.168.117.103 itcast04
192.168.117.104 itcast05
192.168.117.105 itcast06
192.168.117.106 itcast07
192.168.117.107 itcast08
You have new mail in /var/spool/mail/root
[root@itcast05 ~]# 

        下面我们把/itcast/zookeeper-3.4.5/conf/目录下的zoo.cfg文件拷贝到zookeeper2(itcast05)和zookeeper3(itcast06)上。命令如下。

[root@itcast04 conf]# # scp zoo.cfg root@itcast05:/itcast/zookeeper-3.4.5/conf/
[root@itcast04 conf]# # scp zoo.cfg root@itcast06:/itcast/zookeeper-3.4.5/conf/


         下面我们在zookeeper2(itcast05)和zookeeper3(itcast06)的/itcast/zookeeper-3.4.5/data目录下都新建一个myid文件,并且分别输入2和3并保存退出,如下所示。

[root@itcast05 data]# vim myid

2
[root@itcast06 data]# vim myid

3

        下面我们需要修改下Window系统的hosts文件,位置如下图所示。

        以管理员的身份打开HOSTS文件,并在最下面添加如下配置

192.168.117.103 itcast04
192.168.117.104 itcast05
192.168.117.105 itcast06

         为了防止防火墙给集群搭建带来不必要的麻烦,建议关掉防火墙,关闭防火墙的命令是service iptables stop,禁止防火墙重启的命令是chkconfig iptables off。

         由于我们修改了/etc/hosts文件,我们重启下三台Zookeeper设备。重启命令是reboot

         重启之后,我们来依次启动三台zookeeper设备,看集群是否搭建成功。

         先看下zookeeper1(itcast04)的情况,发现该节点zookeeper的角色是follower,如下所示。(注:如果启动报Error contacting service. It is probably not running.这样的错误,请删除/itcast/zookeeper-3.4.5/data目录下的version-2和 zookeeper_server.pid文件,然后重新启动)

[root@itcast04 bin]# ./zkServer.sh start
JMX enabled by default
Using config: /itcast/zookeeper-3.4.5/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@itcast04 bin]# ./zkServer.sh status
JMX enabled by default
Using config: /itcast/zookeeper-3.4.5/bin/../conf/zoo.cfg
Mode: follower
[root@itcast04 bin]# 

            接着看下zookeeper2(itcast05)的情况,发现该节点的zookeeper角色是leader(领导者)

[root@itcast05 bin]# ./zkServer.sh start
JMX enabled by default
Using config: /itcast/zookeeper-3.4.5/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@itcast05 bin]# ./zkServer.sh status
JMX enabled by default
Using config: /itcast/zookeeper-3.4.5/bin/../conf/zoo.cfg
Mode: leader
[root@itcast05 bin]# 


          最后看下zookeeper3(itcast06)的情况,发现该节点zookeeper的角色是follower,这说明我们的zookeeper集群搭建成功了!

[root@itcast06 bin]# ./zkServer.sh start
JMX enabled by default
Using config: /itcast/zookeeper-3.4.5/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@itcast06 bin]# ./zkServer.sh status
JMX enabled by default
Using config: /itcast/zookeeper-3.4.5/bin/../conf/zoo.cfg
Mode: follower
[root@itcast06 bin]# 
第四步:新建四台虚拟机并安装单机版的Solr

      大家可以参考学习淘淘商城第三十五课(Solr的安装)这篇博客进行学习,由于Solr集群会用到中文分析器IKAnalyzer,因此我们需要为每台Solr配置IKAnalyzer,大家可以参考学习淘淘商城第三十七课(中文分析器IK-Analyzer的使用)这篇博客进行配置。

第五步:为了避免tomcat的默认端口8080与我们其它的tomcat工程冲突,我们把Solr所在的四台设备的tomcat的端口都改为8180

       我们到tomcat的conf目录下(/usr/local/solr/tomcat/conf)修改server.xml文件,把下面这段配置的port的值由原来的8080修改为8180。如下所示。

<Connector port="8180" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

        注意:把其它三台Solr虚拟机的tomcat端口也都修改为8180

 

第六步:为4台Solr虚拟机都配置下solrhome目录下的solr.xml文件

[root@itcast07 local]#  cd /usr/local/solr/solrhome/
[root@itcast07 solrhome]# ll
total 20
drwxr-xr-x 2 root root 4096 Aug  6 19:00 bin
drwxr-xr-x 4 root root 4096 Aug  6 19:08 collection1
-rw-r--r-- 1 root root 2473 Aug  6 19:00 README.txt
-rw-r--r-- 1 root root 1715 Aug  6 19:00 solr.xml
-rw-r--r-- 1 root root  501 Aug  6 19:00 zoo.cfg
[root@itcast07 solrhome]# 

        下面我们修改solr.xml,我们修改的只有<solrcloud>里面的前两项,host和hostPort,host的值修改为我们solr4(itcast07:192.168.117.106)的IP地址,hostPort修改为我们刚才为tomcat的修改的端口8180,其它不用动。

[root@itcast07 solrhome]# vim solr.xml 

<?xml version="1.0" encoding="UTF-8" ?>
<solr>

  <solrcloud>
    <str name="host">192.168.117.106</str>
    <int name="hostPort">8180</int>
    <str name="hostContext">${hostContext:solr}</str>
    <int name="zkClientTimeout">${zkClientTimeout:30000}</int>
    <bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
  </solrcloud>

  <shardHandlerFactory name="shardHandlerFactory"
    class="HttpShardHandlerFactory">
    <int name="socketTimeout">${socketTimeout:0}</int>
    <int name="connTimeout">${connTimeout:0}</int>
  </shardHandlerFactory>

</solr>
       上面是solr4(192.168.117.106)上的修改,下面我们还需要对solr1(192.168.117.100) 、solr2(192.168.117.101)、solr3(192.168.117.102)、这三台设备的solr.xml文件进行相关配置,下面是solr1的配置。
[root@itcast01 solrhome]# vim solr.xml 

<?xml version="1.0" encoding="UTF-8" ?>
<solr>

  <solrcloud>
    <str name="host">192.168.117.100</str>
    <int name="hostPort">8180</int>
    <str name="hostContext">${hostContext:solr}</str>
    <int name="zkClientTimeout">${zkClientTimeout:30000}</int>
    <bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
  </solrcloud>

  <shardHandlerFactory name="shardHandlerFactory"
    class="HttpShardHandlerFactory">
    <int name="socketTimeout">${socketTimeout:0}</int>
    <int name="connTimeout">${connTimeout:0}</int>
  </shardHandlerFactory>

</solr>


       下面是solr2的配置

[root@itcast02 solrhome]# vim solr.xml 

<?xml version="1.0" encoding="UTF-8" ?>
<solr>

  <solrcloud>
    <str name="host">192.168.117.101</str>
    <int name="hostPort">8180</int>
    <str name="hostContext">${hostContext:solr}</str>
    <int name="zkClientTimeout">${zkClientTimeout:30000}</int>
    <bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
  </solrcloud>

  <shardHandlerFactory name="shardHandlerFactory"
    class="HttpShardHandlerFactory">
    <int name="socketTimeout">${socketTimeout:0}</int>
    <int name="connTimeout">${connTimeout:0}</int>
  </shardHandlerFactory>

</solr>


       下面是solr3的配置

[root@itcast03 solrhome]# vim solr.xml 

<?xml version="1.0" encoding="UTF-8" ?>
<solr>

  <solrcloud>
    <str name="host">192.168.117.102</str>
    <int name="hostPort">8180</int>
    <str name="hostContext">${hostContext:solr}</str>
    <int name="zkClientTimeout">${zkClientTimeout:30000}</int>
    <bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
  </solrcloud>

  <shardHandlerFactory name="shardHandlerFactory"
    class="HttpShardHandlerFactory">
    <int name="socketTimeout">${socketTimeout:0}</int>
    <int name="connTimeout">${connTimeout:0}</int>
  </shardHandlerFactory>

</solr>


第七步:让zookeeper统一管理配置文件

       我们先找到zkcli.sh文件所在的位置,在我的solr1中zkcli.sh文件的目录如下。

[root@itcast01 local]# cd /usr/local/solr-4.10.3/example/scripts/cloud-scripts/
[root@itcast01 cloud-scripts]# ll
total 12
-rw-r--r-- 1 root root 317 Dec  1  2014 log4j.properties
-rw-r--r-- 1 root root 707 Dec  1  2014 zkcli.bat
-rwxr-xr-x 1 root root 485 Dec  1  2014 zkcli.sh
[root@itcast01 cloud-scripts]# 

       下面我们使用该zkcli.sh脚本文件来执行上传操作,我们要上传的文件目录是/usr/local/solr/solrhome/collection1/conf,该目录下的文件如下所示。注:不同的人安装的习惯不一样,conf这个目录所在的位置也不一样,大家根据实际情况来操作就可以了。

[root@itcast01 cloud-scripts]# cd /usr/local/solr/solrhome/collection1/conf
[root@itcast01 conf]# ll
total 296
-rw-r--r-- 1 root root  1068 Aug  8 14:55 admin-extra.html
-rw-r--r-- 1 root root   928 Aug  8 14:55 admin-extra.menu-bottom.html
-rw-r--r-- 1 root root   926 Aug  8 14:55 admin-extra.menu-top.html
drwxr-xr-x 3 root root  4096 Aug  8 14:55 clustering
-rw-r--r-- 1 root root  3974 Aug  8 14:55 currency.xml
-rw-r--r-- 1 root root  1348 Aug  8 14:55 elevate.xml
drwxr-xr-x 2 root root  4096 Aug  8 14:55 lang
-rw-r--r-- 1 root root 78514 Aug  8 14:55 mapping-FoldToASCII.txt
-rw-r--r-- 1 root root  2868 Aug  8 14:55 mapping-ISOLatin1Accent.txt
-rw-r--r-- 1 root root   873 Aug  8 14:55 protwords.txt
-rw-r--r-- 1 root root    33 Aug  8 14:55 _rest_managed.json
-rw-r--r-- 1 root root   450 Aug  8 14:55 _schema_analysis_stopwords_english.json
-rw-r--r-- 1 root root   172 Aug  8 14:55 _schema_analysis_synonyms_english.json
-rw-r--r-- 1 root root 61573 Aug  8 14:55 schema.xml
-rw-r--r-- 1 root root   921 Aug  8 14:55 scripts.conf
-rw-r--r-- 1 root root 74827 Aug  8 14:55 solrconfig.xml
-rw-r--r-- 1 root root    13 Aug  8 14:55 spellings.txt
-rw-r--r-- 1 root root   781 Aug  8 14:55 stopwords.txt
-rw-r--r-- 1 root root  1119 Aug  8 14:55 synonyms.txt
-rw-r--r-- 1 root root  1416 Aug  8 14:55 update-script.js
drwxr-xr-x 2 root root  4096 Aug  8 14:55 velocity
drwxr-xr-x 2 root root  4096 Aug  8 14:55 xslt
You have new mail in /var/spool/mail/root
[root@itcast01 conf]# 


       在执行上传操作之前,我们需要先安装unzip命令(因为最小化安装的虚拟机当中默认是没有unzip命令的),如果不安装unzip的话,会报找不到unzip命令的错误!我们给四台solr设备都安装上该命令吧。

yum install zip unzip

        下面我们执行上传操作,命令如下(前提条件是在/usr/local/solr-4.10.3/example/scripts/cloud-scripts/目录下):

 

./zkcli.sh -zkhost 192.168.117.103:2181,192.168.117.104:2181,192.168.117.105:2181 -cmd upconfig -confdir /usr/local/solr/solrhome/collection1/conf -confname myconf

     如果想让命令执行的更灵活一点,那就使用绝对路径来操作,如下所示。

/usr/local/solr-4.10.3/example/scripts/cloud-scripts/zkcli.sh -zkhost 192.168.117.103:2181,192.168.117.104:2181,192.168.117.105:2181 -cmd upconfig -confdir /usr/local/solr/solrhome/collection1/conf -confname myconf

      上传成功后,我们到任何一台zookeeper上检验一下配置是否已经被上传上来了,我们到zookeeper1(itcast04)的bin目录下,如下所示。

[root@itcast04 bin]# pwd 
/itcast/zookeeper-3.4.5/bin
[root@itcast04 bin]# ll
total 64
-rwxr-xr-x 1 portal games   238 Sep 30  2012 README.txt
-rwxr-xr-x 1 portal games  1909 Sep 30  2012 zkCleanup.sh
-rwxr-xr-x 1 portal games  1049 Sep 30  2012 zkCli.cmd
-rwxr-xr-x 1 portal games  1512 Sep 30  2012 zkCli.sh
-rwxr-xr-x 1 portal games  1333 Sep 30  2012 zkEnv.cmd
-rwxr-xr-x 1 portal games  2599 Sep 30  2012 zkEnv.sh
-rwxr-xr-x 1 portal games  1084 Sep 30  2012 zkServer.cmd
-rwxr-xr-x 1 portal games  5467 Sep 30  2012 zkServer.sh
-rw-r--r-- 1 root   root  26763 Aug  8 01:07 zookeeper.out
[root@itcast04 bin]# 

       使用命令./zkCli.sh来登录服务端,如下所示。

[root@itcast04 bin]# ./zkCli.sh 
Connecting to localhost:2181
2018-08-08 01:05:33,889 [myid:] - INFO  [main:Environment@100] - Client environment:zookeeper.version=3.4.5-1392090, built on 09/30/2012 17:52 GMT
2018-08-08 01:05:33,894 [myid:] - INFO  [main:Environment@100] - Client environment:host.name=itcast04
......省略..........
JLine support is enabled
2018-08-08 01:05:35,807 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@849] - Socket connection established to localhost/0:0:0:0:0:0:0:1:2181, initiating session
2018-08-08 01:05:35,950 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1207] - Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2181, sessionid = 0x1651843c77e0001, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 0] ls /
[configs, zookeeper, hadoop-ha]
[zk: localhost:2181(CONNECTED) 1] 

        如果我们想连接其它端口(比如2183)的zookeeper,可以使用命令:./zkCli.sh -server 192.168.117.104:2183来进行登录。

       使用命令"ls /"来查看下根目录下是否有configs目录,如下所示,发现已经有了。

[zk: localhost:2181(CONNECTED) 0] ls /
[configs, zookeeper, hadoop-ha]
[zk: localhost:2181(CONNECTED) 1] 

       再看configs目录下是否有myconf目录,如下所示,发现是有的。

[zk: localhost:2181(CONNECTED) 0] ls /configs
[myconf]
[zk: localhost:2181(CONNECTED) 1] 
        我们还可以看看myconf目录下的所有文件,这些都是我们刚才上传的配置文件,如下所示。
[zk: localhost:2181(CONNECTED) 1] ls /configs/myconf
[currency.xml, mapping-FoldToASCII.txt, protwords.txt, scripts.conf, synonyms.txt, stopwords.txt, _schema_analysis_synonyms_english.json, velocity, admin-extra.html, update-script.js, _schema_analysis_stopwords_english.json, solrconfig.xml, admin-extra.menu-top.html, elevate.xml, schema.xml, clustering, xslt, _rest_managed.json, spellings.txt, mapping-ISOLatin1Accent.txt, lang, admin-extra.menu-bottom.html]
[zk: localhost:2181(CONNECTED) 2] 

第八步:  修改Solr所在的四台虚拟机的tomcat/bin目录下的catalina.sh 文件,关联solr和zookeeper

       首先,我们到tomcat的bin目录下,如下所示,可以看到catalina.sh文件。

[root@itcast01 cloud-scripts]# /usr/local/solr/tomcat/bin
-bash: /usr/local/solr/tomcat/bin: is a directory
[root@itcast01 cloud-scripts]# cd /usr/local/solr/tomcat/bin
[root@itcast01 bin]# ls
bootstrap.jar  catalina-tasks.xml            configtest.bat  daemon.sh   setclasspath.bat  shutdown.sh  tomcat-juli.jar       tool-wrapper.sh
catalina.bat   commons-daemon.jar            configtest.sh   digest.bat  setclasspath.sh   startup.bat  tomcat-native.tar.gz  version.bat
catalina.sh    commons-daemon-native.tar.gz  cpappend.bat    digest.sh   shutdown.bat      startup.sh   tool-wrapper.bat      version.sh
[root@itcast01 bin]# 

      修改catalina.sh文件,添加JAVA_OPTS="-DzkHost=192.168.117.103:2181,192.168.117.104:2181,192.168.117.105:2181",如下所示。

[root@itcast01 bin]# vim catalina.sh
You have new mail in /var/spool/mail/root
[root@itcast01 bin]#

# OS specific support.  $var _must_ be set to either true or false.
JAVA_OPTS="-DzkHost=192.168.117.103:2181,192.168.117.104:2181,192.168.117.105:2181"
cygwin=false
darwin=false
os400=false
case "`uname`" in
CYGWIN*) cygwin=true;;
Darwin*) darwin=true;;
OS400*) os400=true;;
esac
       修改完solr1之后,我们再修改其它三台solr设备,添加的内容完全一样,我就不啰嗦了。

第九步:启动每个tomcat实例。要确保zookeeper集群是启动状态。可以使用tailf logs/catalina.out命令查看启动日志。

       下面是solr1的tomcat启动操作,同理,我们再启动其它三台solr上的tomcat。

[root@itcast01 bin]# pwd
/usr/local/solr/tomcat/bin
[root@itcast01 bin]# ./startup.sh 
Using CATALINA_BASE:   /usr/local/solr/tomcat
Using CATALINA_HOME:   /usr/local/solr/tomcat
Using CATALINA_TMPDIR: /usr/local/solr/tomcat/temp
Using JRE_HOME:        /usr/java/jdk1.8.0_171
Using CLASSPATH:       /usr/local/solr/tomcat/bin/bootstrap.jar:/usr/local/solr/tomcat/bin/tomcat-juli.jar
[root@itcast01 bin]# 


第十步:我们访问任何一台Solr的首页,点击"Cloud",可以看到如下图所示。当前还没有进行分片处理。

 


      下面我们来进行分片处理,使用的命令是:http://192.168.117.100:8180/solr/admin/collections?action=CREATE&name=collection2&numShards=2&replicationFactor=2,执行结果如下图所示。


 

      我们再看看solr首页的云图,发现多了一个collection2的库。如下图所示。

        我们把没有分片的collection1删除掉,命令是:http://192.168.117.100:8180/solr/admin/collections?action=DELETE&name=collection1,如下图所示。

        我们再来查看solr首页云图,发现现在只剩下有分片的collection2了,我们的SolrCloud集群搭建成功了!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值