Openresty 做静态资源服务器

94 篇文章 9 订阅
31 篇文章 3 订阅


1. 简介

官网:https://openresty.org/cn/

  OpenResty (又称 ngx_openresty) 是一个基于 NGINX 的可伸缩的 Web 平台,由中国人章亦春发起,提供了很多高质量的第三方模块。

  OpenResty 是一个强大的 Web 应用服务器,Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,更主要的是在性能方面,OpenResty 可以快速构造出足以胜任 10K 以上并发连接响应的超高性能 Web 应用系统。简单地说 OpenResty 的目标是让你的 Web 服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。

2. 源码编译安装

环境

centos 7.6
kernal 3.10.0-1062.el7.x86_64

安装依赖库

# 也可以下载指定版本依赖包编译安装,在编译 openresty 的时候指定依赖包参数
yum -y install readline-devel pcre-devel openssl-devel gcc gcc-c++ curl postgresql-devel

下载安装包https://openresty.org/cn/download.html

wget https://openresty.org/download/openresty-1.21.4.1.tar.gz

编译安装https://openresty.org/cn/installation.html

tar zxvf openresty-1.21.4.1.tar.gz
cd openresty-1.21.4.1/
./configure
make -j 4 && make install
ln -s /usr/local/openresty/nginx/sbin/nginx /usr/local/sbin/

# 写进 /etc/profile
cat >> /etc/profile << EOF
PATH=/usr/local/openresty/nginx/sbin:$PATH
export PATH
EOF
source /etc/profile

# 指定选项
./configure --prefix=/opt/openresty \
            --with-luajit \
            --without-http_redis2_module \
            --with-http_iconv_module \
            --with-http_postgres_module
  1. 默认情况下程序会被安装到 /usr/local/openresty 目录,可以使用 ./configure --help 查看更多的配置选项。
  2. 配置文件(./configure script)运行出错可以到 build/nginx-VERSION/objs/autoconf.err 找到。 VERSION 的地方必须与 OpenResty 版本号相对应。

3. 注册系统服务并启动

启动/停止 openresty

# 启动
/usr/local/openresty/nginx/sbin/nginx
/usr/local/openresty/nginx/sbin/nginx -c /usr/local/openresty/nginx/conf/nginx.conf
/usr/local/openresty/bin/openresty #是 nginx 的软连接
# 停止
/usr/local/openresty/nginx/sbin/nginx -s stop

关闭 openresty

ps -ef | grep nginx
kill -9 <PID>

设置 openresty 开机启动

cat > /lib/systemd/system/openresty.service << EOF
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/openresty/nginx/logs/nginx.pid
ExecStartPre=/usr/local/openresty/nginx/sbin/nginx -t
ExecStart=/usr/local/openresty/nginx/sbin/nginx
ExecReload=/usr/local/openresty/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
ExecStartPost=/bin/sleep 0.1
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF
systemctl enable openresty.service #设置开机自启动
systemctl start openresty.service #启动
systemctl stop openresty.service #关闭
systemctl restart openresty.service #重启
systemctl reload openresty.service #重新加载配置文件

conf/日志目录

/usr/local/openresty/nginx/conf/nginx.conf
/usr/local/openresty/nginx/logs/error.log
/usr/local/openresty/nginx/logs/access.log

访问:默认端口 80

[root@c7-1 ~]#curl 192.168.10.20
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<title>Welcome to OpenResty!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to OpenResty!</h1>
<p>If you see this page, the OpenResty web platform is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to our
<a href="https://openresty.org/">openresty.org</a> site<br/>
Commercial support is available at
<a href="https://openresty.com/">openresty.com</a>.</p>
<p>We have articles on troubleshooting issues like <a href="https://blog.openresty.com/en/lua-cpu-flame-graph/?src=wb">high CPU usage</a> and
<a href="https://blog.openresty.com/en/how-or-alloc-mem/">large memory usage</a> on <a href="https://blog.openresty.com/">our official blog site</a>.
<p><em>Thank you for flying <a href="https://openresty.org/">OpenResty</a>.</em></p>
</body>
</html>

4. 创建 Hello World 实例

OpenResty - Getting Started

我们创建一个临时的工作目录看看效果

pkill -9 nginx	# 先停止先前启动的 nginx
mkdir /home/www
cd /home/www
mkdir logs/ conf/	#logs 目录用于存放日志,conf 用于存放配置文件

在 conf 目录下创建一个 nginx.conf 文件

