• ASP.NET应用使用Nginx做负载均衡遇到的一个问题


      客户在使用我们的某个应用遇到了性能瓶颈,于是决定增加多个节点减轻单节点的压力。部署方案:

    1台Nginx服务器

    2台应用服务器,每台两个站点(一个应用创建两个IIS站点、不同端口号)

    Nginx的配置如下:

    http {
        upstream clusterservice {
            server 10.x.x.181:9001;
            server 10.x.x.181:9002;
            server 10.x.x.187:9001;
            server 10.x.x.187:9002;
            ip_hash;
        }
    
        server {
            server_name xxx;
            listen 10087;
    
            location / {
                proxy_pass http://clusterservice;
    
                proxy_set_header   Host             $http_host;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            }
        }
    }
    

      很常见的Nginx配置,但问题发生了。由于我们有一个负责单点登录的网站,当用户首次访问我们的应用时候它会跳转到单点登录站点,重定向到单点登录的时候在请求中会新增一个名称为ActionUrl的参数,这个参数使用了HttpRequest.Url的值。我们期望的重定向地址:http://sso.xxx.com/SignOn.aspx?actionUrl=http://xxx:10087/。实际情况是获取到的请求地址它的端口使用了本地端口,并不是我们期望的10087。实际的重定向地址:http://sso.xxx.com/SignOn.aspx?actionUrl=http://xxx:9001/。

      反编译System.Web.dll查看HttpRequest的Url属性内部实现到底是如何产生这个地址,发现了解决方案。下面是其内部实现代码:

    internal Uri BuildUrl(Func<string> pathAccessor)
    {
    	Uri uri = null;
    	string text = QueryStringText;
    	if (!string.IsNullOrEmpty(text))
    	{
    		text = "?" + HttpEncoder.CollapsePercentUFromStringInternal(text, QueryStringEncoding);
    	}
    	if (AppSettings.UseHostHeaderForRequestUrl)
    	{
    		string knownRequestHeader = _wr.GetKnownRequestHeader(28);
    		try
    		{
    			if (!string.IsNullOrEmpty(knownRequestHeader))
    			{
    				uri = UriUtil.BuildUri(_wr.GetProtocol(), Uri.UnescapeDataString(knownRequestHeader), null, pathAccessor(), text);
    			}
    		}
    		catch (UriFormatException)
    		{
    		}
    	}
    	if (uri == (Uri)null)
    	{
    		string text2 = _wr.GetServerName();
    		if (text2.IndexOf(':') >= 0 && text2[0] != '[')
    		{
    			text2 = "[" + text2 + "]";
    		}
    		uri = UriUtil.BuildUri(_wr.GetProtocol(), Uri.UnescapeDataString(text2), _wr.GetLocalPortAsString(), pathAccessor(), text);
    	}
    	return uri;
    }
    

      我们发现可以通过在Web.config的appSettings节点新增一个键值让它使用“Host”标头提供的主机和端口作为动态请求地址,而不是默认的Web服务器。如下:

    <appSettings>
          <add key="aspnet:UseHostHeaderForRequestUrl" value="true" />
    </appSettings>
    

      

  • 相关阅读:
    [DOJ练习] 无向图的邻接矩阵表示法验证程序
    [DOJ练习] 求无向图中某顶点的度
    [邻接表形式]有向图的建立与深度,广度遍历
    [DOJ练习] 有向图的邻接表表示法验证程序(两种写法)
    [Java 学习笔记] 异常处理
    [总结]单源最短路(朴素Dijkstra)与最小生成树(Prim,Kruskal)
    时间选择插件jquery.timepickr
    页面值传入后台出现中文乱码
    CheckTreecheckbox树形控件
    JQuery EasyUI DataGrid
  • 原文地址:https://www.cnblogs.com/junchu25/p/9325852.html
Copyright © 2020-2023  润新知