facebook  linkedin  Twitter  skype  Rss googlePlus

Replicating Content to Multiple Servers

May 09 2004
4548

In this article I am presenting one solution for duplicating content across a Web farm.

If you're familiar with highly available systems that run on a Web farm; you have multiple machines serving content for your Website. The most common configuration is where you have your development machine, and once you're done with development you place the content on a middle tier server called a staging server. Once content is on the staging server, it is then replicated across the members of the production Web farm. This configuration provides a great amount of performance and redundancy for the Web site. The major drawback is if you want people to be able to upload data to the Web server, usually you have to use some kind of database solution to store the files in a centralized database rather than on the Web server itself. This is due to the fact you are never sure which Web server the file will be uploaded to, and when replication occurs again, it may delete the file since it does not exist on your staging server.

In this article we are going to present a .Net procedure that accepts the path information of a file that has been placed on a Web server, and then it copies the file to other servers via a share name. The routine will check to see which server in the share name array it is and replicate the content to other machines in the array.

In this example we will need to specify a delimited string which will be our paths to the shares which are members of the farm. In addition to this we will specify a privileged account that will be used to access the share. Modify the appSettings section of the  Web.config file to contain the following:

value="domain\accountname" />






The next thing we need to do is create a WebFarm.vb class which we will use to call from our aspx pages. Create the class and then import the System.IO class for manipulating files, System.Security.Principal for account impersonation, and System.Configuration for working with our web.config file.

Imports System.IO
Imports System.Security.Principal Imports System.Configuration

Next make a declaration to the advapi32..dll API, this will allow us to execute the code under a privileged account that has permissions to all the server shares that were specified.

Public Class Logon
Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As String, _
ByVal lpszDomain As String, ByVal lpszPassword As String, ByVal dwLogonType As Integer, _
ByVal dwLogonProvider As Integer, ByRef phToken As Integer) As Boolean
End Class

Next declare some constants to be passed to the Logon class, whether to logon as an interactive user, or using clear text. In our example here we will be logging on as an interactive user to access the share on the network

Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Const LOGON32_LOGON_NETWORK_CLEARTEXT As Integer = 3
'This parameter causes LogonUser to create a primary token.
Const LOGON32_LOGON_INTERACTIVE As Integer = 2

Private DomainName As String
Private UserAccount As String
Private Password As String
Private CurrentMachine As String = System.Environment.MachineName
Private aryShares As String()

Here we call a routine that is going to populate the variables we declared above. The variables will be populated with the username and password we're going to use to access the share, and create an array of the shares that we want files replicated to.
'GetFarmValues
'Description: Used to parse out information defined in the
' Web.config file for account information and shares.
Private Sub GetFarmValues()
'points to the root directory of the application.
Dim strServers As String = ConfigurationSettings.AppSettings("FarmMembers")
aryShares = Split(strServers, ";")
Password = .Configuration.ConfigurationSettings.AppSettings("ADsPassword")
UserAccount = Mid(ConfigurationSettings.AppSettings("ADsUserName"), _
InStr(ConfigurationSettings.AppSettings("ADsUserName"), "\") + 1)
DomainName = Left(ConfigurationSettings.AppSettings("ADsUserName"), _
InStr(ConfigurationSettings.AppSettings("ADsUserName"), "\") - 1)
End Sub

The following procedure accepts InPath as the local path that the file is being copied to. InFile is the name of the file that we want to copy. And InAppRoot is the application root directory of the path. We use this to determine the path for the share to its web directories.

Public Sub CopyFileToShare(ByVal InPath As String, ByVal InFile As String, _
ByVal InAppRoot As String)
Dim sDestination As String
Dim hToken As Integer
Dim iPtrToken As IntPtr
GetFarmValues()
Dim LocalPath As String = InPath & InFile
Dim i As Integer
Dim loggedOn As Boolean = Logon.LogonUser(UserAccount, DomainName, Password, _
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken)
If loggedOn Then
iPtrToken = New IntPtr(hToken)
Dim ImpersonatedIdentity As New WindowsIdentity(iPtrToken)
Dim MyImpersonation As WindowsImpersonationContext = ImpersonatedIdentity.Impersonate()
'do routine.
Try
For i = 0 To UBound(aryShares)
'check out the share in the array against the current machine.
If InStr(LCase(aryShares(i)), LCase(CurrentMachine)) = 0 Then
'this is a different machine than the local machine.
'we need to figure out the root of the servers.
sDestination = Replace(InPath, InAppRoot, aryShares(i)) & InFile
'if it's there delete it first.
File.Delete(sDestination)
File.Copy(LocalPath, sDestination)
End If
Next
Catch ex As Exception
'file copy failed.
End Try
MyImpersonation.Undo()
End IfEnd Sub

Then from our aspx file for example, if we had an upload routine that accepted a file from a user via the Web, once the file was uploaded to the server, we would immediately call our newly created class and copy that file to other servers in our share array:

Dim objWebFarm As New WebFarm
objWebFarm.CopyFileToShare(Request.MapPath("c:\inetpub\wwwroot\myapp\", _
strFileName, Server.MapPath(Request.ApplicationPath))
objWebFarm = Nothing

By:
Patrick Santry,
MCT, MCSE, MCSA, MCP+SB, contributor of "Windows 2003 Server - The Complete Reference", Co-Author of
"Administering IIS 5.0" both books published by McGraw-Hill. In
addition, Patrick has written several articles and co-authored several books on
Microsoft certification. You can view his personal website at
http://www.santry.com/.


About the Author, Patrick Santry

Patrick Santry, has two decades of experience in enabling businesses to take advantage of the digital landscape. A well rounded experience in technology, and business is what sets me apart from the rest of the pack. When it comes to an overall digital strategy my experience is impressive.

BS in Computer Information Systems. Four time recipient of the Microsoft MVP Award, and author of several books and magazine articles on digital technologies.


blog comments powered by Disqus

 

Thank you for visiting our site, before you leave, please visit some of the areas or information you may have missed.

Popular Articles