我们指定监听端口为 9000

worker_processes  1;
error_log /home/www/logs/error.log;
events {
    worker_connections 1024;
}
http {
    server {
        listen 9000;
        location / {
            default_type text/html;
            content_by_lua '
                ngx.say("<p>Hello, World!</p>")
            ';
        }
    }
}

启动 openresty

cd /home/www
/usr/local/openresty/nginx/sbin/nginx -p `pwd`/ -c conf/nginx.conf
# 如果没有任何输出,说明启动成功,-p 指定我们的项目目录,-c 指定配置文件

访问

[root@c7-1 ~]#curl http://localhost:9000/
<p>Hello, World!</p>

5. 使用 openresty 做静态资源服务器

5.1 修改 nginx.conf

vim /usr/local/openresty/nginx/conf/nginx.conf

......
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location /picture/ {
            root  /home/zc/;  #和上一句连在一起 /home/zc/picture/
            autoindex on;     #开启目录浏览
            autoindex_format html;    #以 html 风格将目录展示在浏览器中
            autoindex_exact_size off; #切换为 off 后,以可读的方式显示文件大小,单位为 KB、MB 或者 GB
            autoindex_localtime on;   #以服务器的文件时间作为显示的时间
        }

        location /doxc/ {
            root  /home/zc/;
            autoindex on;
            autoindex_format html;
            autoindex_exact_size off;
            autoindex_localtime on;
        }
......

5.2 创建目录,上传文件

[root@c7-1 ~]#tree /home/zc/
/home/zc/
├── doxc
│   └── data-center-visitor.doxc
└── picture
    └── 201051-1511352651ab09.jpg

2 directories, 2 files

5.3 访问图片

重启 openresty

systemctl daemon-reload
systemctl restart openresty

访问:http://192.168.10.20/picture/201051-1511352651ab09.jpg

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9aVsweGM-1657816691059)(C:\Users\15205\AppData\Roaming\Typora\typora-user-images\1657776301191.png)]

访问:http://192.168.10.20/doxc/data-center-visitor.doxc 即可下载文件。

6. 使用 openresty 做目录共享

6.1 修改 nginx.conf

创建示例目录

[root@c7-1 ~]#mkdir -p /opt/project/resource/images
[root@c7-1 ~]#cd /opt/project/resource/images
[root@c7-1 /opt/project/resource/images]#tree
.
├── doxc
└── picture

2 directories, 0 files

vim /usr/local/openresty/nginx/conf/nginx.conf

