Tomcat部署及优化

1 Tomcat 概述

1.1 Tomcat 介绍

1.2 Tomcat 核心组件

通常意义上的Web 服务器接受请求后, 只是单纯地响应静态资源(如HTML 文件、图片文件等) , 不能在后端进行一定的处理操作。Tomcat 是Ap ache 下的一个子项目, 它具备Web 服务器的所有功能, 不仅可以监听接受请求并响应静态资源, 而且可以在后端运行特定规范的J ava 代码Servlet, 同时将执行的结果以HTML 代码的形式返回客户端。

Tomcat 由一系列的组件构成其中核心的组件有三个。

  • Web 容器: 完成Web 服务器的功能。
  • Servlet 容器: 名字为catali na, 用千处理Servlet 代码。
  • J SP 容器: 用于将JSP 动态网页翻译成Servlet 代码。

1.3 Tomcat 请求处理

Tomcat 具体的处理请求过程如下所示。

  • 用户在浏览器中输入网址localhost: 8080/test/i ndex.j sp , 请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector 获得;
  • Connector 把该请求交给它所在的Service 的Engi ne C Conta iner ) 来处理, 并等待Engi ne 的回应;
  • Engi ne 获得请求localhost/test/i ndex.jsp , 匹配所有的虚拟主机Host ;
  • Engi ne 匹配到名为lo cal host 的Host ( 即使匹配不到也把请求交给该Host 处理, 因为该Host 被定义为该Engi ne 的默认主机) , 名为localhost 的Host 获得请求/test/index.jsp , 匹配它所拥有的所有Context 。Host 匹配到路径为/test 的Context( 如果匹配不到就把该请求交给路径名为""的Context 去处理) ;
  • path="/test”的Context 获得请求/index.j sp ,在它的ma ppi ng table 中寻找出对应的Servlet。Context 匹配到URL Pattern 为* .jsp 的Servlet,对应千J spServlet 类;
  • 构造Http ServletRequest 对象和HttpSe rvletRes ponse 对象,作为参数调用JspServlet的doGet()或doPost() ,执行业务逻辑、数据存储等;
  • Context 把执行完之后的Http ServletResponse 对象返回给Host ;
  • Host 把HttpServletRe spo nse 对象返回给Engine :
  • Engine 把HttpServletResponse 对象返回Connector:
  • Connector 把HttpServletRespo nse 对象返回给客户Browser 。

2 Tomcat 服务部署

2.1 下载并安装J DK

在部署Tomcat 服务之前需要先部署好实验环境, 实验环境的具体要求如图所示。

名称说明
系统版本Cent0S7.3 ( 64 位)
Tomcat 版本

9.0.8

jdk 版本1.8.0_171
服务器IP地址192.168.9.236 6G 内存
Windows 客户端I P 地址及其配置192.168.9.232 8G 内存
主机名localhost.localdomain
Firewalld关闭
Selinux禁用
Jmeter 版本3.1

下载完安装包后, 将其上传到服务器/root 目录下, 执行安装命令。

[root@local host ~]# rpm -ivh jdk-8u171 -linux-x64.rpm
准备中…                                                 ################################ [100% ]
正在升级/安装…
1 :jdk1 .8-2000: 1.8.0_ 171-fcs                 ################################ [100% ]
Unpacking JAR files...
tools.Jar...
plugin.jar...
javaws .j ar. .
deploy.jar...
rt .jar...
jsse.jar...
charsets .jar.. .
localedata.Jar...

上面显示安装完成,jdk 安装目录在/usr/java/jdk1 .8 .0_171-amd64 ,, 编辑/etc/profile文件, 设置jdk 的环境变屈。具体操作如下。

[root@localhost ~]#vim /etc/profile

export JAVA_HOME=/usr/java/jdk1 .8.0_ 171-amd64

export CLASSPATH= $JAVA_HOME/Ii b/tools.jar:$JAVA_HOME/l ib/dt.jar

export PATH=$JAVA_HOME/bin:$PATH

