ServerName in WCF WSDL instead of domain name when hosted in IIS

If you have an IIS setup with multiple sites you will have problems with the urls that are used in the wsdl to include additional schemas. By default, the computer name is used for that instead of your specified domain.

This makes it hard for your callers to generate a proxy.

You can solve this by the following settings: (add the bold configurations to the web.config)

 <system.serviceModel>
   <serviceHostingEnvironment multipleSiteBindingsEnabled=”true” />
    …
    <services>
      <service name=”YourService”>
        <endpoint address=”" binding=”basicHttpBinding” contract=”YourContract”>
         <identity>
            <dns value=www.yourdomain.de />
          </identity>
        </endpoint>
      </service>

Commerce Server was unable to access IIS

The Site Packager seems to have an issue when you IIS 7 oder 7.5 contains an FTP Site. Once the site packager finds that site it will not let you proceed to the next step.  It will tell you “Commerce Server was unable to access IIS.”

I found that it doesn’t help to stop the particular site, but you can easily comment it out in you applicationhost.config file. So you don’t loose any settings.

HTH,

Ralf

ASP.NET Sessions not timing out

For one of our applications we had a very high memory consumption. Digging into the problem, we found out that no ASP.NET sessions are timing out. (You can see this using the ASP.NET 2.0 Perfomance Counters Active Sessions, Sessions Timed Out.)

Investigation further the reason turned out to be a setting for the ASP.NET cache in the web.config.

<caching>
       <cache percentagePhysicalMemoryUsedLimit=”50″ disableExpiration=”true”/>
</caching>

Reading through the following link this makes sense. When InProc Session is used the Session data is stored in the Cache.

Maybe this helps you, because I couldn’t find anything helpful on this.

Silverlight xap-file is not copied to clientbin folder on Build Server

In one of our projects we had the problem that our TFS Build never deployed the latest version of our silverlight application via TFS build.
It is probably because our build server has not all the silverlight related SDKs installed.

We recognized that the contents in one of the MSBuilds subfolders (C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications) was different from the content of the developer machines. A simple xcopy adjustment of this folder did not do the trick. ;)

We implemented a temporary solution using the following post-buid event:
“$(TargetDir)*.xap” “$(SolutionDir)[YourWebsite]\clientbin\” /Y /R

SOA – More flexibility for my business processes and applications?

In the past years a lot of people told us about service oriented architecture. Loose-coupling, Contract First, Service Versioning, Orchestration, Mapping.

One of the main goals of the SOA is to build IT systems that can be easily adapted to the changing needs of companies. What does it mean? Companies do not act alone in the market. They are connected to various partners, outsource parts of their business processes – or in other words, they consume certain aspects of their work as services from partner companies. Those partner networks are quite dynamic, as partners have to be exchanged from time to time for different reasons.

SOA takes this principle over to the IT. Stand-alone services are defined and can be consumed from different applications and clients. Methods like “Contract First” help service providers to create stable interfaces for their services. Service Versioning ensures backward compatibility while the service itself is under ongoing development. The rise of the web service technology delivered a solid technological basis for the implementation of the new services.

We heard a lot about the different approaches for the service implementation. But as long as we are not the service provider, we are more interested in consuming existing services. So which of the described approaches ensures, that I can easily exchange my service providers? How could my service provider do a proper “Contract First” design, when the service was created by the service provider alone - without any involvement from me as a potential client?  I think the answer is simple: It is not really possible. The contract will reflect the business processes of the service provider. – Not necessarily mine (Conway’s Law ) .

Let’s take a look at an easy example from my daily work. : Consuming Online CreditCard Authorization

We are building worldwide eCommerce applications, where we offer online credit card authorization. As we are more a logistics company, we do not offer the authorization service our self, but use payment service providers (PSP) for it. We use RBS World Pay for Europe, Cybersource for North America and Cobre BEM for the Latam region. Although all three companies offer the same service to us, the interfaces are very different. The following things differ:

  • Message Contracts with different field names
  • HTTP POST vs. HTTP GET vs. SOAP Web Service
  • Error and Result Codes
  • Backend Tools

When I need to implement an online credit card authorization, I don’t want to care about the different PSP service contracts I need one solid facade. It means I have to encapsulate the real interfaces to the PSPs.

The following figure illustrates the situation.



The Service DAL is a component inside our application that encapsulates the communication with the different service providers. This DAL is implemented by using the provider pattern, where each provider implements one interface. You probably see the equivalence to the typical SOA figures, where our service DAL would be an integration platform like biztalk. Such integration platform usually forces us a consumer contract (I choose the name by chance.). Interestingly, in our department we seldom applied this idea when we called external services within the application code. – without having a biztalk in place.

The provider pattern however also offers the possibility to consume a service functionality from different external service providers.



The CreditCardProviderManager class implements logic to initialize and select the providers depending on the current scenario. The abstract class CreditCardProvider defines the Consumer Contract, and the different providers implement the mapping to the external services.

I made good experience with that approach of integrating external services into applications, because it forces you to think about a stable contract the fits for your business needs. – Not for the needs of the particular service provider.

To come back to the initial question: Does service orientation give me more flexibility for my business processes and applications? – I think YES, but you should not use the service contract without a proper mapping to a consumer contract.

Run CS2007 configuration wizard only for selected features

We recently had to reconfigure some of our commerce server development images. I turned out that some of the images had installation issues with the performance counters – for other images the Direct Mailer feature could not be reconfigured. As we don’t really use those features, we just wanted to proceed with the reconfiguration without those features.

Unfortunetally, you can specifiy the features that you want to reconfigure like this:

 csconfig.exe /r <comma seperated feature_list>

The question is, what is the correct spelling of the single features. We couldn’t find it in any documentation. Reflector finally revealed, that we have to use the exact same spelling like the feature names in the registry.

Plain text feature names:

Feature.MS.CS.Admin
Feature.MS.CS.Catalog
Feature.MS.CS.Core
Feature.MS.CS.DWA
Feature.MS.CS.Marketing
Feature.MS.CS.Misc
Feature.MS.CS.Orders
Feature.MS.CS.PCGN
Feature.MS.CS.PerfCounters

In addition to the features that we found in the registry, there are some more features names:

Feature.MS.CS.DirectMailer
Feature.MS.CS.PCW
Feature.MS.CS.CsStaging
Feature.MS.CS.HealthMonitoring

Guter Artikel über Requirements Engineering in agilen Prozessen

Ein, wie ich finde, ziemlich interessanter Artikel!

http://www.heise.de/developer/artikel/Requirements-Engineering-in-Zeiten-der-Agilitaet-804971.html

Thinking about system development

Whenever we create technical systems, software solutions, business processes or whole organization structures, we have to make a lot of decisions. Different constraints are balanced against each other, assumptions are made, models and abstractions for real-world entities are created. Most of you know these situations where you have to choose between several imperfect options during the design phase of a solution. Often, we even have to make decisions under time pressure and with lack of deeper knowledge about the issue. In those cases, it is nice to have at least a set of rules and principles that often lead to a good design and the successful organization of a development.  I know that there is no ultimate guideline, but I like to stick to some principles, which can be used to derive solution strategies. I’d like to use this post to pick out some of those general principles and to explain why I like them.

Let’s start quite general by seeing a system as a set of interacting or interdependent entities, real or abstract, forming an integrated whole. – This can be anything from software, organizations or even whole markets.

Based on that definition, let’s have a look at some laws from different science areas. There is e.g. the law of economizing, that states that individuals tend to economize, maximizing gains for a given cost, and minimizing costs for a given gain. (Optimizing behavior of agents)  Secondly, we have Le Chatelier’s Principle. Originally from the area of chemistry, it says: “Any change in status quo prompts an opposing reaction in the responding system.”  (Stability of the equilibrium).  Paul A. Samuelson applied those two principles to economics and considers as the underlying mathematical structure of economies.

From the area of physics, we know the 2nd Law of Thermodynamics. It states that the total entropy of any isolated thermodynamic system tends to increase over time, approaching a maximum value. The biologist Fisher formulated the theory of natural selection. It states that the more highly adapted an organism becomes, the less adaptable it is to any new change.

You might be wondering what those laws have to do with technical system design. – They all tell us something about the general ability of a system to handle changes. In my opinion the mayor design goal of each system or solution is to do more with less, or in other words to economize.  As long as we want to reach this goal, according to Samuelsons theory  your system is forced to change.