......
    server {
        listen       80;
        server_name  localhost;
        charset utf-8;
        #access_log  logs/host.access.log  main;

        # 图片读取路径
        location ^~ /images {
            default_type    ""; #默认类型,给浏览器解释
            root   /opt/project/resource;
            autoindex on;
            autoindex_exact_size off;
            autoindex_localtime on;
        }

        # 图片上传路径
        location ^~ /uploadfile {
            #lua脚本路径,脚本需要编写
            content_by_lua_file '/usr/local/openresty/lua/file/uploadfile.lua';
        }
        error_page  404              /404.html;


        location / {
            root   html;
            index  index.html index.htm;
        }
......

6.2 lua 脚本接收上传

创建 lua 目录

[root@c7-1 ~]#mkdir -p /usr/local/openresty/lua/file/

uploadfile.lua 脚本放到 /usr/local/openresty/lua/file,uploadfile.lua 脚本如下:

package.path = '/usr/local/openresty/lualib/resty/?.lua;'
local upload = require "upload"
 
local chunk_size = 4096
local form = upload:new(chunk_size)
local file
local filelen=0
form:set_timeout(0) -- 1 sec
local filename
 
-- 设置上传的根路径
local osfilepath = "/opt/project/resource/images/"
-- 获取文件名字
function get_filename(res)
    local filename = ngx.re.match(res,'(.+)filename="(.+)"(.*)')
    if filename then
        return filename[2]
    end
end
 
-- relname是相对路径文件名,创建不存在路径
function file_exists(relname)
        local path = osfilepath .. relname
        local abspath=string.match(path, "(.+)/[^/]*%.%w+$")
        testfile,errs = io.open(abspath,"rb")
        if not testfile then
                ngx.log(ngx.ERR,errs)
                local md="mkdir -p "
                local mdpath=md .. abspath
                ngx.log(ngx.ERR,"not exist! start mkdir "..abspath)
                os.execute(mdpath)
         else
                testfile:close()
        end
end
 
local i=0
-- 循环true 一直接收上传
while true do
    local typ, res, err = form:read()
    if not typ then
        ngx.say("failed to read: ", err)
        return
    end
    if typ == "header" then
        if res[1] ~= "Content-Type" then
            filename = get_filename(res[2])
            file_exists(filename)    -- 判断子文件夹是否存在,不存在创建
            if filename then
                i=i+1
                filepath = osfilepath .. filename
                -- 已只写方式打开
                file,err = io.open(filepath,"w")
                if not file then
                    ngx.say("failed to open file ")
                    ngx.log(ngx.ERR,err)
                    return
                end
            else
            end
        end
    elseif typ == "body" then
        if file then
            filelen= filelen + tonumber(string.len(res))
            file:write(res)
        else
        end
    elseif typ == "part_end" then
        if file then
            file:close()
            file = nil
            -- 上传成功,客户端判断是否成功
            ngx.say("upload-success")
        end
    elseif typ == "eof" then
        break
    else
    end
end
if i==0 then
    ngx.say("please upload at least one file!")
    return
end
[root@c7-1 /usr/local/openresty/lua/file]#ls
uploadfile.lua

6.3 重启 openresty

systemctl daemon-reload
systemctl restart openresty

浏览器访问

1657815997180

7. 制作 openresty 镜像

7.1 安装 docker

[root@c7-1 ~]#cat docker.sh 
#!/bin/bash

systemctl stop firewalld && systemctl disable firewalld
setenforce 0
yum -y install yum-utils device-mapper-persistemt-data lvm2
cd /etc/yum.repos.d/
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum -y install docker-ce
systemctl enable docker && systemctl start docker
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://4iv7219l.mirror.aliyuncs.com"]
}
EOF
cat >> /etc/sysctl.conf <<EOF
net.ipv4.ip_forward=1
EOF
sysctl -p
sudo systemctl daemon-reload
systemctl restart network
systemctl restart docker
systemctl status docker
curl http://49.232.8.65/shell/docker/docker.sh | bash

7.2 编写 Dockerfile

Dockerfile 详解

未优化的 Dockerfile

FROM centos:centos7
MAINTAINER zc
ENV TIME_ZOME=Asia/Shanghai
ENV OPENRESTY_VERSION=1.21.4.1
WORKDIR /usr/local/openresty
RUN yum -y install readline-devel pcre-devel openssl-devel zlib-devel gcc gcc-c++ perl make kernel-headers kernel-devel curl wget postgresql-devel net-tools vim lsof lrzsz tree && \
    wget https://openresty.org/download/openresty-1.21.4.1.tar.gz && \
    tar zxvf openresty-1.21.4.1.tar.gz && \
    cd openresty-1.21.4.1/ && \
    ./configure && \
    make -j 4 && make install && \
    ln -s /usr/local/openresty/nginx/sbin/nginx /usr/local/sbin/

ENV PATH=/usr/local/openresty/nginx/sbin:$PATH
ENV export PATH
VOLUME [/usr/local/openresty/nginx/conf/nginx.conf]
VOLUME [/usr/local/openresty/nginx/logs/access.log]
VOLUME [/usr/local/openresty/nginx/logs/error.log]
EXPOSE 80
EXPOSE 443
CMD ["/usr/local/openresty/nginx/sbin/nginx","-g","daemon off;"]

构建镜像

docker build -t openresty:1.21.4.1 .

运行访问

[root@master ~]#docker run -itd --name openresty_test -p 1567:80 openresty:1.21.4.1
1affb714f2a4d268e7278eb126f41214952d8a6beb8d6b6a821d729ffa78c10f
[root@master ~]#docker ps -a | head -n 2
CONTAINER ID   IMAGE                                               COMMAND                  CREATED          STATUS                  PORTS                                            NAMES
1affb714f2a4   openresty:1.21.4.1                                  "/usr/local/openrest…"   12 seconds ago   Up 11 seconds           443/tcp, 0.0.0.0:1567->80/tcp, :::1567->80/tcp   openresty_test
[root@master ~]#curl -I -s http://192.168.10.65:1567
HTTP/1.1 200 OK
Server: openresty/1.21.4.1
Date: Sun, 17 Jul 2022 16:17:49 GMT
Content-Type: text/html
Content-Length: 1097
Last-Modified: Sun, 17 Jul 2022 16:11:32 GMT
Connection: keep-alive
ETag: "62d434b4-449"
Accept-Ranges: bytes

7.3 Dockerfile 优化版一

[root@master /data]#ls
Dockerfile  openresty-1.21.4.1.tar.gz  start.sh
[root@master /data]#cat start.sh 
#!/bin/bash  
/usr/local/openresty/nginx/sbin/nginx
[root@master /data]#cat Dockerfile 
FROM centos:centos7
MAINTAINER zc
ENV TIME_ZOME=Asia/Shanghai
WORKDIR /usr/local/openresty
RUN yum -y install readline-devel pcre-devel openssl-devel zlib-devel gcc gcc-c++ perl make kernel-headers kernel-devel curl wget postgresql-devel &> /dev/null && \
    wget https://openresty.org/download/openresty-1.21.4.1.tar.gz &> /dev/null && \
    tar zxvf openresty-1.21.4.1.tar.gz &> /dev/null && \
    cd openresty-1.21.4.1/ &> /dev/null && \
    ./configure &> /dev/null && \
    make -j 4 &> /dev/null && make install &> /dev/null && \
    ln -s /usr/local/openresty/nginx/sbin/nginx /usr/local/sbin/ &> /dev/null

ENV PATH=/usr/local/openresty/nginx/sbin:$PATH
ENV export PATH
EXPOSE 80
VOLUME [/usr/local/openresty/nginx/conf/nginx.conf]
VOLUME [/usr/local/openresty/nginx/logs/access.log]
VOLUME [/usr/local/openresty/nginx/logs/error.log]
RUN  echo "daemon off;">>/usr/local/openresty/nginx/conf/nginx.conf
workdir /
ADD start.sh /start.sh
RUN chmod 755 /start.sh
CMD ["/start.sh"]
[root@master /data]#docker build -t openresty:20220718 .
......
[root@master /data]#docker images
REPOSITORY                                                        TAG        IMAGE ID       CREATED          SIZE
openresty                                                         20220718   9e82b0df5e02   18 minutes ago   779MB
......
[root@master /data]#docker run -itd --name openresty_test-01 -p 2000:80 openresty:20220718
......

进入容器修改配置文件

[root@master /data]#docker exec -it bcb0bcef66df bash
[root@bcb0bcef66df conf]# cat /usr/local/openresty/nginx/conf/nginx.conf | grep -v '#' | tr -s '\n'

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        location /picture/ {
            root  /home/zc/;
            autoindex on;
            autoindex_format html;
            autoindex_exact_size off;
            autoindex_localtime on;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
daemon off;

[root@bcb0bcef66df conf]# nginx -t
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful

退出容器,重启 container

[root@master /data]#docker restart bcb0bcef66df

浏览器访问

1658139953336

7.4 docker 挂载目录

拷贝容器的挂载文件

docker cp openresty_test-01:/usr/local/openresty/nginx/conf/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
docker cp openresty_test-01:/usr/local/openresty/nginx/logs/error.log /usr/local/openresty/nginx/logs/error.log
docker cp openresty_test-01:/usr/local/openresty/nginx/logs/access.log /usr/local/openresty/nginx/logs/access.log

删除临时 nginx

[root@master ~]#docker ps -a | head -n 3
CONTAINER ID   IMAGE                                               COMMAND                  CREATED       STATUS                  PORTS                                            NAMES
bcb0bcef66df   openresty:20220718                                  "/start.sh"              3 hours ago   Up 3 hours              0.0.0.0:2000->80/tcp, :::2000->80/tcp            openresty_test-01
3c734319883d   openresty:1.21.4.1                                  "/usr/local/openrest…"   4 hours ago   Up 4 hours              443/tcp, 0.0.0.0:1567->80/tcp, :::1567->80/tcp   openresty_test
[root@master ~]#docker rm -f bcb0bcef66df
bcb0bcef66df
[root@master ~]#docker ps -a | head -n 3
CONTAINER ID   IMAGE                                               COMMAND                  CREATED       STATUS                  PORTS                                            NAMES
3c734319883d   openresty:1.21.4.1                                  "/usr/local/openrest…"   4 hours ago   Up 4 hours              443/tcp, 0.0.0.0:1567->80/tcp, :::1567->80/tcp   openresty_test
bfde437639a1   8522d622299c                                        "/opt/bin/flanneld -…"   3 days ago    Up 3 days                                                                k8s_kube-flannel_kube-flannel-ds-7d9mh_kube-system_3fc2c4bd-32b4-49ac-82e0-392828f13034_9

创建挂载 nginx

docker run -itd --name openresty_test-01 -p 2000:80 \
-v /usr/local/openresty/nginx/conf/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf \
-v /usr/local/openresty/nginx/logs/error.log:/usr/local/openresty/nginx/logs/error.log \
-v /usr/local/openresty/nginx/logs/access.log:/usr/local/openresty/nginx/logs/access.log \
openresty:20220718
# 还可挂载 /usr/local/openresty/nginx/html/index.html

运行查看

[root@master ~]#docker run -itd --name openresty_test-01 -p 2000:80 \
> -v /usr/local/openresty/nginx/conf/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf \
> -v /usr/local/openresty/nginx/logs/error.log:/usr/local/openresty/nginx/logs/error.log \
> -v /usr/local/openresty/nginx/logs/access.log:/usr/local/openresty/nginx/logs/access.log \
> openresty:20220718
da9a036b771e48eb877295f2f935f2465e9b8d3b4a0b9f5b8ead0622c696c725
[root@master ~]#docker ps -a | head -n 3
CONTAINER ID   IMAGE                                               COMMAND                  CREATED         STATUS                  PORTS                                            NAMES
da9a036b771e   openresty:20220718                                  "/start.sh"              7 seconds ago   Up 6 seconds            0.0.0.0:2000->80/tcp, :::2000->80/tcp            openresty_test-01
3c734319883d   openresty:1.21.4.1                                  "/usr/local/openrest…"   4 hours ago     Up 4 hours              443/tcp, 0.0.0.0:1567->80/tcp, :::1567->80/tcp   openresty_test
[root@master ~]#docker exec -it da9a036b771e bash
[root@da9a036b771e /]# tail -f /usr/local/openresty/nginx/logs/access.log 
......

重新加载 nginx

docker exec -it da9a036b771e nginx -s reload	# 如果容器有做软连接的话

7.5 查看容器消耗的资源

[root@master ~]#docker stats
CONTAINER ID   NAME                                                                                                        CPU %     MEM USAGE / LIMIT     MEM %     NET I/O        BLOCK I/O        PIDS
da9a036b771e   openresty_test-01                                                                                           0.00%     2.363MiB / 5.651GiB   0.04%     656B / 0B      0B / 0B          3
3c734319883d   openresty_test                                                                                              0.00%     1.949MiB / 5.651GiB   0.03%     1.9kB / 630B   0B / 0B  
......

8. K8S 运行 openresty Pod

docker 运行的 pod 是无法被 k8s 所识别的

# 运行前确保调度节点有指定镜像
[root@master ~]#kubectl create deployment openresty-v1 --image=openresty:20220718 --port=80 --replicas=2
deployment.apps/openresty-v1 created
[root@master ~]#kubectl get pods,svc -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
pod/openresty-v1-5998cb6f64-8w5rv   1/1     Running   0          8s    10.244.2.6   node02   <none>           <none>
pod/openresty-v1-5998cb6f64-mckl6   1/1     Running   0          8s    10.244.1.5   node01   <none>           <none>

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   9d    <none>

暴露服务

[root@master ~]#kubectl expose deployment openresty-v1 --port=2100 --target-port=80 --name=openresty-service --type=NodePort
service/openresty-service exposed
[root@master ~]#kubectl get pods,svc -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
pod/openresty-v1-5998cb6f64-8w5rv   1/1     Running   0          2m18s   10.244.2.6   node02   <none>           <none>
pod/openresty-v1-5998cb6f64-mckl6   1/1     Running   0          2m18s   10.244.1.5   node01   <none>           <none>

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE   SELECTOR
service/kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP          9d    <none>
service/openresty-service   NodePort    10.103.182.215   <none>        2100:30064/TCP   5s    app=openresty-v1

访问

[root@master ~]#curl -s -I http://192.168.10.65:30064
HTTP/1.1 200 OK
Server: openresty/1.21.4.1
Date: Mon, 18 Jul 2022 14:37:03 GMT
Content-Type: text/html
Content-Length: 1097
Last-Modified: Mon, 18 Jul 2022 09:54:41 GMT
Connection: keep-alive
ETag: "62d52de1-449"
Accept-Ranges: bytes

Linux 下编译安装 OpenResty

openresty 做静态资源服务器(接收图片上传)



  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值