tomcat lb cluster 以及session cluster

本文详细介绍如何配置Tomcat集群实现负载均衡及会话共享,包括DNS解析、无密码SSH登录、防火墙与SELinux关闭等环境配置,以及Apache前端调度、Tomcat节点配置、会话管理等关键技术点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

配置环境
前端:192.168.31.131
node1:192.168.31.132
node2:192.168.31.133

1、创建解析:
# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.31.131 www.cpe.com www
192.168.31.132 node1.cpe.com node1
192.168.31.133 node2.cpe.com node2

2、配置无密码登录
# ssh-keygen
# ssh-copy-id -i /root/.ssh/id_rsa.pub root@node1;ssh-copy-id -i /root/.ssh/id_rsa.pub root@node2
# scp /etc/hosts root@node1:/etc/hosts; scp /etc/hosts root@node2:/etc/hosts

3、关闭防火墙已经sellinux
# yum -y install vim;ssh root@node1 ‘yum -y install vim’;ssh root@node2 ‘yum -y install vim’
# systemctl stop firewalld;ssh root@node1 ‘systemctl stop firewalld’;ssh root@node2 ‘systemctl stop firewalld’
# setenforce Permissive;ssh root@node1 ‘setenforce Permissive’; ssh root@node2 ‘setenforce Permissive’

4、安装配置dns
# yum -y install bind
# vim /etc/named.conf
options {}里修改一下两项:
listen-on port 53 { 192.168.31.131; };
allow-query { any; };
# vim /etc/named.rfc1912.zones
最后加入:
zone “cpe.com” IN {
type master;
file “cpe.com”;
};
# vim /var/named/cpe.com
$TTL 86400
$ORIGIN cpe.com.
@ IN SOA ns1.cpe.com. admin.cpe.com (
2015042201
1H
5M
7D
1D )
IN NS ns1
IN MX 10 mx1
ns1 IN A 192.168.31.131
mx1 IN A 192.168.31.131
www IN A 192.168.31.131
ftp IN CNAME www

5、安装epel源
# yum -y install epel-release;ssh root@node1 ‘yum -y install epel-release’;ssh root@node2 ‘yum -y install

6、配置安装jdk
# ssh root@node1 ‘yum -y install java-1.8.0-openjdk’;ssh root@node2 ‘yum -y install java-1.8.0-openjdk’

7、安装tomcat
# yum -y install wget
# wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.0.45/bin/apache-tomcat-8.0.45.tar.gz
# scp apache-tomcat-8.0.45.tar.gz root@node1: ;scp apache-tomcat-8.0.45.tar.gz root@node2:
# ssh root@node1 ‘tar -xf apache-tomcat-8.0.45.tar.gz -C /usr/local/’;ssh root@node2 ‘tar -xf apache-tomcat-8.0.45.tar.gz -C /usr/local/’
# ssh root@node1 ‘ln -sv /usr/local/apache-tomcat-8.0.45 /usr/local/tomcat’;ssh root@node2 ‘ln -sv /usr/local/apache-tomcat-8.0.45 /usr/local/tomcat’
# ssh root@node1 ‘cat > /etc/profile.d/tomcat.sh << EOF
TOMCAT_HOME=/usr/local/tomcat
PATH=\${TOMCAT_HOME}/bin:\$PATH
EOF’;ssh root@node2 ‘cat > /etc/profile.d/tomcat.sh << EOF
TOMCAT_HOME=/usr/local/tomcat
PATH=\${TOMCAT_HOME}/bin:\$PATH
EOF’

8、关闭防火前以及selinux。
# ssh root@node1 ‘reboot’;ssh root@node2 ‘reboot’
# ssh root@node1 ‘catalina.sh version’;ssh root@node2 ‘catalina.sh version’
# ssh root@node1 ‘systemctl stop firewalld’;ssh root@node2 ‘systemctl stop firewalld’
# ssh root@node1 ‘setenforce Permissive’; ssh root@node2 ‘setenforce Permissive’

