首頁  >  文章  >  web前端  >  中小型網站架構分析及最佳化

中小型網站架構分析及最佳化

伊谢尔伦
伊谢尔伦原創
2016-12-03 11:57:121531瀏覽

先看網站架構圖:

中小型網站架構分析及最佳化

 以上網站架構廣泛運用中大型網站中,本文從架構每一層分析所用主流技術和解決手段,有助於初入網站運維朋友們,進一步對網站架構認識,從而自己形成一套架構概念。

  第一層:CDN

  國內網路分佈主要南電信北聯通,造成跨地區訪問延遲大問題,對於有一定訪問量網站來說,增加CDN(內容分發網絡)層可有效改善此現象,也是網站加速的最好選擇。 CDN把網站頁面緩存到全國分佈的節點上,用戶訪問時從最近的機房獲取數據,這樣大大減少網絡訪問的路徑。如果想自己搭建CDN,不建議這麼做,因為什麼呢?其實說穿了,就是什麼事別往運維上攔。 CDN架構部署不複雜,影響效果的因素卻很多,後期管理維護也比較複雜,想達到預期的效果確非易事,這是一個費力不討好的活,最後老闆還是覺得是你能力不足。建議找專做CDN的公司,費用也不貴,有抗流量攻擊能力,效果也很好,維運也少很多事,何樂而不為呢!

 第二層:反向代理(網頁快取)

  如果CDN沒有快取要請求的資料則向這層發起請求,在代理伺服器配置快取功能(本地),代理伺服器就查找本地快取是否有CDN請求的數據,如果有就直接返回給CDN,如果沒有則請求後端負載平衡器然後轉發給WEB伺服器返回數據給代理伺服器,代理伺服器再將結果給CDN。代理伺服器一般快取不常變動的靜態頁面,如image、js、css、html等,主流的快取軟體有Squid、Varnish、Nginx。

  第三層:負載平衡

  訪問量較大的網站都會用到負載平衡,因為這是解決單一伺服器效能瓶頸的最佳方法。反向代理將請求轉發給負載平衡器,負載平衡器根據演算法(輪訓、負載情況選擇後端等)交給後端WEB服務處理,WEB服務處理完成後直接傳回資料給反向代理伺服器。負載平衡合理分配請求給後端多台WEB伺服器,減輕單一伺服器並發負載,並保證服務可用性。主流的負載平衡軟體有LVS、HAProxy、Nginx。

  第四層:WEB服務

  WEB服務是處理用戶請求的,WEB服務處理效率,直接影響到訪問速度,為避免這層因素造成訪問慢,應對其進行調優,讓WEB服務發揮到最佳狀態。常見的WEB服務有Apache和Nginx。

  Apache最佳化:

  1).mod_deflate壓縮模組

  查看是否載入:

# apachectl –M |grep deflate

      

2).mod_expires快取模組

  查看是否載入:

# /usr/local/apache/bin/apxs –c –I –A apache源码目录/modules/mod_deflate.c
    如果沒有安裝使用apxs編譯進去:

<IfModulemod_deflate.c>
DeflateCompressionLevel6      #压缩等级(1-9),数值越大效率越高,消耗CPU也就越高
SetOutputFilterDEFLATE      #启用压缩
AddOutputFilterByTypeDEFLATE text/html text/plain text/xml #压缩类型
AddOutputFilterByTypeDEFLATE css js html htm xml php 
</IfModule>

      

  快取機制有三種用法:全域、目錄與虛擬主機

  全域配置,在設定檔末尾新增:

# apachectl –M |grep expires
   

  3).工作模式選擇及最佳化

  apache有两种常见工作模式,worker和prefork,默认是worker,是混合型的MPM(多路处理模块),支持多进程和多线程,由线程来处理请求,所以可以处理更多请求,提高并发能力,系统资源开销也小于基于进程的MPM,由于线程使用进程内存空间,进程崩溃会导致其下线程崩溃。而prefork是非线程型MPM,进程占用系统资源也比worker多,由于进程处理连接,在工作效率上也比worker更稳定。可通过apache2 –l查看当前工作模式,在编译时使用—with-mpm参数指定工作模式。根据自己业务需求选择不同工作模式,再适当增加工作模式相关参数,可提高处理能力。

  配置参数说明:

<IfModuleprefork.c>
StartServers      8   #默认启动8个httpd进程
MinSpareServers    5    #最小的空闲进程数
MaxSpareServers    20   #最大的空闲进程数,如果大于这个值,apache会自动kill一些进程
ServerLimit      256   #服务器允许进程数的上限
MaxClients       256  #同时最多发起多少个访问,超过则进入队列等待
MaxRequestsPerChild  4000  #每个进程启动的最大线程
</IfModule>

       Nginx优化:

  1).gzip压缩模块

 http {
    ……
    gzip on;
    gzip_min_length 1k;   #允许压缩的页面最小字节数,默认是0,多大都压缩,小于1k的可能适得其反
    gzip_buffers 4 16k;   #gzip申请内存的大小,按数据大小的4倍去申请内存
    gzip_http_version 1.0;  #识别http协议版本
    gzip_comp_level 2;    #压缩级别,1压缩比最小,处理速度最快,9压缩比最大,处理速度最慢
    gzip_types text/plainapplication/x-javascripttext/css application/xml image/jpg;  #压缩数据类型
    gzip_vary on;      #根据客户端的http头来判断,是否需要压缩
}

    2).expires缓存模块