[root@localhost ~]#source /etc/profile      //使环境变昼生效
[root@l ocal host~]# java -version            //查看jdk 版本号
java version "1 .8.0_ 171"
Java(TM) SE Runtime Environment (build 1.8.0_ 171-b11)
Java HotSpot(TM) 64-Bit Serve 「VM (build 25.171 -b11 , mixed mode)

2.2 安装启动Tomcat

1. 安装Tomcat 服务

从Tomcat 官网下载apache-tomcat-9. 0 .8. tar. gz 稳定版本, 将安装包解压后移动Tomcat目录到/usr/lo cal 下面, 然后执行/usr/local/tomcat/bin/sta rtup . sh 命令启动Tomcat 即可。具体操作如下。

 [root@l ocal host ~]# wget
https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.8/bin/apache-tomcat-9.0.8.tar.gz
[root@localhost~]#tar zxf apache-tomcat-9.0.8.tar.gz
[root@localhost ~]#mv apache-tomcat-9.0.8 /usr/local/tomcat
[root@localhost ~]#/usr/local/tomcatlbin/startup.sh    //启动Tomcat
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /us 「/loca l/tomcat
Using CATALINA_ TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr1ava/jdk1.8.0_ 171-amd64
Using CLASSPATH: /us 「/loca l/tomcat/b in/bootstrap.jar:/usr/local/tomcat/bin/tomcatjuli.jar
Tomcat started.

浏览器打开http:l/192.16 8.9.2 36 : 8080 进行访问会出现Tomcat 主页, 如图所示。

2. 优化Tomcat 服务启动时间

查看日志会发现Tomcat 第一次启动很慢, 默认情况下都需要几十秒。修改JDK 参数可以改善该状况, 打开/usr/java/jdk1.8.0_171-amd64/j re/l i b/security/java.security文件, 找到如下内容: secur可andom . source=fi le :/dev/random 修改成securerandom . source=file :/dev/urandom 。然后重启Tomcat 就会发现启动时间变短很多。

[root@localhost cont]# vim /usr/java/jdk1.8.0_ 171 -amd64/jre/Iib/security/java.security

secure rand om.source=fi le :/dev/urandom

[root@localhost cont}# /usr/local/tomcat/bin/shutdown.sh      //关闭Tomcat

Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_ TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr1ava/jdk1.8.0_ 171-amd64
Using CLASSPATH: /usr/loca l/tomcat/bin/bootstra p.jar:/usr/local/tomcat/bin/tomcatjuli.jar

[root@localhost cont}# /usr/local/tomcatlbin/startup.sh          //启动Tomcat
Using CATALINA_BASE: /usr/loca l/tomcat
Using CATALINA_HOME: /usr/loca l/tomcat
Using CATALINA_ TMPDIR: /usr/local/tomcaUtemp
Using JRE_HOME: /usr1ava/jdk1 .8.0_ 171-amd64
Using CLASSPATH: /usr/loca l/tomcat/b in/bootstra p.jar:/usr/local/tomcat/bin/tomcat-juli .jar
Tomcat started.

3. Tomcat 目录结构

执行11 /usr/local/tomcaV命令即可查看Tomcat 安装后目录结构, 如下图所示。

Tomcat 各目录的作用具体如下所示。

  • bin 目录: 用千存放启动和关闭Tomcat 的脚本文件, 比较常用的是catalina.sh 、startup.sh、shutdown . sh 三个文件。
  • conf 目录: 用千存放Tomcat 服务器的各种配置文件, 比较常用的是server. xml 、context .xml 、tomcat-users .xml 、web.xml 四个文件。
  • lib 目录: 用千存放Tomcat 服务器的jar 包, 一般不作任何改动,除非连接第三方服务,比如redis, 那就需要添加相对应的jar 包。
  • logs 目录: 用于存放Tomcat 日志。
  • tem p 目录: 用于存放Tomcat 运行时产生的文件。
  • webapps 目录: 用千存放项目资源的目录。
  • work 目录: 是Tomcat 工作目录, 一般清除Tomcat 缓存的时候会使用到。

8.3 Tomcat 配置与优化

3.1 虚拟主机配置

