負載均衡下的資源文件配置/多站點下的資源文件夾共享(Windows IIS)


前言:

負載均衡用的是NLB,微軟的方案不太靠譜,舉個例子吧,AB兩台服務器負載出C,如果用戶訪問訪問C之后分配的是A,那么如果A掛了,是不會自動切換到B的。據說后來還有一種NLB的方案可以實現,也不想再試了。

背景:

這里主要是以圖片資源為主,以下是可能存在的場景:

1、同一台服務器上,部署了多個與業務相關的站點,同樣要用到統一的圖片資源(比如接口和后台這兩個業務系統,后台上傳了圖片,接口必須能獲取到這些圖片數據,同樣,反過來也是一樣)

2、使用了負載均衡(這里是微軟的NLB方案(強烈不建議使用微軟的方案),同樣也有很多負載均衡方案,比如nginx等),多個站點同時有圖片操作,那么最后每個站點都要同步進行顯示。

3、上面兩點都是基於Web的方案,那么如果出現WinForm這種,我需要保存文件到一個共享文件夾時的場景。

具體操作:

1、針對上面第1點,對應的解決方案是在IIS新建虛擬目錄實現,且新建的虛擬目錄在代碼操作上和真實目錄一致。

效果類似如下:

實質上,上面web1中的upload是真實存在的文件夾,而web2上是虛擬目錄,但是最終出來的效果都是一樣的,操作如下:

這里可以指向本機文件夾,也可以是局域網共享的文件夾,如果是需要賬號密碼的文件夾,可以設置【連接為(C)...】配置。不過一般我們只要本機就夠了。

接下來我們來代碼操作一下:web1上上傳了圖片,試下web2訪問一下,然后web2上傳了圖片,試下web1的訪問。注意:我這里直接使用一套代碼部署兩個站點,然后看下是否能達到操作虛擬目錄時,代碼是一致的。

前台:

后台代碼:

操作1:先部署到web1上,這個站點是有真實文件夾Upload的,完成通過。

操作2:部署到web2上,這個站點沒有真實文件夾Upload的,還是上面那份代碼:

一切正常!

2、針對上面第2點,那么就要配置同一個內網的文件夾共享。但是代碼還是上面的一份,只不過web.config上需要配置共享賬號。

具體操作:

1)在A服務器添加User1的賬號,密碼為123456;同時也在B服務器添加User1的賬號,密碼為123456;注意,這里兩台服務器上的賬號密碼都是一致的

2)配置A服務器上的Upload文件夾為共享,並添加User1用戶進入共享權限

並添加安全的用戶User1的權限

重要一步,在A服務器和B服務器上設置這個文件夾的權限:“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files”的權限

經過測試,如果不加這一步,會出現編譯不通過的問題。

3)在A服務器和B服務器上新建web站點,其中A服務器上的Upload文件夾為真實文件夾,但是B服務器上的Upload文件夾為虛擬文件夾,並指向A服務器的Upload共享文件夾

4)在代碼上,需要配置web.config,添加賬戶模擬設置

<system.web>
    <identity impersonate="true" userName="User1" password="123456"/>
</system.web>

5)進行部署並測試,先部署A服務器,看運行效果

 

成功,有文件存在。

再來部署B服務器,看運行效果

可以看出,也是成功的上傳的

上圖中的10.18.66.101為A服務器的內網IP

3、針對上面第3點進行測試,那么就要用到在程序中模擬域帳戶進行登錄操作,這種方式同時也是兼容Web方案的,只不過Web方案本身提供更優的解

代碼實現:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;

namespace ConsoleApplication_Test
{
    internal static class WinLogonHelper
    {
        /// <summary>
        /// 模擬windows登錄域
        /// </summary>
        [DllImport("advapi32.DLL", SetLastError = true)]
        public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
    }

    class Program
    {
        static void Main(string[] args)
        {
            IntPtr admin_token = default(IntPtr);
            WindowsIdentity wid_admin = null;
            WindowsImpersonationContext wic = null;

            //在程序中模擬域帳戶登錄
            if (WinLogonHelper.LogonUser("User1", "10.18.66.101", "123456", 9, 0, ref admin_token) != 0)
            {
                using (wid_admin = new WindowsIdentity(admin_token))
                {
                    using (wic = wid_admin.Impersonate())
                    {
                        System.IO.File.Create(@"\\10.18.66.101\Upload\test.txt");
                    }
                }
            }
        }
    }
}

 

 這里還是用User1賬號,密碼123456的用戶去登錄10.18.66.101這台機器,實質上是用模擬域登錄。

登錄完之后,然后就進行文件操作,記得,這個操作也像我們操作共享文件一樣,帶上IP這些。如“\\10.18.66.101\Upload\test.txt”,小技巧,前面加了@符號。

測試效果

將控制台部署到B服務器

效果也是成功的。

總結:

0、模擬域帳戶之后,就有了模擬用戶的權限,這里千萬要注意安全!

1、通過Web方案和WinForm方案,都可以實現局域網內的文件來回交換。

2、假設A服務器在杭州,B服務器在北京,那么要組建內網,可以直接用VPN方案,Windows下搭建PPTP,這里我提供阿里雲的的搭建方案:http://www.cnblogs.com/EasonJim/p/5361943.html

3、還有一種第三方的方案,購買又拍雲這類型的cdn方案,提供統一的接口和訪問地址,那么完全解決,都是多個程序統一一個路徑進行上傳的思路。

4、如果用了負載均衡的方案,在程序上如果用了Session的也要做相應的處理,比如StateServer方案。

5、極力反對使用微軟的NLB方案

參考:

http://www.cnblogs.com/yukaizhao/archive/2010/06/12/c-sharp-windowsimpersonationcontext.html

http://www.cnblogs.com/dudu/archive/2012/03/27/asp_net_share_folder.html

測試代碼:

https://github.com/easonjim/1_dotnet_example/tree/master/%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6%E5%85%B1%E4%BA%AB/WebApplication_Test

后話:

這篇文章是我在13年給一家摩托車公司做抽獎的時候涉及到的配置,當時網絡上對於這類配置比較少,且都是不太可行的,由於用的是微軟的NLB負載均衡方案,所以在項目實施上效果也非常不理想。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM