Вы находитесь на странице: 1из 7

Tips for Deploying ASP.

Net Application in Production


One of my previous article Deploying ASP.Net Applications discussed about how to deploy asp.net applications in IIS. In this article, we will see some of useful tips that can help us in deploying application efficiently in production.

Deploy application with debug="false"


When we develop asp.net application using Visual Studio, the default value for debug attribute is true. This setting will help developers to debug the application in development environment. For example, executing the application in this mode will not cache the resource files rendered by WebResources.axd handler. This prevents the need to clear the temporary cache every time when the developer needs to check the changes done. There will be other useful things done for developers for debugging like debug symbols, settings that will enable breakpoints etc. These setting will give a poor performance in production if released in the default debug mode (false). So, never release your website with debug mode set to true. It should be set to false in web.config when moving to production.
<compilation debug=false/> Disadvantages of debug = true

Code execution will be slow. Compilation will be slow since batch compilation is disabled. Memory consumption is higher since there are additional debug symbols, etc. Resources downloaded with webresources.axd will not be cached. Alternate will be <deployment retail=true/> in machine.config. If you are a server administrator, make this change in machine.config so that it will enforce the debug attribute in the applications web.config to false. It also disables the page output tracing and the ability to show the detailed exception report to the remote users when there is an exception. Read Scott Guthries post about this, http://weblogs.asp.net/scottgu/archive/2006/04/11/442448.aspx

Encrypt the Sensitive data in Web.Config


Sometimes, you will have some sensitive information stored on web.config. For example: SQL Userid and Password if you use SQL authentication to connect to database. Since, the information stored in web.config is clear text then it poses a security risk. Even though, users can't access web.config file, it is still not safe because the server admins can still see the userid and password from web.config files. For example, in shared hosting environments. So, it will be better if we encrypt the connection string in web.config file in these scenarios. Understanding this need, Microsoft introduced a new technique to encrypt and decrypt the Web.Config sections in Asp.Net 2.0. ASP.Net 2.0 has 2 providers for encrypting and decrypting config sections, RSA(RSAProtectedConfigurationProvider) DPAPI(DataProtectionConfigurationProvider) To encrypt a connection string section,
protected void btnEncrypt_Click(object sender, EventArgs e) { Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath); ConfigurationSection section = config.GetSection("connectionStrings"); if (!section.SectionInformation.IsProtected) { section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider"); config.Save(); } }

To use RSA algorithm, use RSAProtectedConfigurationProvider in the DataProtectionConfigurationProvider in the above code snippet. Once encrypted, this section will have encrypted data which is not readable by humans. The connection string can be still accessed in code by regular ways,
SqlConnection con = SqlConnection(ConfigurationManager.ConnectionStrings["Sql"].ConnectionString);

place

of

new

To see back the original connection string we need to decrypt it. To decrypt a connection string section,
protected void btnDecrypt_Click(object sender, EventArgs e) { Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);

ConfigurationSection section = config.GetSection("connectionStrings"); if (section.SectionInformation.IsProtected) { section.SectionInformation.UnprotectSection(); config.Save(); } }

Use App_Offline.htm to make application Offline


When performing an upgradation of an existing website and if you expect a downtime, then it will be good if we give a generic message to the users accessing the site at that time instead of an error. The trick is, just include a HTML file called App_Offline.htm in the root directory and include some messages on the page. Anyone trying to access the site at that time will be presented with the content in the App_Offline.htm file. ASP.Net will shutdown the app domain and sends back the content of this html file instead for every request.
App_Offline.htm <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Untitled Page</title> </head> <body> <h3>We are Upgrading!!! Please visit us later!!!</h3> </body> </html>

If the above page content is not showing up on your browser, then just do the following changes in your IE. Open IE > Tools > Internet Options> Advanced > Uncheck "Show Friendly Http error messages".

Use Web Deployment Project to Create Release files


Features of the Plug-in

For Visual Studio 2005, the plug-in can be downloaded here. For Visual Studio 2008, the plug-in can be downloaded here. The Web Deployment project will provide the following features for building and deploying ASP.NET Web sites: 1. ASP.NET 2.0 precompilation as part of the build process. 2. More flexible options for generating compiled assemblies from a Web project, including these alternatives: A single assembly for the entire Web site. One assembly per content folder. A single assembly for all UI components. An assembly for each compiled file in the Web site. 3. Assembly signing options. 4. The ability to define custom pre-build and post-build actions. 5. The ability to exclude folders from the build. 6. The ability to modify settings in the Web.config file, such as the <connectionString> element, based on the Visual Studio build configuration. 7. Support for creating .msi files with setup projects.

Configure Custom Error Page in Web.Config file


Use the customError section in web.config to redirect to a generic error page in case of any exception. This will give a better user experience when compared to showing some technical exception messages to the users.
<customErrors defaultRedirect="url" mode="On|Off|RemoteOnly"> <error. . ./> </customErrors> mode

On Specifies that custom errors are enabled. If no defaultRedirect attribute is specified, users see a generic error. The custom errors are shown to the remote clients and to the local host. Off Specifies that custom errors are disabled. The detailed ASP.NET errors are shown to the remote clients and to the local host. RemoteOnly Specifies that custom errors are shown only to the remote clients, and that ASP.NET errors are shown to the local host. This is the default value.

You can change this setting accordingly to get the detailed report of an error after deployed to the production.

Separate Application pool

Application Pools a.k.a App Pools is introduced with IIS 6.0 to isolate websites into a group called Application Pools. We can say application pools are a group of one or more URLs that are served by a worker process, means applications running in a single app pools runs in same worker process w3wp.exe, thus providing a boundary so that if one application fails it doesnt hinder other applications running on other app pools. So as a good practice each website can be assigned with a separate app pool. Refer my article Deploying ASP.Net Applications to create new application pool.

Custom Service Account

It is the identity of the App pool under which it services the request. It is an windows account that has very less privileges on the server so that we can reduce the security risk and loop holes. There can be several reasons to opt for custom service account over the default Network service account. Some of the reasons are: We can have different access controls for different applications on the local and network resources such as fileservers, etc. It is also a mode of isolating one application from another by giving a separate identity so other applications cannot access the resource of another application. We can prevent any accidental or deliberate changes to the access controls or permissions associated with the general purpose Network Service account from affecting your application. To create new service account, refer here.

For Intranet applications use Windows Authentication to connect to database

If your application is hosted in an intranet domain, then use windows authentication to connect to the database. The advantage of this approach, you can use the same windows service account configured to run your app pool in IIS 6.0 to connect to the database. This prevents the need to store the password as a clear text in web.config.

Conclusion
There are many things we should consider when we deploy asp.net application to have a better performance in production. The 8 points listed in this article can be considered to make the production application work better and efficiently.

Dont run production ASP.NET Applications with debug=true enabled


One of the things you want to avoid when deploying an ASP.NET application into production is to accidentally (or deliberately) leave the <compilation debug=true/> switch on within the applications web.config file. Doing so causes a number of non-optimal things to happen including: 1) The compilation of ASP.NET pages takes longer (since some batch optimizations are disabled) 2) Code can execute slower (since some additional debug paths are enabled) 3) Much more memory is used within the application at runtime 4) Scripts and images downloaded from the WebResources.axd handler are not cached This last point is particularly important, since it means that all client-javascript libraries and static images that are deployed via WebResources.axd will be continually downloaded by clients on each page view request and not cached locally within the browser. This can slow down the user experience quite a bit for things like Atlas, controls like TreeView/Menu/Validators, and any other third-party control or custom code that deploys client resources. Note that the reason why these resources are not cached when debug is set to true is so that developers dont have to continually flush their browser cache and restart it everytime they make a change to a resource handler (our assumption is that when you have debug=true set you are in active development on your site). When <compilation debug=false/> is set, the WebResource.axd handler will automatically set a long cache policy on resources retrieved via it so that the resource is only downloaded once to the client and cached there forever (it will also be

cached on any intermediate proxy servers). If you have Atlas installed for your application, it will also automatically compress the content from the WebResources.axd handler for you when <compilation debug=false/> is set reducing the size of any client-script javascript library or static resource for you (and not requiring you to write any custom code or configure anything within IIS to get it). What about binaries compiled with debug symbols? One scenario that several people find very useful is to compile/pre-compile an application or associated class libraries with debug symbols so that more detailed stack trace and line error messages can be retrieved from it when errors occur. The good news is that you can do this without having the have the <compilation debug=true/> switch enabled in production. Specifically, you can use either a web deployment project or a web application project to pre-compile the code for your site with debug symbols, and then change the <compilation debug=true/> switch to false right before you deploy the application on the server. The debug symbols and metadata in the compiled assemblies will increase the memory footprint of the application, but this can sometimes be an ok trade-off for more detailed error messages. The <deployment retail=true/> Switch in Maching.config If you are a server administrator and want to ensure that no one accidentally deploys an ASP.NET application in production with the <compilation debug=true/> switch enabled within the applications web.config file, one trick you can use with ASP.NET V2.0 is to take advantage of the <deployment> section within your machine.config file. Specifically, by setting this within your machine.config file: <configuration> <system.web> <deployment retail=true/> </system.web> </configuration> You will disable the <compilation debug=true/> switch, disable the ability to output trace output in a page, and turn off the ability to show detailed error messages remotely. Note that these last two items are security best practices you really want to follow (otherwise hackers can learn a lot more about the internals of your application than you should show them). Setting this switch to true is probably a best practice that any company with formal production servers should follow to ensure that an application always runs with the best possible performance and no security information leakages. There isnt a ton of documentation on this switch but you can learn a little more about it here. Hope this helps, Scott Updated: Tess has a great follow-up post with more details about what happens when debug="true" is enabled. You can read it here.