Your system is constantly faced with new feature requests just because of Le Chatelier’s principle.  Jakob Nielson has refined that principle in his Law of Internet User Experience: Users spend most of their time on other sites. This means that users prefer your site to work the same way as all the other sites they already know. So your software system tends towards equilibrium with their environment. Unfortunately, changing a system increases its complexity. – The system gets more and more chaotic. A similar process happens in physical systems. Here the measured value is not called complexity but entropy. After we have implemented enough new features, that the initial architecture did not really foresee, we have increased the complexity of the system significantly. – The system was adapted the very special demands, future changes get harder or even not feasible. At this point, the market selects which of the competing systems survive.

I hope, you excuse this brief excursion to those very general laws. What I wanted to show, is that the context and the forces, we are facing in software system design are not unique to this area. Parallels exist to other research fields and there might be potential to leverage existing patterns and strategies from them.

Coming back to software development, 1997 Lehmann published the following laws of software evolution, which more or less refine the above general laws. (Lehmann, 1997)

Continuing Change – A system must be continually adapted else they become progressively less satisfactory in use. So without changes a system looses its primary function helping people.

Continuing Growth – The functional capability of systems must be continually increased to maintain user satisfaction over the system lifetime.

Increasing Complexity – As a system is evolved its complexity increases unless work is done to maintain or reduce it.

Declining Maintainability – The maintainability of a system is inversely proportional to the complexity of its individual pieces. (Kanat-Alexander, 2008)

Declining Quality – Unless rigorously adapted to take into account for changes in the operational environment, the quality of a system will appear to be declining.

Considering those laws, we see again that changes cause a lot of bad things to our system, but changes are inevitable. That’s why, my second design goal is to maximize the ability to change.

Goals defined – How to reach them?

Hmm… not very easy to answer. From my experience, the solutions have to least ability to change, if the requirements were misunderstood or incomplete, and therefore lead to an inappropriate model. Nevertheless, I’d like to push this scenario away, because talking about requirements engineering and project management would be far beyond the scope of this post. So assuming, we understood what we have to build, let’s take a look at the following well known principles, which I think help us to maximize the ability to change.

Ockham’s razor – Don’t assume

The principle states that the explanation of any phenomenon should make as few assumptions as possible, eliminating those that make no difference in the observable predictions of the explanatory hypothesis or theory. In software projects, there is always a gap between real world processes and the models that developers create to map real world things to program code.  Assumptions usually simplify the model, but they are often subject to change.

Divide and Conquer

When a problem seems to be too complex to solve directly, break it down to smaller sub-problems and try to solve them. Especially in big projects, the divide and conquer principle is important for creating a platform, that makes it easy to for different team members to contribute solutions for smaller sub-problems. So, Divide and Conquer is about organization not about coding itself. It can be used for structuring processes in companies as well as structuring software.

Sometimes it is not very easy to define the single modules that form the solution for the bigger problem. A lot of strategies exist for that, which more or less can be summarized as separation of concerns. It says: Create your modules in a way that the functionality does not overlap between the modules. Maximize the dependencies between elements within a module (cohesion). Minimize the dependencies between elements of different modules (coupling).

YAGNI – You ain’t gonna need it

Never implement something because you might need it in the future. It often just complicates the current implementation and increases the efforts. – In other words “Simple is Sexy”.

Pareto Principle  – 80/20 principle

Sometimes, you create a nice and simple model which covers all of your requirements, and then suddenly you get a new requirement on your plate which complicates everything. – I just had a call for one of our projects, where we have exactly that case. ;) –  if you them implement that change, it can complicate all future changes for the whole application, and is therefore not a good idea. – You just have to find a way to tell it to your customer. ;)

Incremental Development: Code, Release, improve, repeat.

An incremental development can help you to convince you customer to postpone a requirement to the next iteration, when it is in contrast to the 80/20 principle. It also helps to constantly improve and develop the system over a long time, and enables you to respect the YAGNI principle for each iteration.

Last Responsible moment

Wait to really implement requirements until you really can’t wait any longer to do it. This reduces the number of changes that you have to do. Nevertheless, constantly gather information on the topic.

