SharePoint Farm, Virtual Server and Network Load Balancing

April 13th, 2007 by adrh

I had reason this week to test our WISDOM DMF products operation in a Load Balanced SharePoint environment.

The outcome was very successful and surprising easy to achieve, especially given my previous level or Load Balancing – which was VERY limited, but there were a few thing I learnt that I thought the story was interesting enough to share…

Because I didn't have two physical machines that I felt like re-purposing for a bit of testing I created two fresh Windows 2003 Server Virtual Server machines, called mvwssloadbalanced1 and mvwssloadbalanced2 on our Virtual Server machine.

 

I configured two Virtual Networks on the servers which I believe is required to use the Unicast Cluster Operation Mode as opposed to Multicast which can be used with one Network Interface.

 

It really amounts to the same outcome, just different physical operation (which you can google if you've a mind) but I wanted to replicate a certain configuration. In reality I actually tested both Unicast and Multicast configuration with the same results.

 

Once I had Windows installed I installed SharePoint Services on one of the machines and created a new Farm. Then I extended a SharePoint web application onto the Default IIS web site (root) and created a root site collection on it. When extending the web application there is an option to set the load balanced URL which you need to set (in our case http://mvcluster.macroview.com.au) because by default it uses the machine URL – which I imagine will not work because there will not be any alternate access mapping (see the previous Blog entry on AAM's) created for the load balanced URL. 

 

Next I installed WSS onto the second machine using the default settings – which was a mistake. The defaults do not install the Central Admin web site onto additional servers in the Farm. I fell for this one, because whenever I've come to the last screen of the SharePoint Products and Technologies Configuration Wizard which has the Advanced button on it I've ignored it (because it didn't contain anything interesting)! So, click the button and check the box that installs the central admin site on the additional servers in the farm.

 

This might not be an issue for some (perhaps your) situations, but for us, we have an admin operation that we have added to the Operations tab of Central Admin that needs access to the physical server. If you don't have Central Admin installed on all of the servers then you'll always end up physically on the first server in the farm.

 

In practice, adding the Central Admin Console to all the servers (or at least more than 1) is not a bad idea, because if you don't put it on other servers, then it would'nt be Load Balanced and if the primary server dies, you won't be able to get there! Smile

 

So then I installed our application, which consists of Features, Pages, Web Services etc and is packaged in a SharePoint Solution. This was very cool, because the installation on the Farm deployment was exactly the same as single server:

 

stsadm -o addsolution -filename .

 

Then go to Manage Solutions in the Operations tab of Central Admin and click Deploy! Viola – solution deployed to all servers in the Farm with a single click.

 

Our client application connects to a custom web service in _vti_bin to communicate with SharePoint and so pointing it at the Load Balanced URL worked fine.

Shutting down one of the servers in the cluster from the NLB console resulted in the other server processing the requests as expected. Of course if the server was shutdown in the middle of a call (which you can actually avoid by using a shutdown option to drain all current requests), or just as you made the call some errors were seen, but once the general result was fine.

 

Note that this result is dependent to some degree on configuration in that it is possible to set Affinity on the cluster such that a client's requests are serviced by the same server each time and if that actual server goes down or is shut down using the NLB console, then future requests will fail. However, I believe that Affinity set to none is best for performance and fine when you don't need to manage state.

 

When I shut down a web site or application pool using the IIS console I did get intermittent connection and usage errors caused by failure to connect to the web service. Shutting down services and pools like this causes symptoms similar to a failure that might happen if the web application causes too many errors (say for example there is some faulty memory or something, but not catastrophic hardware failure) and is shut down by IIS. It should be noted that this behaviour is consistent with SharePoint and SharePoint Web Services in general, in that you get intermittent browser connection failures in this situation.

 

This is because NLB does not provide failover for applications or servers only for failure of the server itself - meaning it will not poll a machine to check that a particular service or facility is available and drop the box from the NLB cluster if it does not respond. Therefore requests are still sent to the stopped web site/application pool as they would normally unless a monitoring application is configured to remove servers from the cluster under certain circumstances. NLB provides the services required by monitoring applications to remove servers from the cluster remotely. For example a monitor could be set up to check that a certain web site or application pool responds and remove the server from the cluster if it does not. I think that Microsoft Operations Manager with the SharePoint MOM Pack might assist in this regard and I am about to find out…

 

So, I'm pretty happy with the ease with which SharePoint (and our application) was able to be configured by someone who has never configured a NLB SharePoint environment before.

For more details on the architecture, configurations and features in relation to NLB there is some good information about NLB on TechNet.

SharePoint Farm, Virtual Server and Network Load Balancing

April 13th, 2007 by adrh

I had reason this week to test our WISDOM DMF products operation in a Load Balanced SharePoint environment.

The outcome was very successful and surprising easy to achieve, especially given my previous level or Load Balancing – which was VERY limited, but there were a few thing I learnt that I thought the story was interesting enough to share…

Because I didn't have two physical machines that I felt like re-purposing for a bit of testing I created two fresh Windows 2003 Server Virtual Server machines, called mvwssloadbalanced1 and mvwssloadbalanced2 on our Virtual Server machine.

 

I configured two Virtual Networks on the servers which I believe is required to use the Unicast Cluster Operation Mode as opposed to Multicast which can be used with one Network Interface.

 

It really amounts to the same outcome, just different physical operation (which you can google if you've a mind) but I wanted to replicate a certain configuration. In reality I actually tested both Unicast and Multicast configuration with the same results.

 

Once I had Windows installed I installed SharePoint Services on one of the machines and created a new Farm. Then I extended a SharePoint web application onto the Default IIS web site (root) and created a root site collection on it. When extending the web application there is an option to set the load balanced URL which you need to set (in our case http://mvcluster.macroview.com.au) because by default it uses the machine URL – which I imagine will not work because there will not be any alternate access mapping (see the previous Blog entry on AAM's) created for the load balanced URL. 

 

Next I installed WSS onto the second machine using the default settings – which was a mistake. The defaults do not install the Central Admin web site onto additional servers in the Farm. I fell for this one, because whenever I've come to the last screen of the SharePoint Products and Technologies Configuration Wizard which has the Advanced button on it I've ignored it (because it didn't contain anything interesting)! So, click the button and check the box that installs the central admin site on the additional servers in the farm.

 

This might not be an issue for some (perhaps your) situations, but for us, we have an admin operation that we have added to the Operations tab of Central Admin that needs access to the physical server. If you don't have Central Admin installed on all of the servers then you'll always end up physically on the first server in the farm.

 

In practice, adding the Central Admin Console to all the servers (or at least more than 1) is not a bad idea, because if you don't put it on other servers, then it would'nt be Load Balanced and if the primary server dies, you won't be able to get there! Smile

 

So then I installed our application, which consists of Features, Pages, Web Services etc and is packaged in a SharePoint Solution. This was very cool, because the installation on the Farm deployment was exactly the same as single server:

 

stsadm -o addsolution -filename .

 

Then go to Manage Solutions in the Operations tab of Central Admin and click Deploy! Viola – solution deployed to all servers in the Farm with a single click.

 

Our client application connects to a custom web service in _vti_bin to communicate with SharePoint and so pointing it at the Load Balanced URL worked fine.

Shutting down one of the servers in the cluster from the NLB console resulted in the other server processing the requests as expected. Of course if the server was shutdown in the middle of a call (which you can actually avoid by using a shutdown option to drain all current requests), or just as you made the call some errors were seen, but once the general result was fine.

 

Note that this result is dependent to some degree on configuration in that it is possible to set Affinity on the cluster such that a client's requests are serviced by the same server each time and if that actual server goes down or is shut down using the NLB console, then future requests will fail. However, I believe that Affinity set to none is best for performance and fine when you don't need to manage state.

 

When I shut down a web site or application pool using the IIS console I did get intermittent connection and usage errors caused by failure to connect to the web service. Shutting down services and pools like this causes symptoms similar to a failure that might happen if the web application causes too many errors (say for example there is some faulty memory or something, but not catastrophic hardware failure) and is shut down by IIS. It should be noted that this behaviour is consistent with SharePoint and SharePoint Web Services in general, in that you get intermittent browser connection failures in this situation.

 

This is because NLB does not provide failover for applications or servers only for failure of the server itself - meaning it will not poll a machine to check that a particular service or facility is available and drop the box from the NLB cluster if it does not respond. Therefore requests are still sent to the stopped web site/application pool as they would normally unless a monitoring application is configured to remove servers from the cluster under certain circumstances. NLB provides the services required by monitoring applications to remove servers from the cluster remotely. For example a monitor could be set up to check that a certain web site or application pool responds and remove the server from the cluster if it does not. I think that Microsoft Operations Manager with the SharePoint MOM Pack might assist in this regard and I am about to find out…

 

So, I'm pretty happy with the ease with which SharePoint (and our application) was able to be configured by someone who has never configured a NLB SharePoint environment before.

For more details on the architecture, configurations and features in relation to NLB there is some good information about NLB on TechNet.

Adding SharePoint 2007 Search to the Search Providers in Internet Explorer 7

April 12th, 2007 by adrh

IE 7 allows you to add as many search providers as you like into your search box. While you can add all the usual suspects – Live, Google, Yahoo etc, you can also add SharePoint Search servers:

Open IE and drop down the menu on the search box:

Click on 'Find More Providers'. This will take you to a page that allows you to either select from one of the known Search providers or add your own, given the URL for it. To add MOSS, enter the URL for a search for the word TEST (as it says on the right-hand side of the page).

   

For example, for me the URL is:

http://moss.macroview.com.au/SearchCenter/Pages/results.aspx?k=TEST

You can automate this process for your users by generating the XML and adding a Link tag into the Head of a web page.

There is an article on MSDN that shows how to do this.

 

 

 

Adding SharePoint 2007 Search to the Search Providers in Internet Explorer 7

April 12th, 2007 by adrh

IE 7 allows you to add as many search providers as you like into your search box. While you can add all the usual suspects – Live, Google, Yahoo etc, you can also add SharePoint Search servers:

Open IE and drop down the menu on the search box:

Click on 'Find More Providers'. This will take you to a page that allows you to either select from one of the known Search providers or add your own, given the URL for it. To add MOSS, enter the URL for a search for the word TEST (as it says on the right-hand side of the page).

   

For example, for me the URL is:

http://moss.macroview.com.au/SearchCenter/Pages/results.aspx?k=TEST

You can automate this process for your users by generating the XML and adding a Link tag into the Head of a web page.

There is an article on MSDN that shows how to do this.

 

 

 

Excluding Content Types from Search Results

March 28th, 2007 by adrh

I received a question recently about excluding certain items from the search results and thought it was worth a post. There are two main options that I thought of when asked.

Firstly, editing the XSL on the Core Results web part that controls the format of the returned results. This works fine for actually hiding the items, for example, you can wrap the results display part of the XML in an xsl:if to exclude the current item:

<xsl:if test="contenttype='Contract'">

(assuming you have contenttype included in the Selected Columns XML within the Core Results web part)

The reason why this is not such a great idea is that the web part that displays the results statistics will still include the items in the count and seeing as you cannot access the hidden control that binds the web parts together and can't change the output of the Statistics web part you cannot change that.

The best way is to limit the results based on Scope. Either by creating a separate Scope that can be used when searching or by modifying the default Scope used, ie. All Sites.

First you need to make sure that the Managed Property you want to limit the Scope with is allowed to be used in scopes. To do this go to Central Admin, Shared Services Admin for the SSP in question, Search Settings, Meta-data Property Mappings. Then edit the Managed Property and check the 'Allow this property to be used in scopes' check box:

Next, you need to add a new rule to the Scope to Exclude the items based on the value for the Managed Property. Go back to Search Settings, Click on View Scopes and then edit the scope you want to change. Click Add new Rule and create a Property Query rule that is set the to Exclude items where the property you modified above is equal to the value you want to exclude. For example to exclude Folders from search results:

(note that if you're interested in excluding folders, the above works in SharePoint, but you'll need to do something more for file shares – see Scott Jamisons's post)

Then make sure that you run the Update Scopes option so that the change to Scope takes effect.

I'm not 100% sure, but I think that if you have not had a Scope based on this Managed Property (or it might be if you enable the Managed Property for use in Scopes) you may need to do a Full Crawl to have this all work properly.

Also, if you check the 'Show Scope Picker' option in the Advanced Search Box web part, and you have created a new scope for the Exclusion to apply to, the user can select that Scope when searching. 

Be aware when doing all this that the will be a price to pay somewhere if you have a lot of Scopes defined in this way (even if it's only in confusing the user!), and that if you need really custom restrictions, perhaps you are better off with a custom search solution tailored for the way that the users need to search!

 

Excluding Content Types from Search Results

March 28th, 2007 by adrh

I received a question recently about excluding certain items from the search results and thought it was worth a post. There are two main options that I thought of when asked.

Firstly, editing the XSL on the Core Results web part that controls the format of the returned results. This works fine for actually hiding the items, for example, you can wrap the results display part of the XML in an xsl:if to exclude the current item:

<xsl:if test="contenttype='Contract'">

(assuming you have contenttype included in the Selected Columns XML within the Core Results web part)

The reason why this is not such a great idea is that the web part that displays the results statistics will still include the items in the count and seeing as you cannot access the hidden control that binds the web parts together and can't change the output of the Statistics web part you cannot change that.

The best way is to limit the results based on Scope. Either by creating a separate Scope that can be used when searching or by modifying the default Scope used, ie. All Sites.

First you need to make sure that the Managed Property you want to limit the Scope with is allowed to be used in scopes. To do this go to Central Admin, Shared Services Admin for the SSP in question, Search Settings, Meta-data Property Mappings. Then edit the Managed Property and check the 'Allow this property to be used in scopes' check box:

Next, you need to add a new rule to the Scope to Exclude the items based on the value for the Managed Property. Go back to Search Settings, Click on View Scopes and then edit the scope you want to change. Click Add new Rule and create a Property Query rule that is set the to Exclude items where the property you modified above is equal to the value you want to exclude. For example to exclude Folders from search results:

(note that if you're interested in excluding folders, the above works in SharePoint, but you'll need to do something more for file shares – see Scott Jamisons's post)

Then make sure that you run the Update Scopes option so that the change to Scope takes effect.

I'm not 100% sure, but I think that if you have not had a Scope based on this Managed Property (or it might be if you enable the Managed Property for use in Scopes) you may need to do a Full Crawl to have this all work properly.

Also, if you check the 'Show Scope Picker' option in the Advanced Search Box web part, and you have created a new scope for the Exclusion to apply to, the user can select that Scope when searching. 

Be aware when doing all this that the will be a price to pay somewhere if you have a lot of Scopes defined in this way (even if it's only in confusing the user!), and that if you need really custom restrictions, perhaps you are better off with a custom search solution tailored for the way that the users need to search!

 

Querying the SharePoint Change Logs

March 22nd, 2007 by adrh

SharePoint 2007 keeps a record of all changes made to data, users, permissions, sites etc in a Change Log which you can access via the object model. This is actually how the indexer figures out what to crawl as part of an incremental crawl.

You need to be aware that the log history length is controlled by configuration available to server admins so it is possible that the changes you are looking for might have dropped off the log. And this is why there is a caveat around incremental crawling in Indexing…

For example, say I wanted to get all the items that have been added, modified or deleted from a list:

  //Create a new query, and set it not to return anything by default.
 SPChangeQuery listQuery = new SPChangeQuery(false, false);

 //Now set if to return the types of info we want.
 //In this case item changes of type Add, Delete and Update…
 listQuery.Item = true;
 listQuery.Add = true;
 listQuery.Delete = true;
 listQuery.Update = true;

 //Get the changes that match the query.
 SPChangeCollection changesCollection = currentWeb.GetChanges(listQuery);

 //Do something with them.
 foreach (SPChangeItem currentChange in changesCollection)
  {
     …
   }

The code above will return ALL changes in the log for list items in the specified Web. A Change Token is returned in the as part of the SPChangeCollection and can be passed to subsequent calls to GetChanges to return changes since the last time you checked. Meaning you can perform synchronisation operations in your own apps.

To get the last change token:

    SPChangeToken lastChangeToken = changesCollection.LastChangeToken;

Set the queries start token to the last change token we had:

    listQuery.ChangeTokenStart = lastChangeToken;

And then call the GetChanges method as above.

 

Querying the SharePoint Change Logs

March 22nd, 2007 by adrh

SharePoint 2007 keeps a record of all changes made to data, users, permissions, sites etc in a Change Log which you can access via the object model. This is actually how the indexer figures out what to crawl as part of an incremental crawl.

You need to be aware that the log history length is controlled by configuration available to server admins so it is possible that the changes you are looking for might have dropped off the log. And this is why there is a caveat around incremental crawling in Indexing…

For example, say I wanted to get all the items that have been added, modified or deleted from a list:

  //Create a new query, and set it not to return anything by default.
 SPChangeQuery listQuery = new SPChangeQuery(false, false);

 //Now set if to return the types of info we want.
 //In this case item changes of type Add, Delete and Update…
 listQuery.Item = true;
 listQuery.Add = true;
 listQuery.Delete = true;
 listQuery.Update = true;

 //Get the changes that match the query.
 SPChangeCollection changesCollection = currentWeb.GetChanges(listQuery);

 //Do something with them.
 foreach (SPChangeItem currentChange in changesCollection)
  {
     …
   }

The code above will return ALL changes in the log for list items in the specified Web. A Change Token is returned in the as part of the SPChangeCollection and can be passed to subsequent calls to GetChanges to return changes since the last time you checked. Meaning you can perform synchronisation operations in your own apps.

To get the last change token:

    SPChangeToken lastChangeToken = changesCollection.LastChangeToken;

Set the queries start token to the last change token we had:

    listQuery.ChangeTokenStart = lastChangeToken;

And then call the GetChanges method as above.

 

SharePoint Alternate Access Mappings

March 19th, 2007 by adrh

I came across the second part of Troy Starr's Trilogy on Alternate Access Mappings in SharePoint 2007.

It's a great series from an Administrators perpective on what they are and why you need them.

I recently 'stumbled' upon them when writing some code that accessed a site based on the URL. When I passed the internal name to the web service everything worked fine, by FQDN, IP Address, or externally accessible URL did not work (note I didn't realise that at THAT stage neither would all of the external links – see Troy's post). Once I added alternate access mappings for all the possible ways people could pass a URL to the site to SharePoint all was well.

Whatever you use as the URL when setting up your new server (and therefore becomes the URL you see when choosing application pools in central admin) is the only URL that will work 100% unless you create AAM's!!

What I think often happens is people set up a server and answer all the configuration prompts with the internal port 80 details. Then, when they come to go into production, realise that they need another port, or the server to be accessible via SSL, or FQDN and forget that AAM's need to be configured – and it's not until you try to do…

SPSite mysite=new SPSite("http://…");

 … where the URL is not mapped that you notice it's broken. Or someone reports that some links don't work…

Great post Troy – awaiting Part 3 with antici………..pation. Smile

 

SharePoint Alternate Access Mappings

March 19th, 2007 by adrh

I came across the second part of Troy Starr's Trilogy on Alternate Access Mappings in SharePoint 2007.

It's a great series from an Administrators perpective on what they are and why you need them.

I recently 'stumbled' upon them when writing some code that accessed a site based on the URL. When I passed the internal name to the web service everything worked fine, by FQDN, IP Address, or externally accessible URL did not work (note I didn't realise that at THAT stage neither would all of the external links – see Troy's post). Once I added alternate access mappings for all the possible ways people could pass a URL to the site to SharePoint all was well.

Whatever you use as the URL when setting up your new server (and therefore becomes the URL you see when choosing application pools in central admin) is the only URL that will work 100% unless you create AAM's!!

What I think often happens is people set up a server and answer all the configuration prompts with the internal port 80 details. Then, when they come to go into production, realise that they need another port, or the server to be accessible via SSL, or FQDN and forget that AAM's need to be configured – and it's not until you try to do…

SPSite mysite=new SPSite("http://…");

 … where the URL is not mapped that you notice it's broken. Or someone reports that some links don't work…

Great post Troy – awaiting Part 3 with antici………..pation. Smile