Segnala il sito a un amico |
|
|
Se hai trovato questa pagina interessante, scrivilo ad un amico, clicca qui |
|
|
NEW!! GiDiNet Web Directory |
|
|
GiDiNet Directory è una Web Directory divisa in più aree tematiche in cui potrete
trovare comodamente siti che trattano argomenti di vostro interesse, continua... |
|
|
Statistiche |
|
Oggi
21/11/2024
sei il visitatore n.
per un totale di
visitatori dal 23/04/2007
|
|
|
|
|
Hai un problema particolare? Non trovi quello che stai cercando? clicca qui!
Un sistema di bandwidth management semplificato in ASP.NET
Lo script pubblicato in questa pagina ha lo scopo di creare un sistema semi-automatico per la gestione del traffico web utilizzando il .NET Framework v2.0
Nota: Nella progettazione dello script sono state applicate alcune semplificazioni per permetterne l'uso senza dover installare componenti aggiuntivi sul server web e più in generale senza dover effettuare modifiche di configurazione.
Con un http handler le richieste verso determinati file verranno reindirizzate in automatico su un'altro server, seguendo le impostazioni specificate nel file di configurazione.
Il sistema permette quindi di dividere il traffico su un gruppo di server web (anche vps o normali pacchetti hosting), utilizzando una procedura molto semplificata e senza l'uso di moduli aggiuntivi da installare sul server, questo sistema quindi può essere usato su gran parte degli hosting condivisi.
Sui mirror verranno reindirizzati esclusivamente i download, quindi il sistema operativo e i linguaggi script supportati saranno indifferenti.
Questa soluzione può essere utilizzata ad esempio a siti web che mettono a disposizione download di grosse dimensioni, per ottimizzare i costi del servizio di hosting, o per gestire in modo migliore le richieste di download dei visitatori quando la banda di ciascun server è limitata.
Ad esempio disponendo di un sito web principale (es. www.miosito.ext) di uno o più server (anche vps o pacchetti hosting) che vogliamo usare come mirror, potremo reindirizzare in automatico parte delle richieste sui mirror riducendo notevolmente il traffico generato dal sito web principale.
In pratica per richiamare il modulo sarà sufficiente aggiungere l'estensione .aspx al file richiamato, ad esempio per reindirizzare il download di un file /downloads/miodownload.zip, sarà sufficiente richiamare /downloads/miodownload.zip.aspx.
1. Installazione dello script
Per l'installazione dello script è sufficiente creare due file /App_Code/ManualBandwidthManagement.vb e /Web.config secondo quanto indicato di seguito
Se il file /Web.config fosse già presente sullo spazio web, basterà modificarlo inserendo quanto riportato in grassetto nelle sezioni indicate.
Scarica i sorgenti completi
Codice del file /App_Code/ManualBandwidthManagement.vb:
'Copyright (C) 2007 Daniele Iunco
'This program is free software; you can redistribute it and/or modify
'it under the terms of the GNU General Public License as published by
'the Free Software Foundation; either version 2 of the License, or
'(at your option) any later version.
'This program is distributed in the hope that it will be useful,
'but WITHOUT ANY WARRANTY; without even the implied warranty of
'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
'GNU General Public License for more details.
'You should have received a copy of the GNU General Public License along
'with this program; if not, write to the Free Software Foundation, Inc.,
'51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Imports System
Imports System.Configuration
Imports System.Web
Imports System.Reflection
Namespace GiDiNet
'ManualBandwidthManagement v1.0
'Author: Daniele Iunco
'Date: 7th May 2007
Public Class ManualBandwidthManagement
Implements IHttpHandler
Private Shared _Settings As BandwidthSettings
Private Shared ReadOnly Property Settings() As BandwidthSettings
Get
If _Settings Is Nothing Then _Settings = New BandwidthSettings()
Return _Settings
End Get
End Property
Private Sub ProcessInvalidRequest(ByRef Context As HttpContext)
'TODO: Qui si potrebbe sviluppare un sistema per notificare gli errori all'amministratore
Context.Response.Redirect(Settings.MissingPageURL)
End Sub
Public Sub ProcessRequest(ByVal Context As HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
Dim myRequestPath As String = Context.Request.Path.ToLower()
'Prelevo la configurazione della directory richiesta, se non la trovo restituisco la pagina di errore
Dim myDirectory As String = Settings.GetDirectory(myRequestPath)
If myDirectory Is Nothing Then
'Se non ho trovato una directory restituisco la pagina di errore
ProcessInvalidRequest(Context)
Exit Sub
End If
'Questo primo controllo serve per evitare di eseguire troppe verifiche inutili:
'Se l'estensione più corta è di 3 caratteri e aggiungo 7 caratteri, la lunghezza del percorso richiesto deve essere per forza maggiore di 10 caratteri (la richiesta è nella forma "/percorso/a.ext.aspx")
If myRequestPath.Length < myDirectory.Length + 10 Then
ProcessInvalidRequest(Context)
Exit Sub
End If
'Preparo la stringa col percorso reale
Dim newPath As String = myDirectory & myRequestPath.Substring(myDirectory.Length)
newPath = newPath.Substring(0, newPath.LastIndexOf("."))
'Reindirizzo la richiesta sul server giusto
Context.Response.Redirect(Settings.GetActiveServer().ServerURL & newPath)
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable
Get
Return True
End Get
End Property
End Class
Public Class RemoteServerInfo
Private _ServerHost As String
Public ReadOnly Property ServerHost() As String
Get
Return _ServerHost
End Get
End Property
Private _ServerURL As String
Public ReadOnly Property ServerURL() As String
Get
Return _ServerURL
End Get
End Property
Public Sub New(ByVal ServerHost As String, ByVal ServerURL As String)
_ServerHost = ServerHost
_ServerURL = ServerURL
End Sub
End Class
Public Class BandwidthSettings
Public ReadOnly Property Servers() As RemoteServerInfo()
Get
Return _Servers
End Get
End Property
Public ReadOnly Property DefaultServer() As RemoteServerInfo
Get
Return _DefaultServer
End Get
End Property
Public ReadOnly Property Directories() As String()
Get
Return _Directories
End Get
End Property
Public ReadOnly Property MissingPageURL() As String
Get
Return _MissingPageURL
End Get
End Property
Public ReadOnly Property ServerCheckClass() As String
Get
Return _ServerCheckClass
End Get
End Property
Private _ServerCheckClass As String
Private _Servers As RemoteServerInfo()
Private _Directories As String()
Private _MissingPageURL As String
Private _DefaultServer As RemoteServerInfo
Public Sub New()
'Caricamento delle varie impostazioni dal file di configurazione
Dim myServerNumberString As String = ConfigurationManager.AppSettings("ManualBandwidthManagement_ServerNumber")
If IsNumeric(myServerNumberString) Then
ReDim _Servers(myServerNumberString - 1)
Else
ReDim _Servers(0)
End If
For i As Integer = 1 To _Servers.Length
Dim tmpItem1, tmpItem2 As String
tmpItem1 = ConfigurationManager.AppSettings("ManualBandwidthManagement_ServerHost_" & i)
tmpItem2 = ConfigurationManager.AppSettings("ManualBandwidthManagement_ServerURL_" & i)
If Not tmpItem1 Is Nothing AndAlso tmpItem1.Length > 0 AndAlso Not tmpItem2 Is Nothing AndAlso tmpItem2.Length > 0 Then
_Servers(i - 1) = New RemoteServerInfo(tmpItem1.Trim.ToLower, tmpItem2)
Else
_Servers(i - 1) = New RemoteServerInfo("", "")
End If
Next
Dim myDirectoryNumberString As String = ConfigurationManager.AppSettings("ManualBandwidthManagement_DirectoryNumber")
If IsNumeric(myDirectoryNumberString) Then
ReDim _Directories(myDirectoryNumberString - 1)
Else
ReDim _Directories(0)
End If
For i As Integer = 1 To _Directories.Length
Dim tmpItem As String
tmpItem = ConfigurationManager.AppSettings("ManualBandwidthManagement_Directory_" & i)
If Not tmpItem Is Nothing AndAlso tmpItem.Length > 0 Then
_Directories(i - 1) = tmpItem
Else
_Directories(i - 1) = "/"
End If
Next
_MissingPageURL = ConfigurationManager.AppSettings("ManualBandwidthManagement_MissingPageURL")
If _MissingPageURL Is Nothing Then _MissingPageURL = "/"
Dim myDefaultServerHost As String = ConfigurationManager.AppSettings("ManualBandwidthManagement_DefaultServerHost")
Dim myDefaultServerURL As String = ConfigurationManager.AppSettings("ManualBandwidthManagement_DefaultServerURL")
If myDefaultServerHost Is Nothing Then myDefaultServerHost = ""
If myDefaultServerURL Is Nothing Then myDefaultServerURL = ""
_DefaultServer = New RemoteServerInfo(myDefaultServerHost, myDefaultServerURL)
_ServerCheckClass = ConfigurationManager.AppSettings("ManualBandwidthManagement_ServerCheckClass")
If _ServerCheckClass Is Nothing Then _ServerCheckClass = "UseDefaultServer"
End Sub
Public Function GetDirectory(ByVal RequestPath As String) As String
If RequestPath Is Nothing Then Return Nothing
'Verifico se la directory della richiesta è una sottodirectory di un percorso protetto, e in questo caso restituisco i parametri di configurazione
For i As Integer = 0 To Directories.Length - 1
If RequestPath.Substring(0, Directories(i).Length) = Directories(i) Then Return Directories(i)
Next
Return Nothing
End Function
Public Function GetActiveServer() As RemoteServerInfo
'Per semplificare il codice e permettere di inserire facilmente nuove modalità di controllo uso la reflection e un'interfaccia
Dim myTestingModule As IServerTestingModule
myTestingModule = Assembly.GetExecutingAssembly.CreateInstance(Me.GetType.FullName & "+" & _ServerCheckClass)
If myTestingModule Is Nothing Then Return _DefaultServer
Return myTestingModule.GetActiveServer(_Servers, _DefaultServer)
End Function
Private Interface IServerTestingModule
Function GetActiveServer(ByVal ServerList As RemoteServerInfo(), ByVal DefaultServer As RemoteServerInfo) As RemoteServerInfo
End Interface
'Di seguito sono riportate 3 classi di esempio da utilizzare per la selezione del server
'Per utilizzare altre modalità è necessario:
'- creare di seguito una classe che implementa l'interfaccia IServerTestingModule
'- inserire il nome della classe come valore di ManualBandwidthManagement_ServerCheckClass del web.config
Private Class UseDefaultServer
Implements IServerTestingModule
'Questa classe seleziona sempre il server predefinito
Public Function GetActiveServer(ByVal ServerList As RemoteServerInfo(), ByVal DefaultServer As RemoteServerInfo) As RemoteServerInfo Implements IServerTestingModule.GetActiveServer
Return DefaultServer
End Function
End Class
Private Class SequentialAccess
Implements IServerTestingModule
'Questa classe si occupa di selezionare i server in modo sequenziale
Private Shared _ServerNumber As Integer
Public Function GetActiveServer(ByVal ServerList As RemoteServerInfo(), ByVal DefaultServer As RemoteServerInfo) As RemoteServerInfo Implements IServerTestingModule.GetActiveServer
If ServerList.Length = 0 Then Return DefaultServer
Dim ServerResult As RemoteServerInfo
If _ServerNumber >= ServerList.Length Then _ServerNumber = 0
ServerResult = ServerList(_ServerNumber)
_ServerNumber += 1
Return ServerResult
End Function
End Class
Private Class FirstAvailable
Implements IServerTestingModule
'Questa classe si occupa di verificare la risposta del server al ping
'Viene selezionato il primo server che risponde al ping nel tempo previsto
Public Function GetActiveServer(ByVal ServerList As RemoteServerInfo(), ByVal DefaultServer As RemoteServerInfo) As RemoteServerInfo Implements IServerTestingModule.GetActiveServer
For i As Integer = 0 To ServerList.Length - 1
If My.Computer.Network.Ping(ServerList(i).ServerHost, 500) Then
Return ServerList(i)
End If
Next
Return DefaultServer
End Function
End Class
End Class
End Namespace
Codice del file /Web.config:
Nota: Se sul server web è già presente un file web.config, modificare il file esistente inserendo le righe indicate in grassetto nelle rispettive sezioni (appSettings e httpHandlers)
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="ManualBandwidthManagement_DefaultServerHost" value="hostname_server_predefinito"></add>
<add key="ManualBandwidthManagement_DefaultServerURL" value="http://www.serverpredefinito.ext"></add>
<add key="ManualBandwidthManagement_ServerNumber" value="3"></add>
<add key="ManualBandwidthManagement_ServerHost_1" value="hostname_primo_server"></add>
<add key="ManualBandwidthManagement_ServerURL_1" value="http://www.primo_server.ext"></add>
<add key="ManualBandwidthManagement_ServerHost_2" value="hostname_secondo_server"></add>
<add key="ManualBandwidthManagement_ServerURL_2" value="http://www.secondo_server.ext"></add>
<add key="ManualBandwidthManagement_ServerHost_3" value="hostname_terzo_server"></add>
<add key="ManualBandwidthManagement_ServerURL_3" value="http://www.terzo_server.ext"></add>
<add key="ManualBandwidthManagement_DirectoryNumber" value="2"></add>
<add key="ManualBandwidthManagement_Directory_1" value="/downloads1/"></add>
<add key="ManualBandwidthManagement_Directory_2" value="/downloads2/"></add>
<add key="ManualBandwidthManagement_MissingPageURL" value="http://www.sitoprincipale.ext/pagina404.htm"></add>
<add key="ManualBandwidthManagement_ServerCheckClass" value="FirstAvailable"/>
</appSettings>
<system.web>
<httpHandlers>
<add verb="GET" path="*.zip.aspx" type="GiDiNet.ManualBandwidthManagement"></add>
</httpHandlers>
</system.web>
</configuration>
2. Configurazione e uso dello script
Per la configurazione è necessario modificare i parametri nel file /Web.config, seguendo le istruzioni riportate di seguito:
Parametri generali:
- ManualBandwidthManagement_DefaultServerHost: Indicare l'indirizzo del server web predefinito.
- ManualBandwidthManagement_DefaultServerURL: Indicare l'url sul server predefinito a cui reindirizzare le richiete.
- ManualBandwidthManagement_MissingPageURL: Indicare l'indirizzo di una pagina web da visualizzare per le richieste verso directory non esistenti.
- ManualBandwidthManagement_ServerCheckClass: Indicare la modalità da utilizzare per la selezione del server, nello script fornito sono gestite le modalità seguenti: (case sensitive)
- UseDefaultServer: Reindirizza tutte le richieste verso il server predefinito
- SequentialAccess: Seleziona i server in modo sequenziale
- FirstAvailable: Seleziona il primo server che risponde a un ping
Selezione dei server:
ManualBandwidthManagement_ServerNumber: indicare il numero di server da utilizzare come mirror.
Per ciascun server è necessario inserire due righe: ManualBandwidthManagement_ServerHost_N e ManualBandwidthManagement_ServerURL_N.
- ManualBandwidthManagement_ServerHost_N: dovrà contenere l'hostname o l'ip del server es. "server001.mioprovider.com" oppure "12.34.56.78"
- ManualBandwidthManagement_ServerURL_N: dovrà contenere l'URL, senza la "/" finale, su cui verrà reindirizzata la richiesta, se si utilizza un proprio dominio tipicamente l'URL sarà nella forma "http://www.miodominio.ext"
Nell'esempio vogliamo usare 3 server:
- "hostname_primo_server" con URL "http://www.primo_server.ext"
- "hostname_secondo_server" con URL "http://www.secondo_server.ext"
- "hostname_terzo_server" con URL "http://www.terzo_server.ext"
Selezione delle directory che possono contenere file da reindirizzare:
ManualBandwidthManagement_DirectoryNumber: indicare il numero delle righe ManualBandwidthManagement_Directory_N e quindi il numero di directory che possono contenere file da reindirizzare.
Per ciascuna directory è necessario inserire una riga: ManualBandwidthManagement_Directory_N, dove N è il numero della directory.
ManualBandwidthManagement_Directory_N dovrà contenere il percorso relativo della directory del server principale che può contenere dei file da reindirizzare.
Selezione delle estensioni di file da reindirizzare:
Sarà necessario una riga <add verb=....></add> seguendo l'esempio, per ciascun tipo di file che può essere reindirizzato.
3. Funzionamento del sistema
Per ciascuna directory selezionata nel file di configurazione, sarà possibile richiamare il modulo per il reindirizzamento aggiungendo .aspx al nome del file da richiamare (ad es. nomefile.zip andrà richiamato come nomefile.zip.aspx)
Non è necessario rinominare i file o effettuare interventi particolari sul server.
Esempio, richiamando "http://www.miodominio.ext/downloads/miodownload.zip.aspx", lo script:
- Trova un mirror valido utilizzando la modalità di verifica selezionata, trovando ad es. "hostname_secondo_server"
- Legge l'URL associato al server appena individuato, trovando http://www.secondo_server.ext
- Reindirizza il visitatore sullo stesso percorso del mirror, quindi su http://www.secondo_server.ext/downloads/miodownload.zip
4. Personalizzazione del sistema
Le istruzioni per la personalizzazione del sistema sono indicate nei commenti del codice.
Nei prossimi script vedremo anche una soluzione automatizzare la creazione dei mirror.
Pubblicato da: Daniele Iunco il 07/04/2007
|
|
|