IIS 7 反向代理缓存图片,源图片服务器 和 缓存图片服务器分离

网站发展到一定阶段之后,

图片服务器压力过大,

所以配置成  ,源服务器 -> 缓存服务器 模式

首先览器访问的是 缓存服务器,缓存服务器判断是否有请求的图片,如果有则直接输出给浏览器,没有的话再从源服务器上请求过来,再输出给浏览器


缓存服务器(windows 2008 R2 + IIS 7 + URLRewrite模块 )  IIS 配置文件如下:

Web.Config


<?xml version="1.0" encoding="UTF-8"?>
<configuration>


  <appSettings>


    <add key="proxyDomain" value="http://i-1.test.com/" />



  </appSettings>

  <system.webServer>
      <rewrite>
          <rules>
              <rule name="WhiteList" stopProcessing="true">
                  <match url="/.*" />
                  <action type="Rewrite" url="/404.html" />
                    <conditions>
						<add input="{HTTP_REFERER}" pattern="^$" negate="true" />			
                        <add input="{HTTP_REFERER}" pattern="^http://.*(so|360|qq|baidu)\.(com|cn).*$" negate="true" />						
                    </conditions>
              </rule>		
		  
		  
              <rule name="Rewrite">
                  <match url="/.*" />
                  <action type="Rewrite" url="/proxyStatic.ashx{R:0}" />
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    </conditions>
              </rule>
          </rules>
      </rewrite> 

      
	<staticContent>
		<clientCache cacheControlMode="UseExpires" httpExpires="Thu, 31 Dec 2037 23:55:55 GMT" />
	</staticContent>
        <httpProtocol>
            <customHeaders>
                <remove name="X-Powered-By" />
                <add name="Cache-Control" value="max-age=315360000" />
            </customHeaders>
        </httpProtocol>
        <handlers>
            <remove name="xoml-Integrated" />
            <remove name="xoml-ISAPI-2.0" />
            <remove name="xoml-64-ISAPI-2.0" />
            <remove name="WebServiceHandlerFactory-ISAPI-2.0-64" />
            <remove name="WebServiceHandlerFactory-ISAPI-2.0" />
            <remove name="WebServiceHandlerFactory-Integrated" />
            <remove name="WebAdminHandler-Integrated" />
            <remove name="TRACEVerbHandler" />
            <remove name="TraceHandler-Integrated" />
            <remove name="svc-ISAPI-2.0-64" />
            <remove name="svc-ISAPI-2.0" />
            <remove name="svc-Integrated" />
            <remove name="SSINC-stm" />
            <remove name="SSINC-shtml" />
            <remove name="SSINC-shtm" />
            <remove name="SecurityCertificate" />
            <remove name="rules-ISAPI-2.0" />
            <remove name="rules-Integrated" />
            <remove name="rules-64-ISAPI-2.0" />
            <remove name="PageHandlerFactory-ISAPI-2.0-64" />
            <remove name="PageHandlerFactory-ISAPI-2.0" />
            <remove name="PageHandlerFactory-Integrated" />
            <remove name="OPTIONSVerbHandler" />
            <remove name="HttpRemotingHandlerFactory-soap-ISAPI-2.0-64" />
            <remove name="HttpRemotingHandlerFactory-soap-ISAPI-2.0" />
            <remove name="HttpRemotingHandlerFactory-soap-Integrated" />
            <remove name="HttpRemotingHandlerFactory-rem-ISAPI-2.0-64" />
            <remove name="HttpRemotingHandlerFactory-rem-ISAPI-2.0" />
            <remove name="HttpRemotingHandlerFactory-rem-Integrated" />
            <remove name="AXD-ISAPI-2.0-64" />
            <remove name="AXD-ISAPI-2.0" />
            <remove name="AssemblyResourceLoader-Integrated" />
            <remove name="ASPClassic" />
        </handlers>
        <modules>
            <remove name="WindowsAuthentication" />
            <remove name="UrlAuthorization" />
            <remove name="Session" />
            <remove name="ServiceModel" />
            <remove name="RoleManager" />
            <remove name="Profile" />
            <remove name="OutputCache" />
            <remove name="FormsAuthentication" />
            <remove name="FileAuthorization" />
            <remove name="DefaultAuthentication" />
            <remove name="AnonymousIdentification" />
        </modules>
       
  </system.webServer>

  <system.web>
  
	<compilation debug="false" />
    <sessionState mode="Off"></sessionState>

  </system.web>

</configuration>







<%@ WebHandler Language="C#" Class="proxyStatic" %>