node1:
1、创建app目录
# mkdir -pv /myweb/data/ROOT/{class,lib,WEB-INF,META-INF};
# cp -a /usr/local/tomcat/conf/web.xml /myweb/data/ROOT/WEB-INF/
# cp -a /usr/local/tomcat/conf/context.xml /myweb/data/ROOT/META-INF/

2、提供测试页面
# cat > /myweb/data/index.jsp << EOF
<%@ page language=”java” %>
<html>
<head><title>node1</title></head>
<body>
<h1><font color=”red”>node1.cpe.com</font></h1>
<table align=”centre” border=”1″>
<tr>
<td>Session ID</td>
<% session.setAttribute(“cpe.com”,”cpe.com”); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
EOF

3、编辑配置文件
# mv -v /usr/local/tomcat/conf/server.xml{,.bak}
# vim /usr/local/tomcat/conf/server.xml
<Host name=”www.cpe.com” appBase=”/myweb/data”
unpackWARs=”true” autoDeploy=”true”>
<Context path=”” docBase=”ROOT/”/>
<Valve className=”org.apache.catalina.valves.AccessLogValve” directory=”logs”
prefix=”localhost_access_log” suffix=”.txt”
pattern=”%h %l %u %t &quot;%r&quot; %s %b” />
</Host>

4、为host单独提供配置文件

# vim /usr/local/tomcat/conf/tomcat-users.xml
<tomcat-users xmlns=”http://tomcat.apache.org/xml”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://tomcat.apache.org/xml tomcat-users.xsd”
version=”1.0″>
<role rolename=”manager-gui”/>
<role rolename=”manager-gui”/>
<role rolename=”admin-gui”/>
<user username=”tomcat” password=”ma” roles=”admin-gui,manager-gui”/>
</tomcat-users>

node2:
1、创建文件夹以及提供配置文件
# mkdir -pv /myweb/data/ROOT/{class,lib,WEB-INF,META-INF};
# cp -a /usr/local/tomcat/conf/web.xml /myweb/data/ROOT/WEB-INF/
# cp -a /usr/local/tomcat/conf/context.xml /myweb/data/ROOT/META-INF/

2、编辑配置文件
# mv -v /usr/local/tomcat/conf/server.xml{,.bak}
# scp root@node1:/usr/local/tomcat/conf/server.xml /usr/local/tomcat/conf/server.xml

3、提供测试页面
# cat > /myweb/data/ROOT/index.jsp << EOF
<%@ page language=”java” %>
<html>
<head><title>node2</title></head>
<body>
<h1><font color=”red”>node2.cpe.com</font></h1>
<table align=”centre” border=”1″>
<tr>
<td>Session ID</td>
<% session.setAttribute(“cpe.com”,”cpe.com”); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
EOF

实验验证apache后端调度node1、node2,
1、mod_proxy_http使用模块mod_proxy、mod_proxy_http,负载均衡使用模块mod_proxy_balancer。