There are a lot more laws and basic principles available in specialists publications, but I just wanted to pick out those, that I find most important. I wonder how you see those things.

Take care!

Ralf

Biblography

deVilla, Joey. 2007. Laws of Software Development. [Online] 07 18, 2007. [Cited: 01 30, 2009.] http://www.globalnerdy.com/2007/07/18/laws-of-software-development/ 

Haack, Phil. 2007. 19 Eponymous Laws Of Software Development. [Online] 07 17, 2007. [Cited: 01 31, 2009.] http://haacked.com/archive/2007/07/17/the-eponymous-laws-of-software-development.aspx 

Kanat-Alexander, Max. 2008. Code Simplicity. [Online] 12 12, 2008. [Cited: 01 12, 2009.] http://www.codesimplicity.com/

Lehmann, M.M. 1997. Metrics and Laws of Software Evolution – The Nineties View. [Paper] Warsaw : Institute of Informatics, Warsaw University, 1997.

Unknown. 2009. Wikipedia – System. Wikipedia – System. [Online] 01 31, 2009. [Cited: 01 31, 2009.] http://en.wikipedia.org/wiki/System

A/B Deployment of Commerce Server 2007 Product Catalog Database

Recently, we were asked how we can reduce shop downtimes  during bigger catalog changes. We have a load-balanced setup consisting of two web servers. Those web servers both host our Commerce Site which share the commerce server databases. So we can easily deploy a new version of the site code without a downtime. Unfortunately, this is not possible when we have to do changes to the product catalog database, which happens quite often. – Why?  – Because changes to the database will already affect to node on which we are not deploying yet.

You have to options to come around this issue. First, you can setup two Commerce Sites in Commerce Server for one shop. Then you can switch between those two sites via web.config. Second, you can modify the database connection string of the catalog context pragmatically.

Here is a possible implementation for the second option:

Add a HttpModule to you site and add to following code to the OnBeginRequest Event.

 

 private void OnBeginRequest(object sender, EventArgs e)
 {
            if (!(bool)HttpContext.Current.Application["CatalogConnectionChanged"])
            {
                if (CommerceContext.Current != null)
                {
                        if (CommerceContext.Current.Resources["Product Catalog"]["connstr_db_Catalog"].ToString() != YourProductCatalogConnectionString)
                        {
                            CommerceContext.Current.CatalogSystem = Microsoft.CommerceServer.Catalog.CatalogContext.CreateFromConnectionString(
                                YourProductCatalogConnectionString,
                                new Microsoft.CommerceServer.Runtime.Diagnostics.ConsoleDebugContext(Microsoft.CommerceServer.Runtime.Diagnostics.DebugMode.Debug));
                          }
                        else
                            log.Info("The connectionString defined in Commerce Server Manager is equal to that one defined in web.config. Going on without changing the connectionString.");
                            HttpContext.Current.Application["CatalogConnectionChanged"] = true;
                }
 }

Introduction to dealing with ASP.NET perfomance issues

1 Introduction

During our last project, we had big problems with the performance of our website on both the integration and to production systems. The website was rather slow and consumed a lot of memory. So we digged into this to find out what’s happening. As a result, this post gives an introduction to dealing with performance and memory issues, and it provides links to sites with further information.
Performance issues can be classified like this. Hereby, the magnitude of the problem increases from one to three.

1. Slow performance – application not responsive

2. Hangs

3. Crashes

We can find ourselves in two basic situations when experiencing slow performance or hangs

· Low CPU àwaiting for external resources and or locks

· High CPU àBusy Server, Infinite Loops, long time in GC

 

A Crash is recycling of the applications app domain. A app domain recycle is a normal process of IIS and ASP.NET which usually happens in the following situations (amongst others):

· IIS recycles app pools by default after a period of time

· When changes to web.config or directory names are made.

· When the number of compilations (ASPX, ASCX, or ASAX) exeeds the configured number

 

Beside those regular recycling processes, the app domain can be recycled unwanted e.g. by the follwing things:

· StackOverflow Exception

· OutOfMemory Exception

· Fatal Excecution Engine Exception (Assert in CLR)

o Managed Heap Corruption e.g.

· When unhandled Exceptions in non-request threads, COM-Component Calls, Destructors /Finalizers

A StackOverflow exception is generally caused by bad recursions. It is quite hard to write non-recursive code that causes the stack to overflow. The reason for an OutOfMemory exception is not so obvious. It can be caused by insufficient memory, or by memory fragmentation. Regardless of the real cause of the OutOfMemory exception, the occurrence of this exception means that your worker process is unstable, and it should not continue it’s work.

To dive deeper into understanding memory issues, here is a little recap of the .NET memory organisation. There a two memory areas. The stack and the heap. The stack is the place where .NET stores value types (char, int, long, byte, enum) and structures. It is organized via Last In – First Out principle (LIFO), and it uses scoping to identify blocks of local variables. So the stack is self-cleaning and doesn’t use garbage collection.

The heap on the other hand is the place where reference types are stored. For example strings as a very simple object, where each char takes up to 2 bytes on the heap. The pointers – or in .NET terms references – to the objects on the heap are stored on the stack as they are simple types. (They only contain the memory address.) Every object on heap is immutable according to memory allocation. This is also the reason for using StringBuilder for string manipulation, rather then concatenating strings with +=. Every concatenation creates a new object on the heap. The heap has an extra area for objects that are bigger than 85000 bytes. It is called the large object heap (LOH).

The heap is frequently cleaned and compressed by the .NET garbage collector (GC). It takes care about freeing heap memory that an application has allocated, but no longer uses it. The clean-up takes place by categorizing objects into three generation Gen 0, Gen 1 and Gen 2. At the beginning every object is in generation Gen 0. With every GC run that an object survives, it moves to the next generation but at max. to Gen 2. So the generation of an object tells us something about it’s lifetime. GC runs are are increasingly resource critical from 0 to 2, because a run on e.g. Gen 1 also includes all objects on Gen 0. GC runs for Gen 2 are runs on the complete .NET heap, and they even suspend all other threads in the worker process and therefore slow down the application.

The compression step of GC is not applied to the LOH, because it would take too much CPU. So the LOH gets fragmented over time. When you consider that the .NET runtime allocates space on the heap in chunks of several mega bytes, you can surely image that you can get an OutOfMemory Exception alltough there is still enough memory left. – Just because there is no big enough contiguous block.

 

2 Meassuring Performance and Memory

Having in mind those basic facts about the .NET memory organization, lets take a look at available performance counters that help us in finding out what goes on on the server. The following table provides a list of the most important counters and their significance.

To get a picture about the performance of you application, you need to be able to set the application under load, and you have to monitor to following criteria.

  • Throughput. This includes the number of requests executed per second and throughput related bottlenecks, such as the number of requests waiting to be executed and the number of requests being rejected.
  • Cost of throughput. This includes the cost of processor, memory, disk I/O, and network utilization.
  • Queues. This includes the queue levels for the worker process and for each virtual directory hosting a .NET Web application.
  • Response time and latency. The response time is measured at the client as the amount of time between the initial request and the response to the client (first byte or last byte). Latency generally includes server execution time and the time taken for the request and response to be sent across the network.
  • Cache utilization. This includes the ratio of cache hits to cache misses. It needs to be seen in larger context because the virtual memory utilization may affect the cache performance.
  • Errors and exceptions. This includes numbers of errors and exceptions generated.
  • Sessions. You need to be able to determine the optimum value for session timeout and the cost of storing session data locally versus remotely. You also need to determine the session size for a single user.
  • Loading. This includes the number of assemblies and application domains loaded, and the amount of committed virtual memory consumed by the application.
  • View state size. This includes the amount of view state per page.
  • Page size. This includes the size of individual pages.
  • Page cost. This includes the processing effort required to serve pages.
  • Worker process restarts. This includes the number of times the ASP.NET worker process recycles.

For monitoring those criteria, you can use performance counters on the server.

2.1 Interessting Performance Counters

Performance counters are a good way to estimate your current implementation. Often, it is not easy to judge the impact of a code change just from browsing the pages. You should set up some of the following performance counter to get hard numbers.

Counter Name

Description

Significance/Treshold

Process\Private Bytes

This counter indicates the current number of bytes allocated to this process that cannot be shared with other processes.

Depends on your application and on settings in the Machine config.

ASP.NET default is min(60 percent available physical RAM, 800 MB)

.NET CLR Memory\# Gen X Collections

This counter indicates the number of times the generation X objects are garbage-collected from the start of the application. (X ={0,1,2})

X : X+1 = 10 : 1

.NET CLR Memory\% Time in GC

the percentage of elapsed time spent performing a garbage collection since the last garbage collection cycle.

Should average about 5 percent for most applications when the CPU is 70 percent busy, with occasional peaks

.NET CLR Memory\# Bytes in all Heaps

Sum of Gen 0 Heap Size, Gen 1 Heap Size, Gen 2 Heap Size and Large Object Heap Size. Is always smaller then Process\Private Bytes

Server-Dependant. Should reach a max value after time.

.NET CLR Memory\Large Object Heap Size

Place for objects that are > 85 Kb. LO-Heap can’t be compacted after GC. So it gets fragmented.

 

ASP.NET\Requests Rejected

The total number of requests not executed because of insufficient server resources to process them. This counter represents the number of requests that return a 503 HTTP status code, indicating that the server is too busy.

 

ASP.NET\Requests WaitTime

The number of milliseconds that the most recent request waited in the queue for processing.

 

WebService\ISAPI Extension Requests/Sec

The rates at which the server is processing ISAPI application requests. If this value decreases due to increasing load, you might need to redesign the application.

 

ASP.NET\Requests Queued

The number of requests waiting for service from the queue. When this number starts to increment linearly with increased client load, the Web server computer has reached the limit of concurrent requests that it can process. The default maximum for this counter is 5,000. You can change this setting in the Machine.config file.

 

ASP.NET\Requests in Application Queue

The number of requests in the application request queue.

Configured in appRequestQueueLimit.

ASP.NET\Applications\ Requests Executing

This counter is incremented when the HttpRuntime begins to process the request and is decremented after the HttpRuntime finishes the request.

 

ASP.NET\Worker Process Restart

The number of aspnet_wp process restarts.

1

Table 1ASP.NET and IIS 6.0 Performance Counters

ASP.NET Performance Counter (Figure from Microsoft)
ASP.NET Performance Counter (Figure from Microsoft)

2.2 Improving application performance

Now that we know how to judge the performance of our application with performance counters, we should investigate the real issue. Herefore, you can use automatic tools, memory dump analysis or just a simple code review.

2.2.1 By Code Review

A code review is probably the most effective way to identify performance issues. Beside some commonly known issues, that are listed here, also logical mistakes can be found that way.

  • Use Output buffering where possible
  • Use StringBuilder for string concatenation
  • Don’t use .ToLower() for case-insensitive string comparison. Using String.Compare (string strA, string strB, bool ignoreCase); avoids temp memory allocations
  • Don’t use exception handling to control the flow of your normal application logic
  • Don’t use a try-catch block inside a performance critical loop
  • Use strongly typed collections over generics (Hashtable, Dictionary, Arraylist) for storing simple types. This avoids unnecessary boxing.
  • Initialize collections to an approximate final size
  • Prefer StringDictionary instead of Hashtable for storing strings
  • Call Dispose on IDisposable objects in finally blocks to free ressources
  • Avoid calling Page.DataBind and bind each control individually to optimize your data binding. Calling Page.DataBind recursively calls DataBind on each control on the page.
  • Use Repeater Control rather than  DataList, DataGrid and DataView controls. It has a smaller HTML output
  • DataBinder.Eval uses reflection, which affects performance. In most cases DataBinder.Eval is called many times from within a page, so implementing alternative methods provides a good opportunity to improve performance.
    eg: Bad <%# DataBinder.Eval(Container.DataItem,”field1″) %>
    Good <%# (string)DataBinder.Eval(Container.DataItem,”field1″) %>
  • Mind DataSet Serialization: Avoid multiple versions of the data. Only return relevant data in the DataSet and call AcceptChanges before serializing a DataSet.
  • If you need to search a DataSet using a primary key, create the primary key on the DataTable. This creates an index that the Rows.Find method can use to quickly find the required records. Avoid using DataTable.Select, which does not use indices
  • Do not call GC.Collect() yourself.
  • If your code uses recursion, consider using a loop instead. A loop is preferable in some scenarios because each recursive call builds a new stack frame for the call. This results in consumption of memory, which can be expensive depending upon the number of recursions.
  • Avoid foreach loops when performance is critical. Using foreach can result in extra overhead because of the way enumeration is implemented in .NET Framework collections.
  • Do not use exceptions as a tool to exit one or more loops.
  • Use Output Caching of pages or user controls whenever possible
  • Disable SessionState and Viewstate for pages that don’t need it. If a page only needs to read from session, consider using <%@ Page EnableSessionState=”ReadOnly” . . .%>

A more complete checklist as well as a lot of other interesting information about .NET code performance can be found at (J.D. Meier, 2007)

2.2.2 With Tools

Sometimes resolving the issue just a code review is not possible. In our case, we could identify some issues in our code, but the biggest issue was found at another place. It turned out to be a memory leak in the used ISAPI Rewrite engine. So how do you find such issues?

Here is a list of tools which can help you with analysing performance issues of web applications.

· Debug Diagnostic Tool (DebugDiag)

· Debugging Tools for Windows (X-copy deployment possible!!)

o WinDbg (a Microsoft debugger)

o ADPlus (Recording of Memory Dumps)

o TinyGet (Command Line Load Tester)

o Son-Of-Strike (SOS.dll) (.net extension for native debugger windbg)

· SysInternals Process Explorer / Task Manager

Debug Diag is probably the easiest tool, to record and analyse performance dumps. We could eventually find our problem with DebugDiag on integration. The program has to be installed, what might not be an easy process on a production landscape. But for those cases, we can use the Debugging Tools for Windows, which can be just copied to the server.

Here is a list of important commands for doing the analysis with the debugging tools for windows.

Program

Commands

Description

Command Line

adplus -hang -p [PID] –quiet

Starts recording a memory dump. Tracking all current activity. Not only hangs are recorded

Command Line

adplus -crash -p [PID] –quiet

Sets up a recording session that waits in the background for crashes. When a crash occurs the dump is recorded.

WinDbg

.loadby sos mscorwks

 

Load the Managed Extensions Module in WinDbg

WinDbg

!runaway

 

Lists all threads that used the most CPU time in during the recording session of the memory dump

WinDbg

~* e!clrstack

 

Shows the callstack of all threads in the memory dump

WinDbg

!synchblk

Which treads holds a lock

Table 2Commands for analysing performance problems

 

3 Bibliography

Douglass, David. 2006. .NET on my mind. .NET on my mind. [Online] 03 14, 2006. [Cited: 12 06, 2008.] http://geekswithblogs.net/.netonmymind/archive/2006/03/14/72262.aspx.

Ferrandez, Tess. 2008. If broken it is, fix it you should. If broken it is, fix it you should. [Online] 2008. [Cited: 12 06, 2008.] http://blogs.msdn.com/tess/default.aspx.

J.D. Meier, Srinath Vasireddy, Ashish Babbar, John Allen and Alex Mackman. 2004. Improving .NET Application Performance and Scalability . Improving .NET Application Performance and Scalability . [Online] 2004. [Cited: 12 06, 2008.] http://msdn.microsoft.com/en-us/library/ms998549.aspx.

J.D. Meier, Srinath Vasireddy, Ashish Babbar, Rico Mariani, and Alex Mackman. 2007. Web Application Performance Design Inspection Questions. Web Application Performance Design Inspection Questions. [Online] 12 18, 2007. [Cited: 12 14, 2008.] http://www.guidanceshare.com/wiki/Web_Application_Performance_Design_Inspection_Questions.

2005. Monitoring Applications That Use the IIS 6.0 WWW Service. Monitoring Applications That Use the IIS 6.0 WWW Service. [Online] Microsoft, 08 22, 2005. [Cited: 12 12, 2008.] http://technet.microsoft.com/en-us/library/cc775979.aspx.

Seguin, Karl. 2008. Foundations of Programming – Building better software. www.codebetter.com, Canada/Ontario : s.n., 07 17, 2008.

 

 

Next Page »



Follow

Get every new post delivered to your Inbox.