server {
    location ~ .*\.(gif|jpg|png|bmp|swf)$   #缓存数据后缀类型
    {
      expires 30d;   #使用expires缓存模块,缓存到客户端30天
    }
    location ~ .*\.( jsp|js|css)?$
    {
      expires 1d;
    }
}

    3).fastcgi优化

  nginx不支持直接调用或者解析动态程序(php),必须通过fastcgi(通用网关接口)来启动php-fpm进程来解析php脚本。也就是说用户请求先到nginx,nginx再将动态解析交给fastcgi,fastcgi启动php-fpm解析php脚本。所以我们有必要对fastcgi和php-fpm进行适当的参数优化。

http {
    ……
    fastcgi_cache_path/usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m; 
    # FastCGI缓存指定一个文件路径、目录结构等级、关键字区域存储时间和非活动删除时间
    fastcgi_connect_timeout 300;    #指定连接到后端FastCGI的超时时间
    fastcgi_send_timeout 300;     #指定向FastCGI传送请求的超时时间
    fastcgi_read_timeout 300;     #指定接收FastCGI应答的超时时间
    fastcgi_buffer_size 64k;      #指定读取FastCGI应答第一部分需要多大的缓冲区
    fastcgi_buffers 4 64k;      #指定本地需要用多少盒多大的缓冲区来缓冲FastCGI的应答请求
    fastcgi_busy_buffers_size 128k;  
    fastcgi_temp_file_write_size 128k;  #表示在写入缓存文件时使用多大的数据块,默认值是fastcgi_buffers的两倍
    fastcgi_cache TEST;          #开启fastcgi_cache缓存并指定一个TEST名称
    fastcgi_cache_valid 200 302 1h;   #指定200、302应答代码的缓存1小时
    fastcgi_cache_valid 301 1d;     #将301应答代码缓存1天
    fastcgi_cache_valid any 1m;     #将其他应答均缓存1分钟
{

    php-fpm.conf配置参数:

pm =dynamic        #两种控制子进程方式(static和dynamic)
pm.max_children= 5     #同一时间存活的最大子进程数
pm.start_servers= 2    #启动时创建的进程数
pm.min_spare_servers= 1  #最小php-fpm进程数
pm.max_spare_servers= 3  #最大php-fpm进程数

    4).proxy_cache本地缓存模块

http {
        ……
   proxy_temp_path  /usr/local/nginx/proxy_cache/temp;    #缓存临时目录
   proxy_cache_path /usr/local/nginx/proxy_cache/cache levels=1:2 keys_zone=one:10m inactive=1d max_size=1g;
   #缓存文件实际目录,levels定义层级目录,1:2说明1是一级目录,2是二级目录,keys_zone存储元数据,并分配10M内存空间。inctive表示1天没有被访问的缓存就删除,默认10分钟。max_size是最大分配磁盘空间
   server {
      listen 80;
      server_name 192.168.1.10;
      location / {
        proxy_cache one;   #调用缓存区
        #proxy_cache_valid 200 304 12h; #可根据HTTP状态码设置不同的缓存时间
        proxy_cache_valid any  10m;    #缓存有效期为10分钟
      }
      #清除URL缓存,允许来自哪个网段的IP可以清除缓存(需要安装第三方模块"ngx_cache_purge"),清除URL缓存方法:访问http://192.168.1.10/purge/文件名
      location ~ /purge(/.*){
        allow 127.0.0.1;
        allow 192.168.1.0/24;
        deny all;
        proxy_cache_purge cache_one$host$1$is_args$args;
      }
 }

小结:

  启用压缩模块可以节省一部分带宽,会增加WEB端CPU处理,但在上图网站架构中,WEB端启用压缩模块并没有起到作用,因为传输到上层走的是局域网。对于直接面向用户的架构还是要启用的。WEB也不用启用expires模块,因为有了反向代理服务器和CDN,所以到不了用户浏览器,开启起不到作用。

  如果反向代理使用nginx做代理,可开启expires模块,将静态文件缓存到用户浏览器,浏览器发起请求时,先判断本地缓存是否有请求的数据,如果有再判断是否过期,如果不过期就直接浏览缓存数据,哪怕服务器资源已经改变,所以要根据业务情况合理设置过期时间。

  5). 利用PHP缓存器提高代码执行效率

  php程序在没有使用缓存器情况下,每次请求php页面,php都会对此页面进行代码编译,这就意味着重复的编译工作会增加服务器负载。有了缓存器就会把每次编译后的数据缓存到共享内存中,下次访问直接使用缓冲区已编译好的代码,从而避免重复的编译过程,以加快其执行效率。因此PHP网站使用缓存器是完全有必要的!主流的PHP缓存器有:eAccelerator、XCache

  第五层:动静分离

  动静分离,顾名思义,是将动态页面和静态页面分离到不同服务器上处理,比如使用web是nginx,可以让fastcgi部署到单独一台服务器,专门解析php动态页面,静态页面默认由nginx处理,并做好缓存策略。再比如一个商城网站,会有大量的图片,可以考虑增加文件服务器组,将请求图片和上传图片的都交给文件服务器处理。文件服务器主流使用NFS,存在单点故障,可以DRBD+HeartBeat+NFS部署高可用,如果单台压力过大,考虑使用分布式文件系统,如GlusterFS、MooseFS等。

 第六层:数据库缓存

  利用快取技術,把熱資料快取到記憶體中,如果請求的資料在快取中,就直接返回,否則去資料庫中取,並更新把拿的資料更新到快取系統,提高讀取效能,降低資料庫壓力。快取實作有本地快取和分散式緩存,本地快取是將資料快取到本地伺服器記憶體或檔案。分散式快取是將資料快取到記憶體中,是分散式的,可以快取大量數據,擴展性佳。主流的分散式快取系統有Memcached和Redis,Memcached效能穩定,速度很快,QPS可達8w左右。如果想資料持久化就選擇用Redis,效能不低於Memcached。

  第七層:資料庫

  這層在整個網站架構中起著主導型作用,直接決定用戶體驗,相對架構優化也比較複雜。


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn