C \ # 수 동 으로 부하 균형 서버 만 들 기
부하 균형 서버 의 가장 유명한 숫자 는 Nginx 입 니 다.Nginx 서버 는 내부 네트워크 와 N 개 서버 에 비동기 적 으로 연결 을 전송 하여 단일 응용 서버 의 압력 을 분해 하고 원리 와 장면 을 파악 한 후 C \ # 로 하 나 를 실현 합 니 다.사고방식 은 다음 과 같다.
1. 한 사이트 의 Application_BeginRequest 에서 연결 을 받 고 전송 합 니 다.
2. 각종 정적 자원 에 대해 단독 처 리 를 한다. (돌 릴 수 있 고 돌 릴 수 없다)
3. Get, Post, 비동기 리 트 윗 이 가능 합 니 다.
4. 지정 한 요청 을 같은 서버 에 전송 하여 사용자 의 로그 인 상 태 를 유지 합 니 다.
이루어지다
Vs 2015 Mvc 건설 소: localhost: 1500 /.웹. config 를 수정 하여 모든 연결 을 받 을 수 있 습 니 다.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
</modules>
</system.webServer>
MyCmn. dll 도입 (http://code.taobao.org/svn/MyOql/libs4/), MyHelper 는 유형 변환 함 수 를 봉 하여 사용 하기에 편리 합 니 다.
코드 는 다음 과 같 습 니 다:
(프로젝트 Svn 주소: http://code.taobao.org/svn/MyMvcApp/MyProxy)
public class RequestWrap
{
public HttpWebRequest Request { get; set; }
private ManualResetEvent Event { get; set; }
private Action<HttpWebResponse> Action { get; set; }
public RequestWrap(HttpWebRequest request)
{
Event = new ManualResetEvent(false);
this.Request = request;
}
public void Run(Action<HttpWebResponse> act)
{
this.Action = act;
Request.BeginGetResponse(new AsyncCallback(GetResponseCallback), this);
this.Event.WaitOne(15000);
}
private static void GetResponseCallback(IAsyncResult asyncResult)
{
RequestWrap wrap = (RequestWrap)asyncResult.AsyncState;
HttpWebResponse response = null;
try
{
response = wrap.Request.EndGetResponse(asyncResult) as HttpWebResponse;
}
catch (WebException ex)
{
response = ex.Response as HttpWebResponse;
}
wrap.Action(response);
wrap.Event.Set();
}
}
private void Application_BeginRequest(Object source, EventArgs e)
{
var lastExtName = "";
{
var lastIndex = Request.Url.LocalPath.LastIndexOf('.');
if (lastIndex > 0)
{
lastExtName = Request.Url.LocalPath.Slice(lastIndex);
}
}
// <modules runAllManagedModulesForAllRequests="true"> , 。
if (lastExtName.IsIn(".js", ".css", ".html", ".htm", ".png", ".jpg", ".gif"))
{
return;
}
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(GetTransferHost() + Request.RawUrl);
myRequest.Proxy = null;
myRequest.Timeout = 15000;
myRequest.ReadWriteTimeout = 3000;
myRequest.Method = Request.HttpMethod;
Request.Headers.AllKeys.All(k =>
{
if (!WebHeaderCollection.IsRestricted(k))
{
myRequest.Headers.Add(k, Request.Headers[k]);
}
else
{
var val = Request.Headers[k];
if (k.Is("Range"))
{
myRequest.AddRange(val.AsInt());
}
else if (k.Is("If-Modified-Since"))
{
myRequest.IfModifiedSince = val.AsDateTime();
}
else if (k.Is("Accept"))
{
myRequest.Accept = val;
}
else if (k.Is("Content-Type"))
{
myRequest.ContentType = val;
}
else if (k.Is("Expect"))
{
myRequest.Expect = val;
}
else if (k.Is("Date"))
{
myRequest.Date = val.AsDateTime();
}
else if (k.Is("Host"))
{
myRequest.Host = val;
}
else if (k.Is("Referer"))
{
myRequest.Referer = val;
}
else if (k.Is("Transfer-Encoding"))
{
myRequest.TransferEncoding = val;
}
else if (k.Is("User-Agent"))
{
myRequest.UserAgent = val;
}
//else if (k.Is("Connection"))
//{
// o.Connection = val;
//}
else if (k.Is("KeepAlive"))
{
myRequest.KeepAlive = val.AsBool();
}
}
return true;
});
using (var readStream = Request.InputStream)
{
while (true)
{
byte[] readBuffer = new byte[1024];
var readLength = readStream.Read(readBuffer, 0, readBuffer.Length);
if (readLength == 0) break;
myRequest.GetRequestStream().Write(readBuffer, 0, readLength);
}
}
new RequestWrap(myRequest).Run(myResponse =>
{
myResponse.Headers.AllKeys.All(k =>
{
if (k.Is("X-Powered-By"))
{
return true;
}
Response.Headers[k] = myResponse.Headers[k];
return true;
});
using (var readStream = myResponse.GetResponseStream())
{
while (true)
{
byte[] readBuffer = new byte[1024];
var read = readStream.Read(readBuffer, 0, readBuffer.Length);
if (read == 0) break;
Response.OutputStream.Write(readBuffer, 0, read);
}
}
Response.StatusCode = myResponse.StatusCode.AsInt();
});
Response.End();
}
public static string GetClientIPAddress()
{
if (HttpContext.Current == null)
return string.Empty;
HttpContext context = HttpContext.Current;//System.Web.HttpContext.Current;
string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ipAddress))
{
string[] addresses = ipAddress.Split(',');
if (addresses.Length != 0)
{
return addresses[0];
}
}
return context.Request.ServerVariables["REMOTE_ADDR"]; //+ " host " + context.Request.UserHostAddress;
}
private string GetTransferHost()
{
string[] hosts = new string[] { "http://localhost" };
var index = GetClientIPAddress().Last() % hosts.Length ;
return hosts[index];
}
해명 하 다.
그 중 RequestWrap 은 비동기 요청 포장 에 대한 요청 클래스 입 니 다.Run 방법 을 패키지 하여 비동기 호출 을 진행 합 니 다.응용 서버 의 리 턴 헤드 를 걸 렀 습 니 다. X-Powered-By
... 에 대하 여 WebHeader Collection. IsRestricted 는 오류 로 인 한 것 입 니 다. 이상 처리: 이 레이 블 을 적당 한 속성 이나 방법 으로 수정 해 야 합 니 다. 글 주소: http://blog.useasp.net/archive/2013/09/03/the-methods-to-dispose-http-header-cannot-add-to-webrequest-headers.aspx, 아래 와 같이 발췌:
.
:
Range HTTP AddRange
If-Modified-Since HTTP IfModifiedSince
Accept Accept 。
Connection Connection KeepAlive 。
Content-Length ContentLength 。
Content-Type ContentType 。
Expect Expect 。
Date Date , 。
Host 。
Referer Referer 。
Transfer-Encoding TransferEncoding (SendChunked true)。
User-Agent UserAgent 。
그 중: Connection 설정 이 틀 릴 수 있어 서 제 가 걸 었 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.