阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Varnish+Nginx实现单双Web服务器缓存

124次阅读
没有评论

共计 14241 个字符,预计需要花费 36 分钟才能阅读完成。

实验目的:

varnish 利用实现对后端单双静态 web 服务器的缓存

varnish 包的下载路径:http://repo.varnish-cache.org/redhat/varnish-3.0/el6 可以下载到 varnish 的 rpm 包

需要下载的有:

varnish-3.0.5-1.el6.x86_64

varnish-docs-3.0.5-1.el6.x86_64

varnish-libs-3.0.5-1.el6.x86_64

varnish 的官网地址:https://www.varnish-cache.org/

实验环境:

web1:172.16.18.3            Nginx

web2:172.16.17.12          Nginx

varnish:172.16.18.1        Varnish

实验内容:

一,安装 varnish 包,配置 web 服务器

[root@node1~]# rpm -ql varnish   

/etc/rc.d/init.d/varnish              #varnish 的启动程序   

/etc/rc.d/init.d/varnishlog          #日志   

/etc/rc.d/init.d/varnishncsa          #日志   

/etc/sysconfig/varnish                #配置文件,varnish 定义自身属性   

/etc/varnish                          #配置文件目录   

/etc/varnish/default.vcl              #默认配置文件,定义后端节点的   

/usr/bin/varnish_reload_vcl          #加载 vcl,

/usr/bin/varnishadm                  #客户端程序   

/usr/bin/varnishstat                  #状态监控

二,编辑配置文件

[root@node1 ~]# vim /etc/sysconfig/varnish

NFILES=131072

MEMLOCK=82000

NPROCS=”unlimited”

RELOAD_VCL=1                                                        #是否重载 VCL 文件

## Alternative 3, Advanced configuration

VARNISH_VCL_CONF=/etc/varnish/default.vcl              #vcl 文件路径

VARNISH_LISTEN_PORT=80                                    #varnish 自己工作于那个端口。默认是 6081

VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1      #管理接口

VARNISH_ADMIN_LISTEN_PORT=6082                    #管理接口监听端口

VARNISH_SECRET_FILE=/etc/varnish/secret                #密钥文件

VARNISH_MIN_THREADS=50                                    #最少空闲线程

VARNISH_MAX_THREADS=1000                                #最多启动线程

VARNISH_THREAD_TIMEOUT=120                            #work 超时时长

#VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin        #存储文件

VARNISH_STORAGE_SIZE=64M                                                    #存储文件文件大小

#VARNISH_STORAGE=”file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}”    #存储方式 file

VARNISH_STORAGE=”malloc,${VARNISH_STORAGE_SIZE}”    #基于内存方式

VARNISH_TTL=120

DAEMON_OPTS=”-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \

            -f ${VARNISH_VCL_CONF} \

            -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \

            -t ${VARNISH_TTL} \

            -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \

            -u varnish -g varnish \

            -S ${VARNISH_SECRET_FILE} \

            -s ${VARNISH_STORAGE}”

[root@node1 ~]# vim /etc/varnish/default.vcl

backend default {

  .host = “172.16.18.3”;

  .port = “80”;

}

此时 varnish 就已经可以启动了。下来就是最重要的编写 vcl 文件。

————————————————————

Varnish Cache 的架构笔记 http://www.linuxidc.com/Linux/2013-10/91016.htm

CentOS 5.8 下 Varnish-2.1.5 的安装配置 http://www.linuxidc.com/Linux/2013-09/89916.htm

RedHat 脚本改用 CentOS 源更新安装 Nginx、PHP 5.3、Varnish http://www.linuxidc.com/Linux/2012-07/65801.htm

利用 Varnish 构建 Cache 服务器笔记 http://www.linuxidc.com/Linux/2012-07/65234.htm

缓存服务 Varnish 安装配置 http://www.linuxidc.com/Linux/2012-07/65228.htm

Varnish 编译安装所需准备 http://www.linuxidc.com/Linux/2012-07/65230.htm

