网站静态内容出版解决方案

目录

  • 1. 架构总览
  • 2. cdn
  • 3. www 服务器
  • 4. cms 服务器
  • 5. img
  • 6. Ajax 局部更新与缓存

1. 架构总览

www 负责静态文件浏览, 台数不定, 可以采用零成本的DNS轮询, 或者4层LVS, 或者7层HAProxy, 还可以用F5, Array 等负载均衡设备.

cms 负责静态文件生成. 生成后的文件要同步到www中, 或者采用网络共享, 再者使用分布式文件系统, 总之将生成的文件交给www服务器, 根据你压力横向扩展即可

img 负责图片文件浏览. 通过给图片加版本号, 结局图片更新问题, 这样更新网站不用频繁刷新 CDN

这里不谈论负载均衡, 以及存储方案, 有情绪可以延伸阅读: http://netkiller.github.com/architect/index.html

你掌握了这个方案, 你可以很容易实现 向"京东商城", "VANCL凡客诚品", "走秀网" 这样的网站

这些网站的特点是: 浏览量大, 数据存储主要是图片, 登录/注册与购物车,用户中心 访问量只占到 5% 使用负责均衡很容易解决.

静态化网站可不避免的使用ajax做局部更新, ajax请求也要考虑缓存问题

首次访问服务器

  1. 访问www服务器
  2. nginx 判断文件是否存在,如果存在将文件显示出来
  3. 如果文件不存在,去cms服务器上查找, 如果存在便返回给www服务器,并显示出来
  4. 如果cms上文件不存在,cms服务器便使用rewrite生成该文件, 同时将内容返回给www服务器,www将内容缓存在自己的服务器上,并将内容显示出来

第二次访问

  1. 访问www服务器
  2. nginx 判断文件是否存在,如果存在将文件显示出来
  3. 如果文件不存在,去cms服务器上查找, 如果存在便返回给www服务器,并显示出来
  4. 如果cms上文件不存在,cms服务器便使用rewrite生成该文件, 同时将内容返回给www服务器,www将内容缓存在自己的服务器上,并将内容显示出来

2. cdn

如何使用 cdn 来缓存你的网站内容

让你的网页缓存在 cdn 节点上的方式有下面几种

  1. 让cdn的客服帮你配置缓存的规则, 他们很喜欢一刀切, 例如所有html都缓存2小时
  2. 在他们管理后台自行使用正则配置缓存的时间, 这个他们一般不会提供, 某些公司的CDN会提供这个功能. 非常方便.
  3. 通过HTTP头自行控制缓存时间, 一般是使用 max-age / s-maxage / Last-Modified 判断缓存时间

我比较喜欢最后一种, 通常我们使用max-age 与 s-maxage 同时使用, 这样我可以按照我的意向来决定文件的缓存时.

3. www 服务器

下面给出一个精简后的配置例子

如果文件不存在就会连接后端cms服务器生成文件,并且显示出来,同时加上缓存. 生成的文件会从cms中同步到www服务器上.

你可以采用

  1. rsync同步方案
  2. nfs/samba/gluster 共享方案
  3. iscsi 共享存储方案
  4. 分布式文件系统方案

参考阅读: 分布式文件系统, Netkiller Linux Storage 手札

		upstream  cms.mydomain.com  {
  server   192.168.2.11		weight=5	max_fails=3  fail_timeout=30s;
  server   192.168.2.21     weight=5	max_fails=3  fail_timeout=30s;
  server   192.168.2.23 backup;
  server   192.168.2.23 down;
}