1 . 创建www 和bbs 项目目录和文件

执行下面的命令, 可以创建www 和bbs 项目目录和文件。

[root@localhost ~]# mkdir /usr/local/tomcatlwebappslwww
[root@localhost~]#echo "This is www page\!"> /usr/local/tomcat/webapps/www/index.jsp
[root@localhost ~]# mkdir /usr/local/tomcatlwebapps/bbs
[root@l ocalhost ~]#cho "This is bbs page\!"> /usr/locaUtomcatlwebapps/bbs/index.jsp

2 . 修改Tomcat 主配置文件

修改Tomcat 主配置文件/usr/local/tomcat/conf/server. xml , 在</Host> 下面增加如下内容。

[root@localhost ~]#vim /usr/local/tomcat/conf/server.xml
//关于www.test.com 的虚拟主机配置
<Host name=''www.test.com" appBase="/usr/Iocal/tomca/webapps"
unpackWARs="true" autoDeploy="true" xmlValidation="false"
xmlNamespaceAware="false">
<Context docBase="/usr/l oca l /tomcat/webapps/www"
path="" reloadable="true" />
</Host>
//关于bbs.test.com 的虚拟主机配置
<Host name="bbs.test.com" appBase="/usr/local/tomcat/webapps"
unpackWARs="true" autoDeploy="t「ue" xmlValidation="false"
xmlNamespaceAware="false">
<Context docBase="/usr/local/tomcat/webapps/bbs"
path="" reloadable="true" />
</Host>
[root@localhost ~]#/usr/local/tomcatlbin/shutdown.sh
[root@localhost ~]# /usr/local/tomcatlbin/startup.sh

 3 . 虚拟主机访问测试

客户端绑定两个域名需要写入本机hosts, Tomcat 默认端口是8080。

192.168.9.236  www.test.com
192.168.9.236  bbs.test.com

 使用浏览器访问http ://www. test. com: 8080, 页面效果如图所示。

使用浏览器访问http ://bbs. test. com:8080 , 页面效果如图所示。

3.2 Tomcat 优化

1. Tomcat 配置文件参数优化

关千Tomcat 主配置文件server.xml 里面很多默认的配置项,并不能满足业务需求, 常用的优化参数如下。

  • maxThreads: Tomcat 使用线程来处理接收的每个请求, 这个值表示Tomcat 可创建的最大的线程数, 默认值是200 。
  • minSpareThreads: 最小空闲线程数, Tomcat 启动时的初始化线程数, 表示即使没有人使用也开这么多空线程等待, 默认值是10 。
  • maxSpare Threads: 最大备用线程数, 一旦创建的线程超过这个值, Tomcat 就会关闭不再需要的socket 线程。默认值是-1 (无限制) , 一般不需要指定。
  • URIEncoding : 指定Tomcat 容器的URL 编码格式, Tomcat 语言编码格式这块不如其它Web 服务器软件配置方便, 需要分别指定。
  • connnectionTimeout: 网络连接超时, 单位: 毫秒, 设置为0 表示永不超时, 这样设置有隐患的。通常默认20000 毫秒就可以。
  • enablelookups: 是否反查域名, 以返回远程主机的主机名, 取值为:true 或false ,如果设置为false, 则直接返回IP 地址, 为了提高处理能力, 应设置为false 。
  • disableUploadTimeout: 上传时是否使用超时机制。应设置为true 。
  • connectionU ploadTimeout: 上传超时时间, 毕竞文件上传可能需要消耗更多的时间,该参数需要根据自己的业务需要自行调整,以使Servlet 有较长的时间来完成它的执行,需要与上一个参数一起配合使用才会生效。
  • acceptCount : 指定当所有可以使用的处理请求的线程都被使用时, 可传入连接请求的最大队列长度, 超过这个数的请求将不予处理, 默认为100 个。
  • compression : 是否对响应的数据进行GZIP 压缩,off 表示禁止压缩、on 表示允许压缩(文本将被压缩) 、force 表示所有情况下都进行压缩, 默认值为off。压缩数据后可以有效的减少页面的大小, 一般可以减小1/3 左右, 因而节省带宽。
  • compressionMinSize: 表示压缩响应的最小值, 只有当响应报文大小大千这个值的时候才会对报文进行压缩, 如果开启了压缩功能, 默认值就是2048 。
  • compressableMimeType: 压缩类型, 指定对哪些类型的文件进行数据压缩。
  • noCompressionUserAgents="gozilla, travi ata": 对千以下的浏览器, 不启用压缩。

如果已经对代码进行了动静分离, 静态页面和图片等数据就不需要Tomcat 处理了, 那么也就不需要在Tomcat 中配置压缩了。因为这里只有一台Tomcat 服务器, 而且压测的是Tomcat 首页, 会有图片和静态资源文件, 所以这里启用压缩。

2. jmeter 压测丁具

(1) 客户端安装JDK

从Oracle 官方下载JDK 软件,JDK 安装过程直接下一步即可。因为本章中所使用的客户端是Windows 10, 所以JDK 使用凡k-8u 102-windows-x64 版本。

(2) 运行丿meter 软件

使用的jmeter 软件版本为a pache-j meter-3.1 , 双击运行apache-jmeter-3.1.rar压缩包-> bi n 目录- >ApacheJ Meter.jar 文件即可打开丿meter 软件, 如图所示。

(3) 打开压测脚本进行压测

点击左上角文件->打开->选择压测脚本, 如图所示。

单击第一排绿色三角按钮(鼠标指上去后会显示启动)开始进行压测, 如图所示。

压测脚本里设置的是20 秒启动4000 个线程数, 并发为2000, 超时时间是50000 毫秒。也可以适当的根据自己的需求进行修改。为了不那么复杂, 从压测结果看只关注聚合报告, 聚合报告只关注Average 、90% Line 、Erro喉这三列, 因为压测Tomcat 首页压力不会太大, 所以Error 都是为0 属千正常。先看一组优化前( 默认的配置) 压测截图,如图所示。

(4) 修改Tomcat 配置

打开Tomcat 主配置文件server.xm l, 找到如下默认配置。

[root@localhost ~]# vim /us r/loca I/tom catlconf/server.xmI
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

将Tomcat 原本的默认配置修改为如下所示。

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" minSpare Threads="50"
enableLooku ps="false" d isableU pl oad Ti meout="true"
enable Looku ps="false" disableUpload Timeout="true"
acceptCount="300" maxThreads="500" processorCache="500"

URIEncoding="UTF-8"
compression="on"

compressionMinSize="2048"compressableMimeType="texUhtml,text/xml,text/javascript,text/css,tex
Uplain,image/gif,image1pg,image/png"/>

(5) 修改配置参数后压测

重新启动Tomcat 服务器, jmeter 还是继续保持同样的参数进行压测, 优化后压测截图,
如所示。

从结果看优化后的平均值和90%响应时间比优化前的快。

3. J ava 虚拟机( JVM ) 调优

Tom cat 启动命令行中的优化参数, 就是JVM 的优化。Tomcat 是Java 程序,运行在JVM 之上, 因为它的启动其实也只是一个Java 命令行,我们需要对这个Java 的启动命令行进行调优。不管是YGC 还是Full GC 、GC 都会导致程序运行中断, 正确的选择不同的GC 策略, 调整JVM 、GC 的参数, 可以极大的减少由千GC 工作而导致的程序运行中断方面的问题, 进而适当的提高J ava 程序的工作效率。

Tom cat 的启动参数位千安装目录${JAVA_H OME}/bi n 目录下, Linux 操作系统就是catali na .sh 文件。Java_OPTS 就是用来设置JVM 相关运行参数的变量, 下面具体看JVM常用参数详解。

  • -serve: 一定要作为第一个参数, 只要Tomcat 是运行在生产环境中, 这个参数必须给加上, 不然后面的参数不会生效。
  • -Xms: 表示J ava 初始化堆的大小, -Xms 与-Xmx 设成一样的值, 避免JVM 反复重新申请内存, 导致性能大起大落, 默认值为物理内存的1 /64 , 默认( M i nHea pFreeRatio参数可以调整)空余堆内存小于40%时,JVM 就会增大堆直到-Xmx 的最大限制。
  • -Xmx: 表示最大Java 堆大小, 当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出, 并且导致应用服务崩溃, 因此一般建议堆的最大值设置为物理内存的最大值的50% 。
  • -XX:NewSize: 设置新生代内存大小。
  • -XX:MaxNewSize: 设置最大新生代内存大小。
  • -XX:PermSize: 设置持久代内存大小。
  • XX:MaxPermSize: 设置最大值持久代内存大小, 永久代不属于堆内存, 堆内存只包含新生代和老年代。
  • XX :+Aggress iveOpts: 作用如其名( aggressive ) , 若启用这个参数,则每当JDK 版本升级时,JVM 都会使用最新加入的优化技术(如果有的话) 。
  • -XX :+UseBiasedlocking : 启用一个优化了的线程锁, 要知道在appserver, 每个http请求就是一个线程, 有的请求短有的请求长, 就会有请求排队的现象, 甚至还会出现线程阻塞, 这个优化了的线程锁使得a ppserver 内对线程处理自动进行最优调配。
  • -XX:+ DisableExpl icitGC: 在程序代码中不允许有显示的调用“System.gcO ”。每次在操作结束时手动调用System.gc() 一下, 付出的代价就是系统响应时间严重降低, 就和关千Xms, Xmx 里的原理一样, 这样去调用GC 会导致系统的JVM 大起大落。
  • -XX:+UseParNewGC: 对新生代采用多线程并行回收, 这样收得快。需要注意的是在最新JVM 版本中, 当使用-XX:+UseConcMarkSweepGC 时, -XX : UseParNewGC 会自动开启。因此, 如果年轻代的并行GC 不想开启, 可以通过设置-XX: -UseParNewGC来关掉。
  • -XX:MaxTenuringThreshold: 设置垃圾最大年龄。如果设置为0 的话,则新生代对象不经过Survivor 区, 直接进入老年代。对于老年代比较多的应用( 需要大量常驻内存的应用) , 可以提高效率。如果将此值设置为一个较大值,则新生代对象会在Survivor区进行多次复制, 这样可以增加对象在新生代的存活时间, 增加在新生代即被回收的概率,减少Full GC 的频率, 这样做可以在某种程度上提高服务稳定性。该参数只有在串行GC 时才有效, 这个值的设置是根据本地的jprofiler 监控后得到的一个理想的值,不能一概而论原搬照抄。
  • -XX:+CMSParallelRemarkEnabled: 在使用UseParNewGC 的情况下,尽量减少mark 的时间。
  • -XX:+UseCMSCompactAtFullCollection : 在使用concurrentgc 的情况下, 防止memoryfragmention , 对live object 进行整理, 使memory 碎片减少。
  • -XX:LargePageSizeI nBytes: 指定Java heap 的分页页面大小, 内存页的大小不可设置过大, 会影响Perm 的大小。
  • -XX: +UseFastAccessorMethods: 使用get , set 方法转成本地代码, 原始类型的快速优化。
  • -XX:+UseCMSlniti ati ngOccupancyOnly: 只有在oldgeneration 在使用了初始化的比例后concu rrent collector 启动收集。
  • -Duser. ti mezone=Asia/Shangha i: 设置用户所在时区。
  • -Djava.awt. headless=true: 这个参数一般我们都是放在最后使用。有时我们会在我们的J2EE 工程中使用一些图表工具, 如: jfreecha八, 用于在Web 网页输出GIF/J PG等流, 在Wi ndows 环境下, 一般我们的a pp server 在输出图形时不会碰到什么问题,但是在Linux/Un ix 环境下经常会碰到一个exce ption 导致你在Windows 开发环境下图片正常显示,可是在Li nux/Unix 下却显示不出来, 因此加上这个参数以免避这样的情况出现。
  • -Xmn: 新生代的内存空间大小, 注意:此处的大小是( eden+ 2 surviverspace) 。与jmap-heap 中显示的New gen 是不同的。整个堆大小= 新生代大小+ 老生代大小+ 永久代大小。在保证堆大小不变的情况下, 增大新生代后, 将会减小老生代大小。此值对系统性能影响较大, Sun 官方推荐配置为整个堆的3/8 。
  • -XX : CMSlnitiating OccupancyFraction: 当堆满之后, 并行收集器便开始进行垃圾收集。为了
  • 在应用程序使用完内存之前完成垃圾收集周期, CMS 收集器要比并行收集器更先启动。
  • -XX:+CMSlncrementalMode: 该标志将开启CMS 收集器的增量模式。增量模式经常暂停CMS 过程, 以便对应用程序线程作出完全的让步。因此, 收集器将花更长的时间完成整个收集周期。因此, 只有通过测试后发现正常CMS 周期对应用程序线程干扰太大时, 才应该使用增鼠模式。由于现代服务器有足够的处理器来适应并发的垃圾收集, 所以这种情况发生得很少, 用于但CPU 情况。
  • -XX:NewRatio: 年轻代( 包括Eden 和两个Survivor 区)与年老代的比值(除去待久代) , -XX:NewRati o=4 表示年轻代与年老代所占比值为1 :4, 年轻代占整个堆栈的1/5, Xms=Xmx 并且设置了Xmn 的情况下, 该参数不需要进行设置。
  • -XX:SurvivorRatio: Eden 区与Survivor 区的大小比值, 设置为8 , 表示2 个Survivor 区( JVM 堆内存年轻代中默认有2 个大小相等的Survivor 区)与1 个Eden 区的比值为2:8, 即1 个Survivor 区占整个年轻代大小的1 /10 。
  • -XX:+UseSerialGC: 设置串行收集器。
  • -XX :+UseParallelGC: 设置为并行收集器。此配置仅对年轻代有效。即年轻代使用并行收集, 而年老代仍使用串行收集。
  • -XX: + UseParallelOldGC: 配置年老代垃圾收集方式为并行收集,J DK6.0 开始支待对年老代并行收集。
  • -XX:ConcGCThreads: 早期JVM 版本也叫-XX:ParallelCMSThreads , 定义并发CMS过程运行时的线程数。比如value=4意味着CMS 周期的所有阶段都以4 个线程来执行。尽管更多的线程会加快并发CMS 过程,但其也会带来额外的同步开销。因此,对千特定的应用程序, 应该通过测试来判断增加CMS 线程数是否真的能够带来性能的提升。如果还标志未设置,JVM 会根据并行收集器中的-XX: ParallelGCThreads 参数的值来计算出默认的并行CMS 线程数。
  • -XX: ParallelGCThreads : 配置并行收集器的线程数, 即: 同时有多少个线程一起进行垃圾回收, 此值建议配置与CPU 数目相等。
  • -XX:OldSize : 设置JVM 启动分配的老年代内存大小, 类似千新生代内存的初始大小-XX : NewSize 。

以上就是一些常用的配置参数, 但是有些参数是可以被替代的, 配置思路需要考虑的是Java 提供的垃圾回收机制。虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾能够接受的速度和应用有关, 应该通过分析实际的垃圾收集的时间和频率来调整。假如堆的大小很大, 那么完全垃圾收集就会很慢, 但是频度会降低。

测试前, 先还原Tomcat 到默认的配置文件, 重启后压测一组优化前压测截图,如图所示。

上述关千JVM 优化参数太多, 很多参数需要对GC 回收有很深刻的认识。如果优化的不合适, 往往会起到事倍功半的效果。下面是常见的优化参数, 修改/usr/local/tomca/bi n/catalina .sh , 增加红色字体。

[root@localhost ~]#vim /usr/local/tomcat/bin/catalina.sh
# OS specific support. $var _must_ be set to eit hertrue or false

JAVA_ OPTS="-serve r-Xms4096m -Xmx4096m -XX:PermSize=2048m -XX:MaxPermSize=2048m"
cygwin=false
darwin=false

重启Tomcat 服务再次进行一轮压测, 如图所示。

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值