Linux 下 Varnish 缓存的配置优化 http://www.linuxidc.com/Linux/2012-03/56435.htm

Varnish 基础概念详解 http://www.linuxidc.com/Linux/2014-07/104535.htm

———————————————————————————–

那么我们就应该熟悉这张表,每一个状态引擎所对应的变量

Varnish+Nginx 实现单双 Web 服务器缓存

简单介绍一下 vcl 的语法

VCL 的设计参考了 C 和 Perl 语言,因此,对有着 C 或 Perl 编程经验者来说,其非常易于理解。其基本语法说明如下:

(1)//、# 或 /* comment */ 用于注释

(2)sub $name 定义函数

(3)不支持循环,有内置变量

(4)使用终止语句,没有返回值

(5)域专用

(6)操作符:=(赋值)、==(等值比较)、~(模式匹配)、!(取反)、&&(逻辑与)、||(逻辑或)

编译 vcl 文件中状态引擎的顺序我们按照默认配置文件的顺序来,此顺序也符合请求处理的基本顺序,当然,为了配合实验也会有些改动。我们来看一张图,可以明确的明白请求的过程:

Varnish+Nginx 实现单双 Web 服务器缓存

1,首先我们来编写 vcl_recv 段,

vcl_recv 作为进入 varnish 对请求报文解码后第一个子例程,可以在此处做访问控制,是否查询缓存,以及无法识别的数据的判定。

首先对 default.vcl 文件复制一份重新改名为 test1.vcl

acl purgers {#定义一个 acl

“127.0.0.1”;

“172.16.0.0”/16;

}

sub vcl_recv {

    if (req.url ~ “^/test.html$”) {#请求首部的 url 匹配到 test.html,

                return(pass);                      #跳过缓存

        }

    if

    if (req.request != “GET” &&            #请求方法不是已知的这 7 中则发到 pipe 上去

      req.request != “HEAD” &&

      req.request != “PUT” &&

      req.request != “POST” &&

      req.request != “TRACE” &&

      req.request != “OPTIONS” &&

      req.request != “DELETE”) {

      return (pipe);

      }

    if (req.request != “GET” && req.request != “HEAD”) {#不是获取资源的全部跳过缓存,减少无用缓存查询

      return (pass);

    }

    if (req.request == “PURGE”) {

        if (!client.ip ~ purgers) {#请求 IP 不在 ACL 中定义,则发挥 405 错误页。

            error 405 “Method not allowed”;

          }

        return (lookup);

    }

    return (lookup);

}

那么此时如何加载这个 test1 让他生效呢?

第一修改配置文件。

第二,利用 varnishadm 客户端工具。

varnishadm

