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:

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 services 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.

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.

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.

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.

*.SPRoutingMachinePool
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!).

*.SPRoutingMachineInfo
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.

*.SPThrottlingRule
These cmdlets allow us to manage Throttling Rules. We create them by passing in the Criteria to evaluate and optionally a Expiration and Threshold.

*.SPRoutingRule
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.

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.

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.

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:

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.

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.

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:

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”.

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.

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 ™”!

Hopefully this will be covered in Part 3. Say we have 5 execution groups in place. Down the road, there is some business requirement that will require us to make a new routing rule. The catch...this rule needs to be placed in its own Execution Policy and it needs to be Execution Policy 1 because the rules are processed in order and this needs to be higher in the list. Is there a way to put this in place without having to blow away and recreate all of the Execution Policies that need to remain, but come after the new rule. Can they be bumped down in the list, or do they need to be recreated from scratch?

Nice write up, Spence. Is it too early to tell what kind of performance hit is involved with each additional rule and guidance around the recommended number of rules per execution group? Feel free to ignore this if you're already covering this in part 3 :)