using System;
using System.Web;
using System.Net;
using System.IO;
using System.Collections.Generic;
using System.Configuration;

public class proxyStatic : IHttpHandler
{



    HttpResponse Response;
    HttpRequest Request;
    HttpApplicationState Application;
    HttpServerUtility Server;


    string proxyDomain = ConfigurationManager.AppSettings["proxyDomain"];

    public void ProcessRequest(HttpContext context)
    {
        Response = context.Response;
        Request = context.Request;
        Application = context.Application;
        Server = context.Server;

        Response.Buffer = false;





        //304 缓存
        string date = Request.Headers.Get("If-Modified-Since");
        if (date != null)
        {
            Response.StatusCode = 304;
            Response.StatusDescription = "from cache";
            return;
        }

        Response.Cache.SetLastModified(new DateTime(2000, 1, 1));
        //304 缓存 end


        string path = string.Empty;
        string rawUrl = context.Request.RawUrl;

        int index = rawUrl.IndexOf('?');
        if (index > 0)
        {
            path = rawUrl.Substring(0, index);
        }
        else
        {
            path = rawUrl;
        }


        try
        {
            EchoData(path);
        }
        catch
        {
            Response.StatusCode = 404;
        }


    }



    void EchoData(string path)
    {
        string file404 = Server.MapPath("/404" + path + ".txt");
        if (File.Exists(file404) && (DateTime.Now - File.GetLastWriteTime(file404)).TotalSeconds < 300)
        {
            Response.StatusCode = 404;
            return;
        }




        string imageFilePath = Server.MapPath(path);


        if (File.Exists(imageFilePath))
        {
            string ext = Path.GetExtension(imageFilePath);
            Response.ContentType = GetContentType(ext);
            Response.TransmitFile(imageFilePath);
        }
        else
        {
            //更新Cache File
            string ApplicationKey = "CacheList";
            List<string> List = null;


            if (Application[ApplicationKey] == null)
            {
                Application.Lock();
                Application[ApplicationKey] = List = new List<string>(1000);
                Application.UnLock();
            }
            else
            {
                List = (List<string>)Application[ApplicationKey];
            }


            //判断是否已有另一个进程正在更新Cache File
            if (List.Contains(path))
            {
                try
                {
                    using (WebClient wc = new WebClient())
                    {
                        byte[] buffer = wc.DownloadData(proxyDomain + path);
                        wc.Dispose();
                        string ext = Path.GetExtension(imageFilePath);
                        Response.ContentType = GetContentType(ext);
                        Response.BinaryWrite(buffer);
                    }
                }
                catch
                {

                    Create404File(file404);


                    Response.StatusCode = 404;

                }

            }
            else
            {


                try
                {
                    using (WebClient wc = new WebClient())
                    {
                        List.Add(path);
                        byte[] buffer = wc.DownloadData(proxyDomain + path);
                        wc.Dispose();


                        string folder = Path.GetDirectoryName(imageFilePath);
                        if (!Directory.Exists(folder))
                        {
                            Directory.CreateDirectory(folder);
                        }

                        using (FileStream fs = File.Create(imageFilePath))
                        {
                            fs.Write(buffer, 0, buffer.Length);
                            fs.Close();
                        }

                        List.Remove(path);

                        string ext = Path.GetExtension(imageFilePath);
                        Response.ContentType = GetContentType(ext);
                        Response.BinaryWrite(buffer);
                    }
                }
                catch
                {
                    Create404File(file404);

                    List.Remove(path);
                    Response.StatusCode = 404;
                }
            }
        }
    }


    void Create404File(string file404)
    {
        string folder404 = Path.GetDirectoryName(file404);
        if (!Directory.Exists(folder404))
        {
            Directory.CreateDirectory(folder404);
        }

        using (StreamWriter sw = File.CreateText(file404))
        {
            sw.Close();
            sw.Dispose();
        }
    }

    static string[,] ContentTypes = {
        {".jpg","image/jpeg"},
        {".png","image/png"},
        {".gif","image/gif"},
        {".bmp","application/x-bmp"},
        {".jpeg","image/jpeg"}
    };

    string GetContentType(string ext)
    {
        ext = ext.ToLower();
        for (int i = 0; i < ContentTypes.Length; i++)
        {
            if (ContentTypes[i, 0] == ext)
            {
                return ContentTypes[i, 1];
            }
        }

        return string.Empty;
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}


你可能感兴趣的:(IIS 7 反向代理缓存图片,源图片服务器 和 缓存图片服务器分离)