Introduction
In the first part of this article series I covered the feature capability and provided an architecture overview of Request Management, a new capability introduced with SharePoint Server 2013. Request Management allows SharePoint to understand more about, and control the handling of incoming requests. This second part details an example scenario and provides a step by step of the necessary configuration.
Before we get started, I’d urge you to review Part One. The concepts are very important to grasp before diving in and provisioning stuff. I assume you have read Part One!
Please note that this article applies to SharePoint Server 2013 RTM.
This article series provides comprehensive coverage of the new Request Management capability in three parts:
- Feature Capability and Architecture Overview
- Example Scenario and Configuration Step by Step (this article)
- Deployment Considerations and Recommendations
Example Scenario
In order to provide adequate coverage of the key aspects of Request Management and it’s configuration I have constructed an example scenario. The scenario is deliberately simple, in order to focus only on the Request Management aspects and avoid extraneous details. Furthermore it is a contrived scenario for the purposes of explaining the feature and configuration. I have deliberately made choices so that it is NOT representative of a real world scenario. You wouldn’t implement this exact configuration in a production deployment (or at least I hope you wouldn’t). The idea is that the information provides a solid understanding so that you can configure Request Management to suit the needs of a given deployment.
I have a single SharePoint farm, which I have named “Contoso Farm” and consists of three SharePoint servers (SP01, SP02 & SP03). You could of course do everything on one box, but that is pretty much a pointless exercise if you are interested in Request Management and want to validate that things are working as expected.
The three SharePoint servers will all run the SharePoint Foundation Web Application Service (SPFWAS), which I will refer to as simply “Web Servers”. These Web Servers are all members of a Network Load Balancing cluster. The Web Servers host a single Web Application which will in turn host three Host Named Site Collections (http://www.contoso.com, http://www.fabrikam.com &http://www.adventureworks.com). DNS of course is configured to route those addresses to the VIP of my NLB cluster.
The only service applications deployed in this example are the core farm service applications, namely State Service and the Usage and Health Data Collection Service along with the STS and Topology service of course. There is no need to deploy any other service applications for this scenario.
A quick note on host based sites.
I have chosen to use Host Named Site Collections (HNSC) for this scenario. SharePoint 2013 takes significant strides away from “Path based sites” – the way many are used to working with SharePoint. HNSC or “Host based sites” is a much better approach all-round now that some key limitations have been addressed and allows for far greater scalability, and are a move in the right direction towards dealing with addressing properly in SharePoint. I will almost certainly be posting more on this topic in the future. For the purposes of this article we just need to understand that they are being used, how to create them and how they influence the way SharePoint Web Servers respond to incoming requests.
My contrived business requirements for Request Management are as follows:
- All requests from the OneNote client application should be refused.
- All requests for PDF files should be served by the SP1 and SP2 web servers, regardless of the site collection.
- Other requests for the http://www.fabrikam.com site collection should be served by SP1 and SP2.
- Other requests for the http://www.adventureworks.com site collection should be served by SP1 and SP2.
- Other requests for the http://www.contoso.com site collection should be served by SP3.
These “requirements” allow us to explore the key configuration aspects of Request Management, namely Rules, Execution Groups, Machine Pools and Routing Targets.
The configuration of Request Management to meet these requirements is expressed in the following diagram.
First up the Throttling Rule to deny requests from OneNote is very straightforward. As detailed in part one, Throttling Rules are evaluated before anything else, and therefore are not associated with a Machine pool, nor can we specify their Execution Group. Technically all Throttling Rules are created in Execution Group 0, but from a logical perspective it is appropriate to separate them from Execution Groups.
Our Routing Rules require a little more thought however. If a rule is matched then no further Execution Groups are evaluated. This means we need to ensure that the rule for PDFs is evaluated before the rules for the other requests. To demonstrate this, I have therefore placed this rule in Execution Group 0. Execution Group 1 contains the remaining Routing Rules.
Each rule is associated with one of two Machine Pools. The Primary Machine Pool includes servers SP01 and SP02, whilst the Contoso Machine Pool includes server SP03.
Once again this scenario is very simply but provides enough to be able to demonstrate the configuration and the behaviour of Request Management.
Assumptions
Before we get started with the setup, a warning. For here on out it’s all Windows PowerShell. There is no UI in Central Administration (or anywhere else) for configuring Request Management. Thus I expect you, the reader, to be familiar with core Windows PowerShell concepts and so forth. I will call out any tricks or wackiness that may enter into play.
The base infrastructure for this scenario is five machines (a DC, a SQL server, and three SharePoint Servers). I assume you are able to configure the base infrastructure along with AD, DNS and NLB correctly. Furthermore I start with a SharePoint Farm created and the core service applications provisioned.
OK, enough caveats, let’s get started!
Creating the Web Application and Host Named Site Collections
This is very simple. We don’t need to do anything special here because we are using Request Management, but it is worth covering as Host Named Site Collections, and the behaviour of SharePoint with respect to IIS bindings are not familiar to many SharePoint practitioners.
We obviously need a Web Application running which can respond to requests but we want a single web application to respond to all requests regardless of the host name of the request. Thus we need a web application whose bindings in IIS are listening on “All Unassigned”.
This is simply a matter of setting up some variables, grabbing a Managed Account and then creating the new Web Application. We also need a site collection at the “root”. In a HNSC scenario this won’t ever be accessed by end users, but is a support requirement and best practice to create one.
# App Pool details
$waAppPoolName = "SharePoint Content"
$waAppPoolUserName = "CORP\spcontent"
# Web App details
$hostingMainURL = "http://sp01"
$webAppName = "SharePoint Hosting"
$contentDBName = "ContosoFarm_Content_Hosting"
# get the existing Managed Account
$waManagedAccount = Get -SPManagedAccount $waAppPoolUserName
< # Create a new Web App using Claims (Windows (NTLM)) - Path is set automatically if omitted DefaultProxyGroup is used if omitted - Port 80 will only work if there are no apps on this port unless we specify a host header we do not want a host header, as we will be using host named site collections #>
$authProvider = New -SPAuthenticationProvider
$webApp = New -SPWebApplication -ApplicationPool $waAppPoolName -ApplicationPoolAccount $waManagedAccount -Name $webAppName -Port 80 -AuthenticationProvider $authProvider -DatabaseName $contentDBName
< # Create Site Collection at root This wont ever be accessed by users We do NOT need to create a site from a template, we are creating an Empty site #>
New -SPSite -Url $hostingMainURL -owneralias $ownerAlias -ownerEmail $ownerEmail
|
Now we have a Web Application, we can go ahead and create our Host Named Site Collections (HNSC). Windows PowerShell is the only way to create HNSC, which is somewhat ironic given how badly Microsoft wants us to use them going forward. However it’s very simple, we use New-SPSite as normal but pass in a URL and a HostHeaderWebApplication to use.
I’ve created a simple function to make this repeatable and I’ll also set the Title to make it obvious which site I’m working with when testing.
$hostingMainURL = "http://sp01" function CreateHnsc( $customerName , $customerUrl , $customerAdmin , $customerAdminEmail , $hostingMainURL ) {
# grab the web app
$webApp = Get -SPWebApplication $hostingMainURL # create a HNSC
New -SPSite -url $customerUrl -HostHeaderWebApplication $webApp -owneralias $customerAdmin -owneremail $customerAdminEmail -template sts #0 # Configure Title
$web = Get -SPWeb $customerUrl
$web .Title = $CustomerName
$web .Update()
}# do this for each HNSC
$customerName = "Contoso"
$customerUrl = "http://www.contoso.com"
$customerAdmin = "CORP\Administrator"
$customerAdminEmail = "Admin@corp.contoso.com"
CreateHnsc $customerName $customerUrl $customerAdmin $customerAdminEmail $hostingMainURL
$customerName = "Fabrikam"
$customerUrl = "http://www.fabrikam.com"
$customerAdmin = "CORP\Administrator"
$customerAdminEmail = "Admin@corp.contoso.com"
CreateHnsc $customerName $customerUrl $customerAdmin $customerAdminEmail $hostingMainURL $customerName = "Adventure Works"
$customerUrl = "http://www.adventureworks.com"
$customerAdmin = "CORP\Administrator"
$customerAdminEmail = "Admin@corp.contoso.com"
CreateHnsc $customerName $customerUrl $customerAdmin $customerAdminEmail $hostingMainURL |
At this stage it would be a good idea to test that we can access these HNSC to confirm that they were created correctly, and that our DNS and NLB is in order before continuing.
Starting the Request Management Service Instance
The next step is to start the Request Management service instance. This is a trivial task we can accomplish manually using Services on Server. There is no service application to worry about. It’s also a trivial task in Windows PowerShell using Start-SPServiceInstance. However, as we need the Request Management service instance running on all machines in the farm that run SPFWAS it would be useful to have a reusable snippet that determines which machines should run the service instance and then start it.
I’ve created a couple of helper functions to do the work, and then I simply call them using the appropriate service instance types.
# Start the RM service instance on all machines in the farm which run the WA service instance # we could ofcourse simply pass in an array of servers
# Gets a list of server names for servers running a given service instance type
function GetServersRunningServiceInstance ( $svcType )
{
return get -spserviceinstance | ? {$_.TypeName -eq $svcType -and $_.Status -eq "Online" } | select Server |% {($_.Server.Name)}
}
# Starts a service instance on a given server
function StartServiceInstance ( $svcType , $server ) {
Write-Host ( "Starting " + $svcType + " on " + $server + "..." )
$svc = Get -SPServiceInstance -Server $server | where {$_.TypeName -eq $svcType }
$svc | Start -SPServiceInstance
while ( $svc .Status -ne "Online" )
{
Start-Sleep 2
$svc = Get -SPServiceInstance $svc
}
Write-Host ( "Started " + $svcType + " on " + $server + "!" )
}
$waSvcType = "Microsoft SharePoint Foundation Web Application"
$rmSvcType = "Request Management"
# loop thru servers and start RM..
GetServersRunningServiceInstance $waSvcType | % {StartServiceInstance $rmSvcType $_} |
After this script has run, the end result should be the topology we are after, which is shown below.
Configuring Request Management
Request Management is configured by a collection of Windows PowerShell cmdlets. Before we take a look at the example scenario it's worth summarising the key cmdlets we will be using.
*.SPRequestManagementSettings:
The Get-SPRequestManagementSettings cmdlet returns a SPRequestManagementSettings object for a given Web Application. It’s important to remember that Request Management is Web Application scoped and therefore we have a SPRequestManagementSettings object for each Web Application.
The SPRequestManagementSettings object includes a number of read only properties related to the configuration along with some which are configurable via Set-SPRequestManagementSettings. An example here is ThrottlingEnabled which we can toggle on or off.
We will pass the SPRequestManagementSettings object into the other cmdlets in order to configure Machine Pools, Rules and Routing Targets.
These cmdlets allow us to configure our Machine Pools by creating or adding them, along with a set of Routing Targets to include in that Machine Pool (for which the parameter is named MachineTargets!).
These cmdlets allow us to configure Routing Targets, for example setting the Static Weight for a given server.
New-SPRequestManagementRuleCriteria:
This cmdlet let’s us define our rule criteria for either a Throttling Rule or a Routing Rule. Aside from the match value there are two important parameters. The Property parameter defines the HTTP request property we wish to evaluate (CustomHeader, Host, HttpMethod, IP, SoapAction, Url, UrlReferrer or UserAgent). The MatchType parameter is how we wish to perform the evaluation (EndsWith, Equals, Regex or StartsWith). The there is a Value parameter which is the value we will match against.
These cmdlets allow us to manage Throttling Rules. We create them by passing in the Criteria to evaluate and optionally a Expiration and Threshold.
These cmdlets allow us to manage Routing Rules. We create them by passing in the Criteria to evaluate, a Machine Pool and optionally an Execution Group and Expiration.
Note that there are no cmdlets for working with Execution Groups, these are configured whilst managing Routing Rules.
Let’s now go ahead and implement the example scenario using these cmdlets. The first thing we need to do is grab our SPRequestManagementSettings and place it in a variable for later use.
$waUrl = "http://sp01"
# Get the RM settings for a particular web app.
$wa = Get-SPWebApplication $waUrl
$rmSettings = $wa | Get-SPRequestManagementSettings
We can view the current settings by it’s properties:$rmSettings
Name :
MinimumCacheRefreshTime : 00:00:15
RoutingEnabled : True
RoutingScheme : Default
RequestBufferLength : 524288
MaxRequestBufferCount : 1000
RequestTimeout : 00:01:40
RoutingHealthScoreDepreciationTime : 00:00:02
PingInterval : 00:00:02
PingAvailabilityThreshold : 0.333333333333333
PingFailureLimit : 3
PingPassLimit : 1
ThrottlingEnabled : True
RoutingRules : {}
ThrottlingRules : {}
MachinePools : {}
RoutingTargets : {SP01, SP02, SP03}
IsInitialized : True
TypeName : Microsoft.SharePoint.Administration.SPRequestManagementSettings
DisplayName :
Id : 8136fcee-b2ca-48a1-8b74-370911772b28
Status : Online
Parent : SPWebApplication Name=SharePoint Hosting
Version : 20763
Properties : {}
Farm : SPFarm Name=ContosoFarm_Config
UpgradedPersistedProperties : {}
Note the RoutingRules, ThrottlingRules and MachinePools properties are empty and the RoutingTargets property includes every machine in the farm running SPFWA.
Next we need to create a couple of Machine Pools to match our requirements. We do this by using the SPRoutingMachinePool cmdlets. A key consideration here is that the Set-SPRoutingMachinePool and Add-SPRoutingMachinePool cmdlets expect a MachineTargets parameter (the servers to be included in the Machine Pool). This parameter is a SPRoutingRuleTarget pipe bind.
If our Machine Pool is just a single server this is simple – we can just specify the server name. However if we have multiple servers (as we likely would in a real world scenario) we need to pass in an array of servers.
# Create a Machine Pool with a Name and using an array of Routing Targets
$mpName = "Primary Machine Pool"
$serverNames = @("SP01","SP02")
$mp1 = Add-SPRoutingMachinePool -RequestManagementSettings $rmSettings -Name $mpName -MachineTargets $serverNames
Now we do the same thing to create the second Machine Pool:
# Create a Machine Pool with a Name and using an array of Routing Targets
$mpName = "Contoso Machine Pool"
$serverNames = @("SP03")
$mp1 = Add-SPRoutingMachinePool -RequestManagementSettings $rmSettings -Name $mpName -MachineTargets $serverName
It’s worth noting that the Machine Targets are validated, we can’t pass in a server name which is not a valid Routing Target. We can view the Machine Pool configuration to validate it:
# Display the Machine Pool Configuration
Get-SPRoutingMachinePool -RequestManagementSettings $rmSettings
MachineTargets : {SP03}
PingAvailabilityThreshold : 0.333333333333333
Name : Contoso Machine Pool
TypeName : Microsoft.SharePoint.Administration.SPRoutingMachinePool
DisplayName : Contoso Machine Pool
Id : 0b04d341-4f13-41c8-b90c-19528674a0c1
Status : Online
Parent : SPRequestManagementSettings
Version : 21594
Properties : {}
Farm : SPFarm Name=ContosoFarm_Config
UpgradedPersistedProperties : {}
MachineTargets : {SP01, SP02}
PingAvailabilityThreshold : 0.333333333333333
Name : Primary Machine Pool
TypeName : Microsoft.SharePoint.Administration.SPRoutingMachinePool
DisplayName : Primary Machine Pool
Id : e4b5519f-6256-4dd1-8add-ecf66e5c47fe
Status : Online
Parent : SPRequestManagementSettings
Version : 21570
Properties : {}
Farm : SPFarm Name=ContosoFarm_Config
UpgradedPersistedProperties : {}
We can alter the Static Weighting of a Routing Target at any time, before we add the Target to a Machine Pool or after. We can view the properties of a Routing Target using Get-SPRoutingMachineInfo.
$rmSettings | Get-SPRoutingMachineInfo -Name "SP02"
Availability : Available
StaticWeighting : 1
OutgoingScheme : SameAsIncoming
OutgoingPort :
PingTimeout : 00:00:01
PingEnabled : True
Name : SP02
TypeName : Microsoft.SharePoint.Administration.SPRoutingFarmMachineInfo
DisplayName : SP02
Id : b3efd7c2-422a-446b-8a11-9c1ccfb78020
Status : Online
Parent : SPRequestManagementSettings
Version : 21567
Properties : {}
Farm : SPFarm Name=ContosoFarm_Config
UpgradedPersistedProperties : {}
And modify the Static Weighting:
$rmMachineInfo = $rmSettings | Get-SPRoutingMachineInfo -Name "SP02"
Set-SPRoutingMachineInfo -Identity $rmMachineInfo -StaticWeight 9
Now we have the Machine Pools defined, we can create some rules. This is done by first defining the rule criteria and then adding the rule. First up are Throttling Rules. Again these are not associated with a Machine Pool. This rule refuses requests from the OneNote client based upon the UserAgent property.
# Create a rule criteria, and then add a Throttling Rule
# Throlling Rules dont use a machine pool, threshold is the health score
$criteria = New-SPRequestManagementRuleCriteria -Property UserAgent -MatchType Regex -Value ".*Microsoft Office OneNote 2013*"
$rmSettings | Add-SPThrottlingRule -Name "Refuse OneNote Requests" -Criteria $criteria
We need to be a touch careful when using the Regex MatchType. Often another match type will be more appropriate and remember that regular expressions (especially when badly authored) can be very expensive. Creating a rule criteria with the Regex match type will generate a warning to that effect. Regexs are validated to a degree, invalid syntax will not be accepted but that validation won’t prevent a very badly authored regex with valid syntax. You have been warned!
We can also use the –Threshold parameter on the Add-SPThrottlingRule cmdlet to specify a threshold for the criteria which is based upon the server health score:
$rmSettings
| Add
-SPThrottlingRule
-Name
"Refuse OneNote Requests"
-Criteria
$criteria
-Threshold
8
Moving on to our Routing Rules we follow a similar pattern however we also must associate a Routing Rule with a Machine Pool and we can optionally control the Execution Group. This Routing Rule serves all requests for PDFs from the Primary Machine Pool and is placed in Execution Group 0 to ensure it is evaluated before the other Routing Rules.
# create the Rule Criteria, a regex is semi validated $mpName = "Primary Machine Pool" $ruleName = "Serve all PDF requests from the $mpName" $critera = New-SPRequestManagementRuleCriteria -Property Url -MatchType Regex -Value ".*\.pdf"
# Get the correct Machine Pool $mp = Get-SPRoutingMachinePool -RequestManagementSettings $rmSettings -Name $mpName
# Create the rule, add it to a execution group (0 if omitted) and a Machine Pool, expiry is a time at which to stop that rule $rule = Add-SPRoutingRule -RequestManagementSettings $rmSettings -Name $ruleName -ExecutionGroup 0 -MachinePool $mp -Criteria $critera
|
|
The next Routing Rule will route requests for the www.fabrikam.com HNSC to the Primary Machine Pool. This time we specify Execution Group 1 and we also make use of the Host property and a Match Type of Equals, which is far quicker than a regex.
# create the Rule Criteria
$mpName = "Primary Machine Pool"
$ruleName = "Serve all requests for www.fabrikam.com from the $mpName"
$critera = New-SPRequestManagementRuleCriteria -Property Host -MatchType Equals -Value "www.fabrikam.com"
# Get the correct Machine Pool
$mp = Get-SPRoutingMachinePool -RequestManagementSettings $rmSettings -Name $mpName
# Create the rule, add it to a execution group (0 if omitted) and a Machine Pool, expiry is a time at which to stop that rule
$rule = Add-SPRoutingRule -RequestManagementSettings $rmSettings -Name $ruleName -ExecutionGroup 1 -MachinePool $mp -Criteria $critera
We do the same thing for the remaining Routing Rules for www.adventureworks.com andwww.contoso.com. However for the www.contoso.com rule we specify the Contoso Machine Pool.
# create the Rule Criteria $mpName = "Primary Machine Pool" $ruleName = "Serve all requests for www.adventureworks.com from the $mpName" $critera = New-SPRequestManagementRuleCriteria -Property Host -MatchType Equals -Value "www.adventureworks.com"
# Get the correct Machine Pool $mp = Get-SPRoutingMachinePool -RequestManagementSettings $rmSettings -Name $mpName
# Create the rule, add it to a execution group (0 if omitted) and a Machine Pool, expiry is a time at which to stop that rule $rule = Add-SPRoutingRule -RequestManagementSettings $rmSettings -Name $ruleName -ExecutionGroup 1 -MachinePool $mp -Criteria $critera
# create the Rule Criteria $mpName = "Contoso Machine Pool" $ruleName = "Serve all requests for www.contoso.com from the $mpName" $critera = New-SPRequestManagementRuleCriteria -Property Host -MatchType Equals -Value "www.contoso.com"
# Get the correct Machine Pool $mp = Get-SPRoutingMachinePool -RequestManagementSettings $rmSettings -Name $mpName
# Create the rule, add it to a execution group (0 if omitted) and a Machine Pool, expiry is a time at which to stop that rule $rule = Add-SPRoutingRule -RequestManagementSettings $rmSettings -Name $ruleName -ExecutionGroup 1 -MachinePool $mp -Criteria $critera
|
|
We can validate that our Routing Rules are as we want them:
Get-SPRoutingRule $rmSettings
MachinePool : SPRoutingMachinePool Name=Primary Machine Pool
Name : Serve all PDF requests from the Primary Machine Pool
Criteria : {}
ExecutionGroup : 0
Expiration : 31/12/9999 23:59:59
MachinePool : SPRoutingMachinePool Name=Primary Machine Pool
Name : Serve all requests for www.adventureworks.com from the Primary Machine Pool
Criteria : {}
ExecutionGroup : 1
Expiration : 31/12/9999 23:59:59
MachinePool : SPRoutingMachinePool Name=Contoso Machine Pool
Name : Serve all requests for www.contoso.com from the Contoso Machine Pool
Criteria : {}
ExecutionGroup : 1
Expiration : 31/12/9999 23:59:59
MachinePool : SPRoutingMachinePool Name=Primary Machine Pool
Name : Serve all requests for www.fabrikam.com from the Primary Machine Pool
Criteria : {}
ExecutionGroup : 1
Expiration : 31/12/9999 23:59:59
With respect to Routing Rules we need to be a touch careful. A single Routing Rule can be added to multiple Execution Groups. That might be necessary but we should think long and hard about whether it’s a good idea. It is also possible to add a Routing Rule to Execution Group 26, which of course does not exist. Routing Rules planning is paramount!
We can also view the overall settings again from the SPRequestManagementSettings:
$rmSettings
Name :
MinimumCacheRefreshTime : 00:00:15
RoutingEnabled : True
RoutingScheme : Default
RequestBufferLength : 524288
MaxRequestBufferCount : 1000
RequestTimeout : 00:01:40
RoutingHealthScoreDepreciationTime : 00:00:02
PingInterval : 00:00:02
PingAvailabilityThreshold : 0.333333333333333
PingFailureLimit : 3
PingPassLimit : 1
ThrottlingEnabled : True
RoutingRules : {Serve all PDF requests from the Primary Machine Pool, Serve all requests for www.adventureworks.com from the Primary Machine Pool, Serve all requests
for www.contoso.com from the Contoso Machine Pool, Serve all requests for www.fabrikam.com from the Primary Machine Pool}
ThrottlingRules : {Refuse OneNote Requests}
MachinePools : {Contoso Machine Pool, Primary Machine Pool}
RoutingTargets : {SP01, SP02, SP03}
IsInitialized : True
TypeName : Microsoft.SharePoint.Administration.SPRequestManagementSettings
DisplayName :
Id : 8136fcee-b2ca-48a1-8b74-370911772b28
Status : Online
Parent : SPWebApplication Name=SharePoint Hosting
Version : 20763
Properties : {}
Farm : SPFarm Name=ContosoFarm_Config
UpgradedPersistedProperties : {}
At this point our Request Management configuration is complete and we can move on to testing the capability is working as expected.
It’s worth pointing out at this stage how well factored and implemented these cmdlets are. On initial inspection things seem a little disjointed, but they really do work very well and once the core concepts are grasped are very easy to work with. As regular readers will be aware certain aspects of SharePoint’s PowerShell are most certainly not up to this quality bar! Like many areas (e.g. multi tenancy) the playbook is essential to understand how they should be best used.
Validation and Testing
Now for the moment of truth as it were. We shouldn’t (obviously :)) just assume the system is working as we expect and we need to test everything is in order.
Open up OneNote 2013 and from the File Open dialog box attempt to open http://www.contoso.com. After a slight delay we will see the following:
Looks good so far, but frankly that error message could be the result of a couple dozen different things. Let’s crack open our old and trusty friend ULSViewer on one of the SharePoint machines (hint: in an NLB cluster in a single user testing scenario it will always be the one with an NLB priority of 1, in my case SP01). Load up the current ULS and filter on a Category of “Request Management”.
1 |
08/08/2012 04:21:04.43 w3wp.exe (0x0CE8) 0x13E0 SharePoint Foundation Request Management adc7u Medium Mapping URI from 'http://www.contoso.com:80/' to 'http://SP03/' cc66c19b-f5e9-1003-363b-668bca8e184f |
2 |
08/08/2012 04:21:04.44 w3wp.exe (0x0CE8) 0x09C4 SharePoint Foundation Request Management adc7u Medium Mapping URI from 'http://www.contoso.com:80/' to 'http://SP03/' cc66c19b-e5eb-1003-363b-6e2753de8f15 |
3 |
08/08/2012 04:21:06.86 w3wp.exe (0x0CE8) 0x1118 SharePoint Foundation Request Management aaz9o Medium The request has been throttled by the throttling rules cd66c19b-1582-1003-363b-6912a23bd168 |
4 |
08/08/2012 04:21:06.88 w3wp.exe (0x0CE8) 0x13FC SharePoint Foundation Request Management aaz9o Medium The request has been throttled by the throttling rules cd66c19b-0584-1003-363b-6258a51eae26 |
Note that the request is actually mapped to the correct Routing Target (SP03) but then is throttled (lines 5 & 6).
If we perform every SharePoint practitioners favourite command IISRESET on the Web Server and then request www.adventureworks.com from a browser we can see the Request Management Activity.
01 |
08/08/2012 04:28:45.86 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management aer40 High [Forced due to logging gap, cached @ 08/08/2012 04:28:45.81, Original Level: VerboseEx] Adding new execution group to evaluator '{0}' 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
02 |
08/08/2012 04:28:45.86 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management aaz9f High [Forced due to logging gap, Original Level: VerboseEx] Lookup helper adding Regex rule '{0}' 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
03 |
08/08/2012 04:28:45.94 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management aer48 High [Forced due to logging gap, cached @ 08/08/2012 04:28:45.89, Original Level: VerboseEx] Evaluating rules for execution group '{0}' 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
04 |
08/08/2012 04:28:45.94 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management aer48 High [Forced due to logging gap, Original Level: VerboseEx] Evaluating rules for execution group '{0}' 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
05 |
08/08/2012 04:28:46.05 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management aaz9n High [Forced due to logging gap, cached @ 08/08/2012 04:28:46.03, Original Level: Verbose] Unthrottled routing target count: {0} 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
06 |
08/08/2012 04:28:46.05 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management aaz91 High [Forced due to logging gap, Original Level: VerboseEx] Target count to load balance for this request: {0} 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
08 |
08/08/2012 04:28:46.17 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management adc7x High [Forced due to logging gap, cached @ 08/08/2012 04:28:46.16, Original Level: VerboseEx] Copying request header '{0}' with value '{1}' 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
09 |
08/08/2012 04:28:46.17 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management adc72 High [Forced due to logging gap, Original Level: VerboseEx] Setting request KeepAlive to '{0}' 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
10 |
08/08/2012 04:28:48.18 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management aeboc High [Forced due to logging gap, cached @ 08/08/2012 04:28:46.20, Original Level: Verbose] No data was found on the incoming client request 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
11 |
08/08/2012 04:28:48.18 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management advu0 High [Forced due to logging gap, Original Level: Verbose] Server challenged request: '{0}' 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
12 |
08/08/2012 04:28:48.26 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management adc8e High [Forced due to logging gap, cached @ 08/08/2012 04:28:48.20, Original Level: VerboseEx] Setting response StatusDescription to '{0}' 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
13 |
08/08/2012 04:28:48.26 w3wp.exe (0x12F0) 0x0BF0 SharePoint Foundation Request Management accci High [Forced due to logging gap, Original Level: VerboseEx] Machine affinity required for this request 3b67c19b-f584-1003-363b-69dd6f6f1c7c |
16 |
08/08/2012 04:29:37.51 w3wp.exe (0x12F0) 0x11FC SharePoint Foundation Request Management aeboc High [Forced due to logging gap, cached @ 08/08/2012 04:29:13.72, Original Level: Verbose] No data was found on the incoming client request 4467c19b-d55f-1003-363b-64374e6bcd1a |
18 |
08/08/2012 04:29:37.57 w3wp.exe (0x12F0) 0x1118 SharePoint Foundation Request Management ai2q4 Medium Unavailable machines based on ping results: SP01 4a67c19b-a531-1003-363b-6410b47d9c5d |
22 |
08/08/2012 04:31:07.01 w3wp.exe (0x12F0) 0x13E0 SharePoint Foundation Request Management aeboc High [Forced due to logging gap, cached @ 08/08/2012 04:29:37.60, Original Level: Verbose] No data was found on the incoming client request 4a67c19b-8534-1003-363b-67437ce81a69 |
The Request Manager fires up and loads the Execution Groups and Rules, and then the incoming request is processed, in this case mapped to the Routing Target SP01 and then a bunch of Mappings are processed for each of the elements of the page.
We can do the same thing for other requests to www.contoso.com and www.fabrikam.com and we will see the request being served from the correct hosts.
As a further check we can look at the IIS log files. One thing immediately obvious is the Request Management ping mechanism (SPPING) used to ascertain if a Routing Target is available:
1 |
2012-08-08 03:11:50 fe80::6caa:fd16:46e5:d3d4 % 14 SPPING / - 80 - fe80::6caa:fd16:46e5:d3d4 % 14 - 200 0 0 0 |
2 |
2012-08-08 03:11:52 fe80::6caa:fd16:46e5:d3d4 % 14 SPPING / - 80 - fe80::6caa:fd16:46e5:d3d4 % 14 - 200 0 0 0 |
3 |
2012-08-08 03:11:54 fe80::6caa:fd16:46e5:d3d4 % 14 SPPING / - 80 - fe80::6caa:fd16:46e5:d3d4 % 14 - 200 0 0 0 |
4 |
2012-08-08 03:11:56 fe80::6caa:fd16:46e5:d3d4 % 14 SPPING / - 80 - fe80::6caa:fd16:46e5:d3d4 % 14 - 200 0 0 0 |
5 |
2012-08-08 03:11:58 fe80::6caa:fd16:46e5:d3d4 % 14 SPPING / - 80 - fe80::6caa:fd16:46e5:d3d4 % 14 - 200 0 0 0 |
6 |
2012-08-08 03:12:00 fe80::6caa:fd16:46e5:d3d4 % 14 SPPING / - 80 - fe80::6caa:fd16:46e5:d3d4 % 14 - 200 0 0 0 |
7 |
2012-08-08 03:12:02 fe80::6caa:fd16:46e5:d3d4 % 14 SPPING / - 80 - fe80::6caa:fd16:46e5:d3d4 % 14 - 200 0 0 0 |
8 |
2012-08-08 03:12:04 fe80::6caa:fd16:46e5:d3d4 % 14 SPPING / - 80 - fe80::6caa:fd16:46e5:d3d4 % 14 - 200 0 0 0 |
But there are no entries for any www.contoso.com requests. I have to move to the SP03 machine’s log files to see those.
The last thing rule we need to check is the PDF rule. If we browse to a document library on thewww.contoso.com site and then attempt to download a PDF file we will see the following in the ULS:
01 |
08/08/2012 04:42:41.87 w3wp.exe (0x12F0) 0x0EE8 SharePoint Foundation Request Management adc7u Medium Mapping URI from 'http://www.contoso.com:80/' to 'http://SP03/' 0968c19b-35aa-1003-363b-6a42d60cd9ab |
02 |
08/08/2012 04:42:41.88 w3wp.exe (0x12F0) 0x12D4 SharePoint Foundation Request Management adc7u Medium Mapping URI from 'http://www.contoso.com:80/' to 'http://SP03/' 0968c19b-15ae-1003-363b-614c3cf3b89f |
03 |
08/08/2012 04:42:41.90 w3wp.exe (0x12F0) 0x0938 SharePoint Foundation Request Management adc7u Medium Mapping URI from 'http://www.contoso.com:80/' to 'http://SP03/' 0968c19b-15af-1003-363b-697b58753238 |
06 |
08/08/2012 04:42:42.18 w3wp.exe (0x12F0) 0x1348 SharePoint Foundation Request Management aeboc High [Forced due to logging gap, cached @ 08/08/2012 04:42:41.99, Original Level: Verbose] No data was found on the incoming client request 0968c19b-f5b3-1003-363b-6ec509b4389e |
08 |
08/08/2012 04:42:44.30 w3wp.exe (0x12F0) 0x1314 SharePoint Foundation Request Management aeboc High [Forced due to logging gap, cached @ 08/08/2012 04:42:44.19, Original Level: Verbose] No data was found on the incoming client request 0a68c19b-653d-1003-363b-69b4d6f8912c |
12 |
08/08/2012 04:42:50.92 w3wp.exe (0x12F0) 0x0874 SharePoint Foundation Request Management advuz Medium Client disconnected before request finished processing 0b68c19b-a5e0-1003-363b-6cfe0a87b6d8 |
13 |
08/08/2012 04:42:54.90 w3wp.exe (0x12F0) 0x09A0 SharePoint Foundation Request Management aeboc High [Forced due to logging gap, cached @ 08/08/2012 04:42:50.92, Original Level: Verbose] No data was found on the incoming client request 0b68c19b-a5e2-1003-363b-6398666467f8 |
14 |
08/08/2012 04:42:54.99 w3wp.exe (0x12F0) 0x09A0 SharePoint Foundation Request Management adc8e High [Forced due to logging gap, cached @ 08/08/2012 04:42:54.90, Original Level: VerboseEx] Setting response StatusDescription to '{0}' 0b68c19b-a5e2-1003-363b-6398666467f8 |
As expected, the initial requests to the site and document library are served from SP03, but the PDF download is being served from SP01.
If we go ahead and stop the W3SVC service on SP01 and then request www.fabrikam.com we will see the following in the ULS for SP02:
01 |
08/08/2012 04:50:09.87 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management aer48 High [Forced due to logging gap, cached @ 08/08/2012 04:50:09.82, Original Level: VerboseEx] Evaluating rules for execution group '{0}' 7768c19b-6506-1003-ad61-6117a7f3fccd |
02 |
08/08/2012 04:50:09.87 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management aer48 High [Forced due to logging gap, Original Level: VerboseEx] Evaluating rules for execution group '{0}' 7768c19b-6506-1003-ad61-6117a7f3fccd |
03 |
08/08/2012 04:50:09.98 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management aer5d High [Forced due to logging gap, cached @ 08/08/2012 04:50:09.93, Original Level: VerboseEx] Evaluating rules for execution group '{0}' 7768c19b-6506-1003-ad61-6117a7f3fccd |
04 |
08/08/2012 04:50:09.98 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management aa0a4 High [Forced due to logging gap, Original Level: VerboseEx] Lookup helper lowest threshold for request is '{0}' 7768c19b-6506-1003-ad61-6117a7f3fccd |
05 |
08/08/2012 04:50:10.04 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management adc7u Medium Mapping URI from 'http://www.fabrikam.com:80/' to 'http://SP01/' 7768c19b-6506-1003-ad61-6117a7f3fccd |
06 |
08/08/2012 04:50:10.10 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management agmky High [Forced due to logging gap, cached @ 08/08/2012 04:50:10.09, Original Level: Verbose] Existing correlation ID found '{0}' , adding header to outgoing request 7768c19b-6506-1003-ad61-6117a7f3fccd |
07 |
08/08/2012 04:50:10.10 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management aa0ak High [Forced due to logging gap, Original Level: Verbose] Attempting to send data with method '{0}' to server 7768c19b-6506-1003-ad61-6117a7f3fccd |
08 |
08/08/2012 04:50:31.16 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management aeboc High [Forced due to logging gap, cached @ 08/08/2012 04:50:10.10, Original Level: Verbose] No data was found on the incoming client request 7768c19b-6506-1003-ad61-6117a7f3fccd |
09 |
08/08/2012 04:50:31.16 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management aa0al High Proxy response returned error: 'Unable to connect to the remote server' 7768c19b-6506-1003-ad61-6117a7f3fccd |
10 |
08/08/2012 04:50:31.16 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management acccm Unexpected Proxy request does not contain a response 7768c19b-6506-1003-ad61-6117a7f3fccd |
11 |
08/08/2012 04:50:31.32 w3wp.exe (0x04A8) 0x04B0 SharePoint Foundation Request Management ai2q4 Medium Unavailable machines based on ping results: SP01 7c68c19b-d549-1003-ad61-6de197d9d1f0 |
13 |
08/08/2012 04:50:31.38 w3wp.exe (0x04A8) 0x0B54 SharePoint Foundation Request Management adc8e High [Forced due to logging gap, cached @ 08/08/2012 04:50:31.35, Original Level: VerboseEx] Setting response StatusDescription to '{0}' 7c68c19b-d549-1003-ad61-6de197d9d1f0 |
14 |
08/08/2012 04:51:01.07 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management ai2q4 Medium Unavailable machines based on ping results: SP01 8368c19b-258d-1003-ad61-66cd2d751bb9 |
15 |
08/08/2012 04:51:01.07 w3wp.exe (0x04A8) 0x0C18 SharePoint Foundation Request Management adc7u Medium Mapping URI from 'http://www.fabrikam.com:80/' to 'http://SP02/' 8368c19b-258d-1003-ad61-66cd2d751bb9 |
16 |
08/08/2012 04:51:05.97 w3wp.exe (0x04A8) 0x0BAC SharePoint Foundation Request Management adc7u Medium Mapping URI from 'http://www.fabrikam.com:80/' to 'http://SP02/' 8468c19b-55bf-1003-ad61-6c37aca5eba0 |
17 |
08/08/2012 04:51:05.98 w3wp.exe (0x04A8) 0x0FC4 SharePoint Foundation Request Management adc7u Medium Mapping URI from 'http://www.fabrikam.com:80/' to 'http://SP02/' 8468c19b-45c0-1003-ad61-6dc8d19c7344 |
18 |
08/08/2012 04:51:06.05 w3wp.exe (0x04A8) 0x0FC4 SharePoint Foundation Request Management aeboc High [Forced due to logging gap, cached @ 08/08/2012 04:51:05.98, Original Level: Verbose] No data was found on the incoming client request 8468c19b-45c0-1003-ad61-6dc8d19c7344 |
19 |
08/08/2012 04:51:06.05 w3wp.exe (0x04A8) 0x0FC4 SharePoint Foundation Request Management aht6j High [Forced due to logging gap, Original Level: Verbose] Proxy response duration: WFE '{0}' , RM '{1}' 8468c19b-45c0-1003-ad61-6dc8d19c7344 |
21 |
08/08/2012 04:51:06.06 w3wp.exe (0x04A8) 0x0F1C SharePoint Foundation Request Management ai2q4 Medium Unavailable machines based on ping results: SP01 8468c19b-25c5-1003-ad61-6f5faa677d34 |
23 |
08/08/2012 04:51:07.36 w3wp.exe (0x04A8) 0x0F1C SharePoint Foundation Request Management aeboc High [Forced due to logging gap, cached @ 08/08/2012 04:51:06.06, Original Level: Verbose] No data was found on the incoming client request 8468c19b-25c5-1003-ad61-6f5faa677d34 |
24 |
08/08/2012 04:51:07.40 w3wp.exe (0x04A8) 0x0B10 SharePoint Foundation Request Management ai2q4 Medium Unavailable machines based on ping results: SP01 8568c19b-0519-1003-ad61-68c7de1c60d5 |
26 |
08/08/2012 04:51:07.70 w3wp.exe (0x04A8) 0x0B10 SharePoint Foundation Request Management aeboc High [Forced due to logging gap, cached @ 08/08/2012 04:51:07.40, Original Level: Verbose] No data was found on the incoming client request 8568c19b-0519-1003-ad61-68c7de1c60d5 |
Initially the request is mapped to SP01 but it soon figures out that SP01 is unavailable as it is not responding to the SPPING and goes on to map the request to SP02.
That wraps up our testing and validation. As you can see it’s a very nice capability indeed.
Conclusion
In this the second part of the Request Management article series I have shown you the money, providing a simple example scenario and covered the end to end configuration of Request Management for that scenario along with some testing and validation steps. Hopefully this example shows you the power and flexibility of Request Management in SharePoint Server 2013 Preview. Stay tuned for the final part (coming soon) in which I will cover some real world deployment considerations and recommendations. In the meantime, remember the golden rule of SharePoint, “Just because you can, doesn’t mean you should !"
$waAppPoolName
=
"SharePoint Content"