(1、编辑配置文件
# vim /etc/httpd/conf/httpd.conf
注释掉支持虚拟主机
# DocumentRoot “/var/www/html

(2、配置加载的mod
# vim /etc/httpd/conf.modules.d/00-proxy.conf
必须要加载以下三个模块
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so

(3、配置apache lb后端tomcat主机
编辑配置文件
# vim /etc/httpd/conf.d/virhost.conf
<proxy balancer://lbcluster1>
BalancerMember http://192.168.31.132:8080 loadfactor=10 route=TomcatA
BalancerMember http://192.168.31.133:8080 loadfactor=10 route=TomcatB
</proxy>

<VirtualHost *:80>
ServerName www.cpe.com ##虚拟主机名字
ProxyVia On ##添加代理header
ProxyRequests Off ##关闭正向代理,反向正向只能开一个
ProxyPreserveHost On ##保护requesturl,支持虚拟主机
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://lbcluster1/
ProxyPassReverse / balancer://lbcluster1/
<Location />
Require all granted
</Location>
</VirtualHost>

(4、配置dns
让dns发到前端apache上

(5、条件jvm-route
node1:
# vim /usr/local/tomcat/conf/server.xml
添加:
<Engine name=”Catalina” defaultHost=”localhost” jvmRoute=”TomcatA”>
node2:
# vim /usr/local/tomcat/conf/server.xml
添加:
<Engine name=”Catalina” defaultHost=”localhost” jvmRoute=”TomcatB”>

(6、session保持两种方案均可以
(((1、马哥未成功经过查询官网后:
<proxy balancer://lbcluster1>
BalancerMember http://192.168.31.132:8080 loadfactor=10 route=TomcatA
###tomcat的jvm-route需要添加
BalancerMember http://192.168.31.133:8080 loadfactor=10 route=TomcatB
###tomcat的jvm-route需要添加
ProxySet stickysession=JSESSIONID
</proxy>

<VirtualHost *:80>
ServerName www.cpe.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://lbcluster1/ stickysession=JSESSIONID
ProxyPassReverse / balancer://lbcluster1/
<Location />
Require all granted
</Location>
</VirtualHost>
(((2、马哥推荐方法经过测试正常
Header add Set-Cookie “ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/” env=BALANCER_ROUTE_CHANGED
<proxy balancer://lbcluster1>
BalancerMember http://192.168.31.132:8080 loadfactor=10 route=TomcatA
BalancerMember http://192.168.31.133:8080 loadfactor=10 route=TomcatB
ProxySet stickysession=ROUTEID
</proxy>

<VirtualHost *:80>
ServerName www.cpe.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://lbcluster1/
ProxyPassReverse / balancer://lbcluster1/
<Location />
Require all granted
</Location>
</VirtualHost>

2、mod_proxy_ajp使用模块mod_proxy、mod_proxy_ajp,负载均衡使用模块mod_proxy_balancer。(其它均一样)
配置1:
Header add Set-Cookie “ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/” env=BALANCER_ROUTE_CHANGED
<proxy balancer://lbcluster1>
BalancerMember ajp://192.168.31.132:8009 loadfactor=10 route=TomcatA
BalancerMember ajp://192.168.31.133:8009 loadfactor=10 route=TomcatB
ProxySet stickysession=ROUTEID
</proxy>

<VirtualHost *:80>
ServerName www.cpe.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://lbcluster1/
ProxyPassReverse / balancer://lbcluster1/
<Location />
Require all granted
</Location>
</VirtualHost>
或者配置2:
<proxy balancer://lbcluster1>
BalancerMember ajp://192.168.31.132:8009 loadfactor=10 route=TomcatA
###tomcat的jvm-route需要添加
BalancerMember ajp://192.168.31.133:8009 loadfactor=10 route=TomcatB
###tomcat的jvm-route需要添加
ProxySet stickysession=JSESSIONID
</proxy>

<VirtualHost *:80>
ServerName www.cpe.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://lbcluster1/ stickysession=JSESSIONID
ProxyPassReverse / balancer://lbcluster1/
<Location />
Require all granted
</Location>
</VirtualHost>
补充:mod_proxy_balancer模块内置的manager:
<Location /balancer-manager>
SetHandler balancer-manager
Proxypass !
Order Deny,Allow
Allow from all
</Location>
3、mod_jk(目前官方不建议,老构架有任然在使用的)

(1、编译mod_jk
# yum -y install httpd-devel
# yum -y groupinstall “Development Tools
# which apxs
/usr/bin/apxs
# wget http://archive.apache.org/dist/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.40-src.tar.gz
# tar xf tomcat-connectors-1.2.40-src.tar.gz
# cd tomcat-connectors-1.2.40-src/native/
# ./configure –with-apxs=/usr/bin/apxs
# make && make install
出现mod_jk.so就ok了
chmod 755 /usr/lib64/httpd/modules/mod_jk.so

(2、为了便于管理与mod_jk模块相关的配置,这里使用一个专门的配置文件/etc/httpd/extra/httpd-jk.conf来保存相关指令及其设置。
# mkdir -pv /etc/httpd/extra
# vim /etc/httpd/extra/httpd-jk.conf
# Load the mod_jk
LoadModule jk_module modules/mod_jk.so
JkWorkersFile /etc/httpd/extra/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel debug
JkMount /* lbcluster1
JkMount /status/ stat1

(3、在让apache读取mod_jk配置文件
# vim /etc/httpd/conf/httpd.conf
Include /etc/httpd/extra/httpd-jk.conf

(4、编辑mod_jk配置文件
# vim /etc/httpd/extra/workers.properties
worker.list = lbcluster1,stat1
worker.TomcatA.type = ajp13
worker.TomcatA.host = 192.168.31.132
worker.TomcatA.port = 8009
worker.TomcatA.lbfactor = 1
worker.TomcatB.type = ajp13
worker.TomcatB.host = 192.168.31.133
worker.TomcatB.port = 8009
worker.TomcatB.lbfactor = 1
worker.lbcluster1.type = lb
worker.lbcluster1.sticky_session = 0
worker.lbcluster1.balance_workers = TomcatA, TomcatB
worker.stat1.type = status

(5、对于status要做访问控制

4、会话管理:
标准会话管理器和持久会话管理器:只保存自己的,重启后完成加载,但是不加载别人的回话。

(1、标准会话管理器(StandardManager):
<Manager className=”org.apache.catalina.session.StandardManager”
maxInactiveInterval=”7200″/>
默认保存于$CATALINA_HOME/work/Catalina/<hostname>/<webapp-name>/下的SESSIONS.ser文件中。
maxActiveSessions:最多允许的活动会话数量,默认为-1,表示不限制;
maxInactiveInterval:非活动的会话超时时长,默认为60s;
pathname:会话文件的保存目录;

(2、持久会话管理器(PersistentManager):高可用
将会话数据保存至持久存储中,并且能在服务器意外中止后重新启动时重新加载这些会话信息。持久会话管理器支持将会话保存至文件存储(FileStore)或JDBC存储(JDBCStore)中。

(1、)保存至文件中的示例:
<Manager className=”org.apache.catalina.session.PersistentManager”
saveOnRestart=”true”>
<Store className=”org.apache.catalina.session.FileStore”
directory=”/data/tomcat-sessions”/>
</Manager>

每个用户的会话会被保存至directory指定的目录中的文件中,文件名为<session id>.session,并通过后台线程每隔一段时间(checkInterval参数定义,默认为60秒)检查一次超时会话。
(2、)保存至JDBCStore中的示例:
<Manager className=”org.apache.catalina.session.PersistentManager”
saveOnRestart=”true”>
<Store className=”org.apache.catalina.session.JDBCStore”
driverName=”com.mysql.jdbc.Driver”
connectionURL=”jdbc:mysql://localhost:3306/mydb?user=jb;password=pw”/>
</Manager>
(3、deltamanager tomcat session cluster:
以下内容定义在Engine容器中,则表示对所有主机均启动用集群功能。
如果定义在某Host中,则表示仅对此主机启用集群功能。
此外,需要注意的是,Receiver中的address=”auto”一项的值最好改为当前主机集群服务所对应的网络接口的IP地址。
要在Tomcat 8容器中运行会话复制,应完成以下步骤:
node1:

(1、)在配置文件中加入
# vim /usr/local/tomcat/conf/server.xml
<Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster”
channelSendOptions=”8″>

<Manager className=”org.apache.catalina.ha.session.DeltaManager”
expireSessionsOnShutdown=”false”
notifyListenersOnReplication=”true”/>

<Channel className=”org.apache.catalina.tribes.group.GroupChannel”>
<Membership className=”org.apache.catalina.tribes.membership.McastService”
address=”228.0.1.4″
port=”45564″
frequency=”500″
dropTime=”3000″/>
<Receiver className=”org.apache.catalina.tribes.transport.nio.NioReceiver”
address=”192.168.31.132″
port=”4000″
autoBind=”100″
selectorTimeout=”5000″
maxThreads=”6″/>

<Sender className=”org.apache.catalina.tribes.transport.ReplicationTransmitter”>
<Transport className=”org.apache.catalina.tribes.transport.nio.PooledParallelSender”/>
</Sender>
<Interceptor className=”org.apache.catalina.tribes.group.interceptors.TcpFailureDetector”/>
<Interceptor className=”org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor”/>
</Channel>

<Valve className=”org.apache.catalina.ha.tcp.ReplicationValve”
filter=””/>
<Valve className=”org.apache.catalina.ha.session.JvmRouteBinderValve”/>

<Deployer className=”org.apache.catalina.ha.deploy.FarmWarDeployer”
tempDir=”/tmp/war-temp/”
deployDir=”/tmp/war-deploy/”
watchDir=”/tmp/war-listen/”
watchEnabled=”false”/>

<ClusterListener className=”org.apache.catalina.ha.session.ClusterSessionListener”/>
</Cluster>

(2、)在web-app内加入
# vim /myweb/data/ROOT/WEB-INF/web.xml
<web-app>
<distributable/>
</web-app>

(3、)查看状态
# tail -50 /usr/local/tomcat/logs/catalina.out
07-Jul-2017 15:31:33.216 INFO [Membership-MemberAdded.] org.apache.catalina.ha.tcp.SimpleTcpCluster.memberAdded Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{192, 168, 31, 133}:4000,{192, 168, 31, 133},4000, alive=1026, securePort=-1, UDP Port=-1, id={-36 102 0 91 58 73 70 -71 -116 -40 -39 103 63 -20 -46 -114 }, payload={}, command={}, domain={}, ]

(4、)httpd前端配置
# vim /etc/httpd/conf.d/virhost.conf
<proxy balancer://lbcluster1>
BalancerMember ajp://192.168.31.132:8009 loadfactor=10 route=TomcatA
###tomcat的jvm-route需要添加
BalancerMember ajp://192.168.31.133:8009 loadfactor=10 route=TomcatB
###tomcat的jvm-route需要添加
# ProxySet stickysession=JSESSIONID
ProxySet lbmethod=bytraffic
</proxy>

<VirtualHost *:80>
ServerName www.cpe.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://lbcluster1/
ProxyPassReverse / balancer://lbcluster1/
<Location />
Require all granted
</Location>
<Location /balancer-manager>
SetHandler balancer-manager
Proxypass !
Order Deny,Allow
Allow from all
</Location>
</VirtualHost>

(3、Backupmanager

省略重点还是memcached

一直以来,我误解认为启动了n个tomcat,则Session需要同步复制到n个Tomcat中存在,因此在启动了6个以上的Tomcat,性能会大大下降。 而实际情况下,采取Apache 加Tomcat进行负载均衡集群的时候,是可以不用将Session复制到所有的节点里, 比如有六个Tomcat实例 Tomcat1,Tomcat2,Tomcat3,Tomcat4,Tomcat5,Tomcat6 是可以配置成 三组互相复制Session的群组, 比如Tomcat1和Tomcat2互相同步Session, 比如Tomcat3和Tomcat4互相同步Session, 比如Tomcat5和Tomcat6互相同步Session. 再在Apache的mod_jk模块里,对每个worker配置上redirect和activation属性。 将Tomcat1,Tomcat3,Tomcat5做为对外正常提供服务器的Tomcat, Tomcat2,Tomcat4,Tomcat6作为分别对应的灾难恢复的备份Tomcat. 即比如Tomcat1当机之后,Apache会自动将发给Tomcat1的请求转发到Tomcat2上, 而Tomcat2因为同步了Tomcat1的Session信息,因此从用户的角度,是感觉不出任何差异的。 单纯的Tomcat测试如下: Tomcat配置: Tomcat1. port=”15080″, jvmRoute=”tomcat1″, <Membership className=”org.apache.catalina.tribes.membership.McastService” address=”228.0.0.5″ port=”45564″ frequency=”500″ dropTime=”3000″/> Tomcat2. port=”16080″, jvmRoute=”tomcat2″, <Membership className=”org.apache.catalina.tribes.membership.McastService” address=”228.0.0.5″ port=”45564″ frequency=”500″ dropTime=”3000″/> Tomcat3. port=”17080″, jvmRoute=”tomcat3″, <Membership className=”org.apache.catalina.tribes.membership.McastService” address=”228.0.0.6″ port=”45564″ frequency=”500″ dropTime=”3000″/> Tomcat4. port=”18080″, jvmRoute=”tomcat4″, <Membership className=”org.apache.catalina.tribes.membership.McastService” address=”228.0.0.6″ port=”45564″ frequency=”500″ dropTime=”3000″/> Tomcat5. port=”19080″, jvmRoute=”tomcat5″, <Membership className=”org.apache.catalina.tribes.membership.McastService” address=”228.0.0.7″ port=”45564″ frequency=”500″ dropTime=”3000″/> Tomcat6. port=”20080″, jvmRoute=”tomcat6″, <Membership className=”org.apache.catalina.tribes.membership.McastService” address=”228.0.0.7″ port=”45564″ frequency=”500″ dropTime=”3000″/> 所有的Tomcat webapp的web.xml加上<distributable /> (例如D:\Java\Tomcat2\webapps\examples\WEB-INF\web.xml ,) 测试页面为: 第一组: http://localhost:15080/examples/servlets/servlet/SessionExample http://localhost:16080/examples/servlets/servlet/SessionExample 第二组: http://localhost:17080/examples/servlets/servlet/SessionExample http://localhost:18080/examples/servlets/servlet/SessionExample 第三组: http://localhost:19080/examples/servlets/servlet/SessionExample http://localhost:20080/examples/servlets/servlet/SessionExample 在每一组中,打开其中任何一个链接,然后设置属性值, 都可以在访问另外一个链接的时候得到。对应的sessionid的后缀会变成对应Tomcat的jvmRoute. (以上测试的tomcat均在同一台服务器上) 接下来再配置Apache的mod_jk. workers.properties的内容节选如下: (重点是redirect和activation两个属性) worker.tomcat1.port=15009 worker.tomcat1.host=127.0.0.1 worker.tomcat1.type=ajp13 worker.tomcat1.lbfactor=1 worker.tomcat1.redirect=tomcat2 worker.tomcat2.port=16009 worker.tomcat2.host=10.108.20.126 worker.tomcat2.type=ajp13 worker.tomcat2.lbfactor=1 worker.tomcat2.redirect=tomcat1 worker.tomcat2.activation=disabled 详细参考: http://tomcat.apache.org/connectors-doc/generic_howto/loadbalancers.html 备注:Tomcat6已经没有使用JGroups来实现集群复制, 而是使用Apache Tribes 来实现该效果的。 Apache Tribes的介绍在: http://tomcat.apache.org/tomcat-6.0-doc/tribes/introduction.html 为了简便配置,因此只使用一份Tomcat,使用不同的cofig来启动,配置好的文件在: http://618119.com/docs/Tomcat/TomcatCluster.zip 下载解压到Tomcat(例如D:\Java\apache-tomcat-6.0.14)目录里,运行对应的bat文件即可: start15080.bat start16080.bat start17080.bat start18080.bat start19080.bat start20080.bat
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值