server {
    listen       80;
    server_name  www.mydomain.com;

    charset utf-8;
    access_log  /var/log/nginx/www.mydomain.com.access.log  main;

    location / {
        root   /www/mydomain.com/www.mydomain.com;
        index  index.html index.htm;

		if ($request_uri ~* "\.(ico|css|js|gif|jpe?g|png|html)$") {
            expires 1d;
        }
        if ($request_uri ~* "\.(xml|json)$") {
            expires 1m;
        }

		valid_referers none blocked *.mydomain.com;
		if ($invalid_referer) {
			#rewrite ^(.*)$  http://www.mydomain.com/cn/$1;
			return 403;
		}

        proxy_intercept_errors  on;
        if (!-f $request_filename) {
          proxy_pass http://cms.mydomain.com;
          break;
        }
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}		

4. cms 服务器

CMS 内容管理系统的主要功能

  1. 内容分类管理
  2. 内容模板管理
  3. 内容编辑与发布
  4. 内容生成

服务应该实现

  1. 当发现目录中文件不存, 通过rewrite生成html, 这样可能根据需要生成html页面
  2. 当页面更新的时候,应该通过api 刷新cdn的缓存, 图片的版本好应该加一
  3. 将页面分成多个模块, 通过SSI拼装页面, 避免有重大改版时, 整站生成HTML.
  4. 避免使用seesion技术, 这样在负载均衡的时候可以使用最小连接数算法

例如:

rewrite ^/product/(phone|notebook)/(\d+).html /product/$1.php?id=$2 last;		

URL 唯一, url设计要考虑唯一性, 不要出现同一个url处理两个任务, 例如下面的例子, 每个用户的profile一个URL, 当被访问的时候便可以缓存在CDN或者用户浏览器上.

		http://www.mydomain.com/profile/neo.html
http://www.mydomain.com/profile/jam.html		
		server {
    listen       80;
    server_name  www.mydomain.com;

    #charset koi8-r;
    access_log  /var/log/nginx/www.mydomain.com.access.log  main;

    location / {
        root   /www/mydomain.com/www.mydomain.com;
        index  index.html;
    }
}

server {
    listen       80;
    server_name  cms.mydomain.com;

    charset utf-8;
    access_log  /var/log/nginx/cms.mydomain.com.access.log  main;

    location / {
        root   /www/mydomain.com/cms.mydomain.com;
        index  index.html index.php;

    }

    location ~ ^/(cn|tw)/(comment|affiche)/.*\.html {
		root /www/mydomain.com/www.mydomain.com;
		if (!-f $request_filename) {
			rewrite ^/(cn|tw)/(comment|affiche)/(\d+).html /publish/$2.php?id=$3&lang=$1 last;
		}
    }
    location /xml/ {
		root /www/mydomain.com/www.mydomain.com/xml;
    }
    location ~ ^/(config|include|crontab)/ {
		deny all;
		break;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
	root		/www/mydomain.com/cms.mydomain.com;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /www/mydomain.com/cms.mydomain.com$fastcgi_script_name;
        include        fastcgi_params;
		fastcgi_param  DOCUMENT_ROOT /www/mydomain.com/cms.mydomain.com;
		fastcgi_param  HOSTNAME cms.mydomain.com;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    location ~ /\.ht {
        deny  all;
    }
}		

5. img

img.mydomain.com

		server {
    listen       80;
    server_name  img.mydomain.com;

    charset utf-8;
    access_log  /var/log/nginx/img.mydomain.com.access.log  main;

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico)$
    {
		expires      7d;
    }
    location ~ .*\.(js|css)$
    {
		expires      1d;
    }
    location ~ .*\.(html|htm)$
    {
		expires      15m;
    }

    location / {
        root   /img/mydomain.com/img.mydomain.com;
        index  index.html;

        rewrite  "/theme/([0-9] {4})([0-9] {2})([0-9] {2})/(.+)\.(.+)\.(.+)" /theme/$1/$2/$3/$4.$6;
        rewrite  "/news/([0-9] {4})([0-9] {2})([0-9] {2})/(.+)\.(.+)\.(.+)" /news/$1/$2/$3/$4.$6;
        rewrite  "/product/([0-9] {4})([0-9] {2})([0-9] {2})/(.+)\.(.+)\.(.+)" /product/$1/$2/$3/$4.$6;
    }

}		

/theme/2012/08/15/images.1.jpg 实际上就是 /theme/2012/08/15/images.jpg 文件

/theme/2012/08/15/images.2.jpg 也是 /theme/2012/08/15/images.jpg

/theme/2012/08/15/images.3.jpg 也是 /theme/2012/08/15/images.jpg

但CDN与你的浏览器会每次下载新的文件, 这样只要更新CDN中的html页面即可, 不用去理睬图片, 你的浏览器会用新的地址下载图片. 这样就解决了烦琐的刷新工作.

6. Ajax 局部更新与缓存

例如我的新闻评论页面,需要使用ajax技术, 将用户回复的品论显示来, ajax 载入json数据然后局部更新, 我对他做了1分钟的缓存

if ($request_uri ~* "\.(xml|json)$") {
	expires 1m;
}		

如果有新的提交我们可以为json增加版本是控制例如: http://api.mydomain.com/news.json?1.0

原文发布于微信公众号 - Netkiller(netkiller-ebook)

原文发表时间:2016-04-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏落花落雨不落叶

canvas画简单电路图

84911
来自专栏杨龙飞前端

scrollto 到指定位置

2954
来自专栏C#

DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱。不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬。(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...)...

5968
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.4K7
来自专栏闻道于事

js登录滑动验证,不滑动无法登陆

js的判断这里是根据滑块的位置进行判断,应该是用一个flag判断 <%@ page language="java" contentType="text/html...

8678
来自专栏Golang语言社区

【Golang语言社区】GO1.9 map并发安全测试

var m sync.Map //全局 func maintest() { // 第一个 YongHuomap := make(map[st...

5458
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

5228
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2870
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2997
来自专栏张善友的专栏

Mix 10 上的asp.net mvc 2的相关Session

Beyond File | New Company: From Cheesy Sample to Social Platform Scott Hansel...

2787

扫码关注云+社区