[root@node1 ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082        #进入到管理工具   
200     
—————————–   
Varnish Cache CLI 1.0   
—————————–   
Linux,2.6.32-431.el6.x86_64,x86_64,-sfile,-smalloc,-hcritbit   
varnish-3.0.5 revision 1a89b1f   
Type ‘help’ for command list.   
Type ‘quit’ to close CLI session.   
varnish> vcl.load test1 test1.vcl                                                                    #加载 vcl 文件

200

VCL compiled.

varnish> vcl.list

200

active 2 boot

available 0 test1

varnish> vcl.use test1

200

varnish> vcl.list

200

available 2 boot

active 0 test1

这样就设定成功了。

为了显示效果我们来配置一下 deliver 段,给客户端返回时候匹配到缓存信息,以便我我们来查看实验结果。

sub vcl_deliver {

        if (obj.hits > 0) {#判断条件缓存匹配次数���于 0

                set resp.http.X-Cache = “HIT via” + ” ” + server.hostname;    #添加 HIT via

        } else {

                set resp.http.X-Cache = “MISS via” + ” ” + server.hostname;  #没有匹配到则添加 MISS via

        }

}

访问缓存 172.16.18.1. 第一次是 miss via 之后的访问在缓存有效期内都是 HIT via

Varnish+Nginx 实现单双 Web 服务器缓存

当访问 test.html 是会被 vcl_recv 定义的 pass 匹配到,直接跳过缓存,所以 X -cache 状态一直是 MISS via

Varnish+Nginx 实现单双 Web 服务器缓存

2,编辑 vcl_hash,自定义 hash 生成时的数据来源。

sub vcl_hash {

  hash_data(req.url);                  #依据 req.url 来匹配

if (req.http.host) {

  hash_data(req.http.host);          #请求首部的 host 来缓存

  } else {

  hash_data(server.ip);

  }

  return (hash);

}

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2014-09/107268p2.htm

3,编辑 vcl_hit, 从缓存中查找到缓存对象时要执行的操作

sub vcl_hit {

    if(req.request == “PURGE”){#当进入缓存后清理缓存对象,返回 Purged;

        purge;

        error 200 “Purged”;

        }

}

非 pipe 请求必经过 hit,miss,pass,这三条任意一条,所以也要在其他两路做 purge 匹配。

4,vcl_miss , 从缓存中查找不到缓存对象时要执行的操作;

sub vcl_miss {

    if (req.request == “PURGE”) {如果直接不经过缓存,匹配到了 PURGE,则返回 404 说没有进入缓存,否则发往 fetch

        error 404 “Not in cache”;

}

    return (fetch);

}

5,vcl_pass,用于将请求直接传递至后端主机

vcl_pass {

if (req.request == “PURGE”) {#如果直接是 pass, 跳过缓存,且匹配到 PURGE,

    error 502 “PURGE on a passed object”; 

}

    return (pass);

}

6,vcl_fetch, 是在请求从后端被成功接收后调用的,可以使用 req,bereq,beresp.

可在此处定义 cache 的缓存有效时长

sub vcl_fetch {

    set beresp.ttl = 360s;                            #修改缓存时长为 360s,

    if (req.url ~ “.[jpg|gif|png]$”){#图片文件缓存时长 1h

        set beresp.ttl = 1h;

    }

    if (beresp.status != 200){#backend 返回状态码不是 200, 则不缓存数据

        return (hit_for_pass);

    }

    return (deliver);

}

6,sub vcl_deliver , 将用户请求的内容响应给客户端时用到的方法;deliver, 在 recv 之后我们就用过,在里边添加了一个相应给用户的 X -cache, 是否用到了缓存。复制下来!完善一下!

sub vcl_deliver {

        if (obj.hits > 0) {

                set resp.http.X-Cache = “HIT via” + ” ” + server.hostname; 

        } else {

                set resp.http.X-Cache = “MISS via” + ” ” + server.hostname; 

        }

        set resp.http.host = server.hostname;

        retuen (deliver);

}

7,sub vcl_pipe {

    return (pipe);

}

到此一个简单的 vcl 功能就写好了。

先请求一下 curl -X PURGE http://172.16.18.1/index.html

[root@node3 html]# curl -X PURGE http://172.16.18.1/index.html   
<html>   
<head><title>405 Not Allowed</title></head>            #发现和我们定义的 Method not allowed 不一样,那是为什么呢?

<body bgcolor=”white”>   
<center><h1>405 Not Allowed</h1></center>   
<hr><center>nginx/1.6.2</center>   
</body>   
</html>

经过查看 vcl_recv 段发现,我们在 PURGE 之上就将不是定义的方法送到了 pipe. 无法到达 PURGE. 修改如下。将 PURGE 写在方法判断之前

sub vcl_recv {

    if (req.url ~ “^/test.html$”) {

                return(pass);                   

        }

    if (req.request == “PURGE”) {

        if (!client.ip ~ purgers) {

            error 405 “Method not allowed”;

          }

        return (lookup);

    }

    if (req.request != “GET” &&                     

      req.request != “HEAD” &&

      req.request != “PUT” &&

      req.request != “POST” &&

      req.request != “TRACE” &&

      req.request != “OPTIONS” &&

      req.request != “DELETE”) {

      return (pipe);

      }

    if (req.request != “GET” && req.request != “HEAD”) {

      return (pass);

    }

    return (lookup);

}

[root@node3 html]# curl -X PURGE http://172.16.18.1/index.html   
<?xml version=”1.0″ encoding=”utf-8″?>   
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”   
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>   
<html>   
<head>   
<title>404 Not in cache</title>   
</head>   
<body>   
<h1>Error 404 Not in cache</h1>   

Not in cache

<h3>Guru Meditation:</h3>   

XID: 506876240

<hr>   

Varnish cache server

</body>   
</html>

这下和我们定义的一样的,看来还得注意判断的先后次序。

下边我们来定义一下有 cookie 的文件走向。

首先在 vcl_resv 添加

if (!(req.url ~ “wp-(login|admin)”)) {#所有有 cookie 的请求都不查缓存

    unset req.http.cookie;

  }

在 vcl_fetch 中定义抹除 cookie         

sub vcl_fetch {

  if (!(req.url ~ “wp-(login|admin)”)) {

      unset beresp.http.Set-Cookie;

  }

}

三,后端主机的健康检测

backend web1 {

    .host = “172.16.18.3”;

    .port = “80”;

    .probe = {

        .url = “/index.html”;            #探测什么文件

        .interval = 1s;                    #几秒探测一次

        .window = 5;                      #失败探测多少次

        .threshold = 2;                  #成功探测多少次

}

}

在 varnishadm 中查看

varnish> backend.list

200

Backend name Refs Admin Probe

default(172.16.18.3,,80) 8 probe Healthy 5/5     

四,varnish 使用多台后端主机

Varnish 中可以使用 director 指令将一个或多个近似的后端主机定义为一个逻辑组,并可以指定的调度方式 (也叫挑选方法) 来轮流将请求发送至这些主机上。不同的 director 可以使用同一个后端主机,而某 director 也可以使用“匿名”后端主机(在 director 中直接进行定义)。每个 director 都必须有其专用名,且在定义后必须在 VCL 中进行调用,VCL 中任何可以指定后端主机的位置均可以按需将其替换为调用某已定义的 director。

注意:当使用自定义的主机时一定要在 vcl_recv 中指定使用哪个主机,

backend web1 {

    .host = “172.16.18.3”;

    .port = “80”;

    .probe = {

        .url = “/index.html”;         

        .interval = 1s;                 

        .window = 5;                   

        .threshold = 2;               

}

backend web2 {

    .host = “172.16.18.3”;

    .port = “80”;

    .probe = {

        .url = “/index.html”;         

        .interval = 1s;   

.window = 5;

        .threshold = 2;               

}

director webservers round-robin {

  {.backend = web1;}

  {.backend = web2;}

}

vcl_recv {添加下边段落

set req.backend = webservers;                        放在最前边   
}

}

下来访问 172.16.18.1 验证有没有将请求在两个 web 服务器上轮询,

Varnish+Nginx 实现单双 Web 服务器缓存

Varnish+Nginx 实现单双 Web 服务器缓存

可以看到请求的 test.html 是轮询的,为什么不请求 172.16.18.1 呢,应为 172.16.18.1 有缓存,看不到效果。

varnish 的实验就到此了。

Varnish 的详细介绍:请点这里
Varnish 的下载地址:请点这里

实验目的:

varnish 利用实现对后端单双静态 web 服务器的缓存

varnish 包的下载路径:http://repo.varnish-cache.org/redhat/varnish-3.0/el6 可以下载到 varnish 的 rpm 包

需要下载的有:

varnish-3.0.5-1.el6.x86_64

varnish-docs-3.0.5-1.el6.x86_64

varnish-libs-3.0.5-1.el6.x86_64

varnish 的官网地址:https://www.varnish-cache.org/

实验环境:

web1:172.16.18.3            Nginx

web2:172.16.17.12          Nginx

varnish:172.16.18.1        Varnish

实验内容:

一,安装 varnish 包,配置 web 服务器

[root@node1~]# rpm -ql varnish   

/etc/rc.d/init.d/varnish              #varnish 的启动程序   

/etc/rc.d/init.d/varnishlog          #日志   

/etc/rc.d/init.d/varnishncsa          #日志   

/etc/sysconfig/varnish                #配置文件,varnish 定义自身属性   

/etc/varnish                          #配置文件目录   

/etc/varnish/default.vcl              #默认配置文件,定义后端节点的   

/usr/bin/varnish_reload_vcl          #加载 vcl,

/usr/bin/varnishadm                  #客户端程序   

/usr/bin/varnishstat                  #状态监控

二,编辑配置文件

[root@node1 ~]# vim /etc/sysconfig/varnish

NFILES=131072

MEMLOCK=82000

NPROCS=”unlimited”

RELOAD_VCL=1                                                        #是否重载 VCL 文件

## Alternative 3, Advanced configuration

VARNISH_VCL_CONF=/etc/varnish/default.vcl              #vcl 文件路径

VARNISH_LISTEN_PORT=80                                    #varnish 自己工作于那个端口。默认是 6081

VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1      #管理接口

VARNISH_ADMIN_LISTEN_PORT=6082                    #管理接口监听端口

VARNISH_SECRET_FILE=/etc/varnish/secret                #密钥文件

VARNISH_MIN_THREADS=50                                    #最少空闲线程

VARNISH_MAX_THREADS=1000                                #最多启动线程

VARNISH_THREAD_TIMEOUT=120                            #work 超时时长

#VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin        #存储文件

VARNISH_STORAGE_SIZE=64M                                                    #存储文件文件大小

#VARNISH_STORAGE=”file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}”    #存储方式 file

VARNISH_STORAGE=”malloc,${VARNISH_STORAGE_SIZE}”    #基于内存方式

VARNISH_TTL=120

DAEMON_OPTS=”-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \

            -f ${VARNISH_VCL_CONF} \

            -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \

            -t ${VARNISH_TTL} \

            -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \

            -u varnish -g varnish \

            -S ${VARNISH_SECRET_FILE} \

            -s ${VARNISH_STORAGE}”

[root@node1 ~]# vim /etc/varnish/default.vcl

backend default {

  .host = “172.16.18.3”;

  .port = “80”;

}

此时 varnish 就已经可以启动了。下来就是最重要的编写 vcl 文件。

————————————————————

Varnish Cache 的架构笔记 http://www.linuxidc.com/Linux/2013-10/91016.htm

CentOS 5.8 下 Varnish-2.1.5 的安装配置 http://www.linuxidc.com/Linux/2013-09/89916.htm

RedHat 脚本改用 CentOS 源更新安装 Nginx、PHP 5.3、Varnish http://www.linuxidc.com/Linux/2012-07/65801.htm

利用 Varnish 构建 Cache 服务器笔记 http://www.linuxidc.com/Linux/2012-07/65234.htm

缓存服务 Varnish 安装配置 http://www.linuxidc.com/Linux/2012-07/65228.htm

Varnish 编译安装所需准备 http://www.linuxidc.com/Linux/2012-07/65230.htm

Linux 下 Varnish 缓存的配置优化 http://www.linuxidc.com/Linux/2012-03/56435.htm

Varnish 基础概念详解 http://www.linuxidc.com/Linux/2014-07/104535.htm

———————————————————————————–

那么我们就应该熟悉这张表,每一个状态引擎所对应的变量

Varnish+Nginx 实现单双 Web 服务器缓存

简单介绍一下 vcl 的语法

VCL 的设计参考了 C 和 Perl 语言,因此,对有着 C 或 Perl 编程经验者来说,其非常易于理解。其基本语法说明如下:

(1)//、# 或 /* comment */ 用于注释

(2)sub $name 定义函数

(3)不支持循环,有内置变量

(4)使用终止语句,没有返回值

(5)域专用

(6)操作符:=(赋值)、==(等值比较)、~(模式匹配)、!(取反)、&&(逻辑与)、||(逻辑或)

编译 vcl 文件中状态引擎的顺序我们按照默认配置文件的顺序来,此顺序也符合请求处理的基本顺序,当然,为了配合实验也会有些改动。我们来看一张图,可以明确的明白请求的过程:

Varnish+Nginx 实现单双 Web 服务器缓存

1,首先我们来编写 vcl_recv 段,

vcl_recv 作为进入 varnish 对请求报文解码后第一个子例程,可以在此处做访问控制,是否查询缓存,以及无法识别的数据的判定。

首先对 default.vcl 文件复制一份重新改名为 test1.vcl

acl purgers {#定义一个 acl

“127.0.0.1”;

“172.16.0.0”/16;

}

sub vcl_recv {

    if (req.url ~ “^/test.html$”) {#请求首部的 url 匹配到 test.html,

                return(pass);                      #跳过缓存

        }

    if

    if (req.request != “GET” &&            #请求方法不是已知的这 7 中则发到 pipe 上去

      req.request != “HEAD” &&

      req.request != “PUT” &&

      req.request != “POST” &&

      req.request != “TRACE” &&

      req.request != “OPTIONS” &&

      req.request != “DELETE”) {

      return (pipe);

      }

    if (req.request != “GET” && req.request != “HEAD”) {#不是获取资源的全部跳过缓存,减少无用缓存查询

      return (pass);

    }

    if (req.request == “PURGE”) {

        if (!client.ip ~ purgers) {#请求 IP 不在 ACL 中定义,则发挥 405 错误页。

            error 405 “Method not allowed”;

          }

        return (lookup);

    }

    return (lookup);

}

那么此时如何加载这个 test1 让他生效呢?

第一修改配置文件。

第二,利用 varnishadm 客户端工具。

varnishadm

[root@node1 ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082        #进入到管理工具   
200     
—————————–   
Varnish Cache CLI 1.0   
—————————–   
Linux,2.6.32-431.el6.x86_64,x86_64,-sfile,-smalloc,-hcritbit   
varnish-3.0.5 revision 1a89b1f   
Type ‘help’ for command list.   
Type ‘quit’ to close CLI session.   
varnish> vcl.load test1 test1.vcl                                                                    #加载 vcl 文件

200

VCL compiled.

varnish> vcl.list

200

active 2 boot

available 0 test1

varnish> vcl.use test1

200

varnish> vcl.list

200

available 2 boot

active 0 test1

这样就设定成功了。

为了显示效果我们来配置一下 deliver 段,给客户端返回时候匹配到缓存信息,以便我我们来查看实验结果。

sub vcl_deliver {

        if (obj.hits > 0) {#判断条件缓存匹配次数���于 0

                set resp.http.X-Cache = “HIT via” + ” ” + server.hostname;    #添加 HIT via

        } else {

                set resp.http.X-Cache = “MISS via” + ” ” + server.hostname;  #没有匹配到则添加 MISS via

        }

}

访问缓存 172.16.18.1. 第一次是 miss via 之后的访问在缓存有效期内都是 HIT via

Varnish+Nginx 实现单双 Web 服务器缓存

当访问 test.html 是会被 vcl_recv 定义的 pass 匹配到,直接跳过缓存,所以 X -cache 状态一直是 MISS via

Varnish+Nginx 实现单双 Web 服务器缓存

2,编辑 vcl_hash,自定义 hash 生成时的数据来源。

sub vcl_hash {

  hash_data(req.url);                  #依据 req.url 来匹配

if (req.http.host) {

  hash_data(req.http.host);          #请求首部的 host 来缓存

  } else {

  hash_data(server.ip);

  }

  return (hash);

}

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2014-09/107268p2.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计14241字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中