ASP.NET Memory: If your application is in production then why is debug=true


Ensure that the debug="false" on the <compilation> element in the web.config file of each and every ASP.NET application on the server. The default during development is "true" and it is a common mistake to allow this development time setting to find its way onto production servers during deployment. You don't need it set to true in production and it often leads to memory overhead and inefficiencies.

What problems does leaving debug=true cause? There are three main differences between debug=true and debug=false: 1. ASP.NET Timeouts 2. Batch compilation 3. Code optimization

ASP.NET Timeouts

When debug is set to true, asp.net requests will not time out. This is to allow you to debug with visual studio at your own pace without having to worry about the requests suddenly disappearing. Of course in a production environment timeouts are crucial to avoid for requests to be stuck indefinitely, so this is reason #1 to make sure debug is set to false when the application is deployed into production.

Batch compilation
In short, when debug=true, we dont batch compile, when debug=false we do What does this mean? When an aspx, asax, or ascx page is first requested it gets compiled into an assembly. This assembly has a name like 3ks0rnwz.dll or similar (8 characters) and stores the class for the actual ascx, asax, or aspx page (not the code behind). The assembly goes into a folder in the C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files with the same name as the application. The code behind class gets compiled into the main dll for the assembly, and it along with all the other dlls in the applications bin directory get shadow copied to the Temporary ASP.NET files. Back to the 3ks0rnwz.dll If we have debug=true, we create one dll per aspx, asax, or ascx page and this dll is compiled in debug mode, so if you have 100 web pages, you will have 100 assemblies, and they are generated as the pages are requested. If we instead have debug=false, we batch compile, which means that the first time you request any page in your application, we compile the whole batch into one big assembly. This is a truth with some modification. The user controls (ascx pages) are compiled into a separate assembly from the aspx pages and the aspx pages are compiled in groups based on what other files (read usercontrols) they include. The global.asax is also compiled separately. And batch compilation occurs on a directory bases, meaning that if your application has subdirectories, the subdirectories are compiled separately to avoid for example name clashes, as it is valid to have two aspx pages with the same name in different directories. But all in all, instead of 100 dlls, you might end up with 3 or 4. Ok, big deal? Its the same code so the size of the combined assemblies shouldnt much differ from the size of the individual assemblies right? Truth is, there probably isnt an enormous difference. But and this is a big but there is overhead for each dll, and if the dll is compiled in debug mode there is overhead for items needed for debugging, and last but not least (in fact probably most important), the assemblies wont be laid exactly side by side, so with a large number of assemblies you start fragmenting the virtual address space making it harder and harder to find large enough spaces to store the managed heaps, potentially causing out of memory exceptions. One caution even if you have debug=false, is that if you go in and change something in one of your aspx pages, this page will have to be recompiled, but this doesnt cause an appdomain reload so the whole application is not batch compiled again. This has the effect that the page will now get recompiled separately and get its own dll, so dont change your aspx pages on a live server too often.

There is a setting in machine.config determining how many recompiles are allowed before the app domain restarts, by default it is set to 15, so after 15 recompilations the app domain will restart, just as it would if you touched the web.config or touched the bin directory.

Code optimization
In order to be able to step through code line by line the JITter cant really optimize the code which means that your debug dlls will be less performant than if they were compiled in release mode. So as you can probably figure, there is a large benefit to having debug=false in production How can you identify it in a memory dump? To find out if any of the applications on your server run with debug=true you can run a nifty command in sos.dll called !finddebugtrue which will list out all applications where debug=true in the web.config, now how easy is that 0:016> !finddebugtrue Debug set to true for Runtime: 61b48dc, AppDomain: /MyDebugApplication Debug set to true for Runtime: 1f50e6d8, AppDomain: /MemoryIssues Total 16 HttpRuntime objects And to find out if you forgot to compile some of your assemblies in release mode run !finddebugmodules 0:016> !finddebugmodules Loading all modules. Searching for modules built in debug mode... MyDebugApplication.dll built debug MemoryIssues.dll built debug fl4sq-9i.dll built debug wepr1t3k.dll built debug r9ocxl4m.dll built debug zmaozzfb.dll built debug Done Searching The dlls above with weird 8 character names are the dlls generate when JITing the aspx pages, so they will go away when debug=false. Oh, before I forget when you change from debug=true to debug=false it is a good idea to clean out your Temporary ASP.NET files for this application so you dont have some old junk in there causing it to still not batch compile.

In ASP.NET 2.0 there is a switch that can be turned on in machine.config that turns off all debug=true, so in 2.0 applications you can do this directly without worrying about finding out which applications do and dont have it.
<configuration> <system.web> <deployment retail=true/> </system.web> </configuration>

If you want some more goodies about debug=true, read ScottGus blog post about it http://weblogs.asp.net/scottgu/archive/2006/04/11/442448.aspx

Вам также может понравиться