CDN的多语言缓存机制

背景信息

CDN默认支持多副本缓存,本文以源站为nginx为例,介绍如何根据客户端请求的语言(Accept-Language 请求头)缓存多个版本的资源。

配置流程

源站服务器配置

  1. 在源站服务器上准备多语言版本的文件。以中文和英文为例,在 Nginx 服务目录下创建 index-cn.html 和 index-en.html 两个文件。无需创建 index.html

  2. 在 Nginx 配置文件中增加逻辑判断。CDN 的多副本缓存机制依赖于源站的响应,因此区分不同语言版本的逻辑需要在源站上实现。以下为示例代码:

    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;
    events {
        worker_connections 1024;
    }
    http {
        log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_accept_language"';
        access_log /var/log/nginx/access.log main;
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        include /etc/nginx/mime.types;
        default_type application/octet-stream;
        
        #根据客户端请求头中的 Accept-Language 字段匹配语言偏好
        map $http_accept_language $preferred_lang {
            default "cn";
            ~*\ben\b "en";  # 精确匹配 en
            ~*\bzh\b "cn";  # 精确匹配 zh
            ~*en "en";      # 模糊匹配 en
            ~*zh "cn";      # 模糊匹配 zh
        }
        server {
            listen 80;
            server_name xxxxxxxxxxxx;
            root /var/www/html;  # 改成真实路径
            charset utf-8;
            # 所有对 / 的请求都重写到 index.html(触发语言选择)
            location = / {
                return 302 /index.html;
            }
            # 核心:处理 /index.html 请求
            location = /index.html {
                # 根据 map 结果选择文件
                set $lang_file "index-${preferred_lang}.html";
                try_files /$lang_file =404;
                add_header Vary "Accept-Language" always;
            }
            # 其他静态资源
            location / {
                try_files $uri $uri/ =404;
            }
        }
    }

    关键代码说明:

    map $http_accept_language $preferred_lang {
            default "cn";
            ~*en "en";
            ~*zh "cn";
            ~*\ben\b "en";
            ~*\bzh\b "cn";
        }

    主要作用为提取请求头中的Accept-Language值进行匹配。

    location = /index.html {
                # 根据 map 结果选择文件
                set $lang_file "index-${preferred_lang}.html";
                try_files /$lang_file =404;
                add_header Vary "Accept-Language" always;
            }

    根据匹配结果返回对应的语言页面,并添加 Vary: Accept-Language 响应头,以便 CDN 区分缓存。示例流程如下:

    1. 用户访问 http://yourdomain.com/index.html。

    2. Nginx 根据请求头中的 Accept-Language 解析出 $preferred_lang(如 cn)。

    3. 生成文件名 $lang_file=index-cn.html

    4. 检查服务器上是否存在 /var/www/html/index-cn.html

      • 存在 → 返回该文件。

      • 不存在 → 返回 404 错误。

CDN配置

CDN无需特殊配置,仅需配置常规的缓存规则。

  1. CDN控制台的域名管理页,单击目标域名右侧的管理

  2. 缓存配置 > 缓存过期时间页面单击添加,配置缓存过期时间。

    参数

    类型

    文件后缀名

    后缀名

    html

    过期时间

    10

    image

结果验证

使用 CURL 命令进行访问测试。

  1. 请求中文版本。

    curl -H "Accept-Language: zh,zh;q=0.9" http://yourdomain.com/index.html -v

    image

  2. 请求英文版本。

    curl -H "Accept-Language: en,en;q=0.9" http://yourdomain.com/index.html -v

    image