Understanding ASP.NET Core with Apache - apache

In IIS we had an aspnet_isapi extension that handles the request, it then spawns a process w3wp.exe, w3wp.exe then loads and starts the CLR and then CLR does its job.
Now, Kestrel is configured inside the Main() method, so first the Main() should execute, so who starts the Core CLR ? is it IIS for windows and Apache for Linux? Do IIS and Apache know how to search and start Core CLR?
What I know is, when a .NET application is executed at that time the control will go to the operating system, the OS creates a process to load CLR.
The program used by the operating system for loading CLR is called runtime host, which are different depending upon the type of application that is desktop or web-based application i.e.
The runtime host for desktop applications is an API function called CorbinToRuntime.
The runtime host for web-based applications is the ASP.NET worker process (aspnet-wp.exe).
So, how is it possible that first the Main() method will execute and then the CLR, i am not able to digest it, please help.

Forget about everything you know about IIS.
For Apache or nginx, just run your ASP.NET Core console application (who initializes Core CLR) at a local port (http://localhost:5000 for example), and then set up reverse proxy rules to forward external traffic to that port.
That's roughly what Microsoft documented in this article
Such reverse proxy setup is common, as other web stacks (Node.js, Python, Go) are using the same approach.
Because of this specific setup, Linux launches your .NET Core console app by analyzing the COFF envelope (of dotnet executable, or your own executable for self contained deployment) to locate the native entry (not your managed Main).
Apache/nginx is not involved in anyway.
Calling into this entry triggers CoreCLR initialization, and in turn your managed assemblies are loaded and managed Main is called.
You might find articles like this helpful.

Related

Do IIS Web Applications that use the same App Pool share DLLs in memory?

I inherited a large web site. To the user, it consists of 20 "modules" with different functionality. Each module can be accessed via a menu from each other module.
Each module has been implemented as a separate Web Application in IIS, all sitting under the Default Web Site. They all use the same App Pool. All implemented in ASP.NET Core (net5).
The modules share about 70% of their code. This library code sits in several projects. The web application projects all have References to the library DLLs. After everything has been built, the bin folder of each web application project has a copy of the library DLLs (so there are then 20 copies of each library DLL on disk).
Assuming that web application 1 is receiving requests and has been loaded into server memory. If web application 2 then gets loaded into server memory, will the library DLLs then be loaded into memory again for web application 2? Or will web application 2 use the library DLLs that have already been loaded into memory for web application 1? As in, after web applications 1 and 2 have been loaded in memory, will there be 1 copy of the library cod in memory or 2 copies?
Reason behind the question is that I need to reduce memory usage on the web server. There are no operational benefits to having separate web applications. They are all deployed together in one go. We never start or stop just one of them, it is always all or nothing. Wondering if I can save memory by having 1 big web application instead of 20 smaller web applications.
Your ASP.NET Core web apps in the same application pool are configured to use out-of-process hosting, so all their assemblies/libraries are loaded into individual .NET Core processes (Kestrel based) (dotnet.exe usually, or your own executable when self contained deployment is used).
Diagrams in that Microsoft article make it super easy to understand the relationship among the runtime processes.
In that mode, IIS worker process(es) w3wp.exe only loads the ASP.NET Core module to work as reverse proxy.
Combining the two above, the answer to your question Do IIS Web Applications that use the same App Pool share DLLs in memory? is rather clear that nothing is shared and you cannot share anything either due to the process boundary.

Why does .NET Core build generate an EXE file but not generate a dll file?

I have .net core project, When i build that project it generates .exe file but not .dll, My requirement is to create .dll of project and host it in IIS server. how to generate .dll file,what settings need to be done.
An ASP.Net Core binary is meant to be a self-hosted application, so the .exe embed a web server (the default one being Kestrel) that can accept HTTP requests. One of the challenges behind ASP.Net Core was to make it self-contained and decoupled from IIS. So having an .exe is perfectly expected, you can double click on it and you'll get a web server running.
That being said, in a standard production environment, you are supposed to have a webserver like IIS sitting in front of your ASP.Net Core app and acting as a reverse proxy, forwarding the requests to the app. So having an .exe file will not prevent you from hosting behind IIS.
I learned a lot from this article: https://weblog.west-wind.com/posts/2016/Jun/06/Publishing-and-Running-ASPNET-Core-Applications-with-IIS
If there is a way to create a DLL with ASP.Net Core, I don't know it, but what would be the point?
Switching the output type in your project properties to Class Library from Console Application will generate a DLL instead of an EXE.

How do you setup a load balanced environment with ASP.Net 5 (vNext) while using the DNX environment?

Description
I am curious about how a DNX load balanced setup will work. I am accustomed to working with an ARR (Application Request Routing)/Server Farm setup with IIS like this. Typically there is nothing done on the code side with the ARR/Server Farm setup. However, with the cross platform support that DNX provides, while getting rid of IIS, this sort of load balanced setup seems like it will now need to be handled in the code. Or at least in my case I would be responsible for code deploys as opposed to a Network Admin that would install updates. The closest that I could find is session management. Can you do load balancing with this, potentially, I just do not see it there yet.
Functional Impact
Decide to download a third party ARR, use MS ARR, or Role your own ARR?
What I need
I would like to keep this from "I like this best" responses as much as possible and see responses that are "Here is why you need this" or "Here is why I found this to work well". I know that dnx is a new environment, but the experience of setting up LB servers in OSX and Linux is not. With the move to cross platform, I do not expect that the MS ARR will work on OSX or Linux. I am not very familiar with those OS's so I do not know where to begin.
Question(s)
1) Is the https://github.com/aspnet/Session/ project (or another project) expected to contain an ARR?
If no on 1
2) Is there an ARR that is cross platform (Windows, OSX, Linux)?
There's no out-of-the-box load balancer for ASP.NET 5.
Your solution is the right one, add a load balancer in front of DNX. On Windows you can use IIS, on cross plat you can use something like ngnix
No changes and no support for in-app.
ASP.NET 5 is not where this should be going. IIS will still exist and the ARR module is a part of IIS itself. Not the app.
On the page itself it says:
Works With: IIS 7, IIS 7.5, IIS 8, IIS 8.5, IIS 10
As for supporting different kind of servers? I don't see why not since the ARR module is basically just a reverse-proxy.
Nothing need to change. You can even compile to CoreCLR and have it hosted on a farm of Linux machines with Apache but have an IIS server with the ARR Module set in Reverse-Proxy to forward load balance the requests.

Deploying an application server to a server

I am building a client-server application, this is all running locally on my computer whilst I am developing the system. However, eventually I would like to deploy the server-side part of the application to a server to run 24/7, enabling client applications to connect and consume the service at will. What I would like to know is, when I come to doing this would I simply just install the server-side application on the server, hit run and that's it? That just seems... well not right (to me), is this the way it is done? or is there a lot more to it? I imagine there is, but I can't seem to find any content on this subject.
FYI - the server is a self hosted WCF application.
You'd want to take your program's executable, support dlls and config files and drop them into a folder. Then create a Windows Service to run the program; if you don't use a Windows Service, the program will only run while you're logged on, which isn't good. As a Windows Service, a reboot of the server will bring the program back online even if you're not logged on.
Here's a knowledge base article from MS on how to make a windows service.
http://support.microsoft.com/kb/251192
If you're program is compiled as a DLL, then create a small .exe program to run it (a wrapper) then deploy the program as described in the article.
Good luck.

Out of process COM server works fine in the unit test harness but not in the real service

We have a WCF service hosted in IIS that currently calls a VB6 DLL to do part of its job. This works fine, but we can't deploy the service to a 64-bit target environment without configuring IIS to run it in a 32-bit worker process.
I am currently investigating ways around that restriction. Porting the VB6 DLL to .NET is not possible for various reasons, so I created an ActiveX EXE wrapper around the DLL in VB6, so that the service can run in 64-bit and the VB6 parts in 32-bit.
When I tested the service I got this error:
Type: System.UnauthorizedAccessException
Message: Retrieving the COM class factory for component with CLSID {9AE7303B-D159-43F6-B1A5-52D297581820} failed due to the following error: 80070005.
After some Googling I found that this is due to either:
Calling an MS Office component
DCOM permissions not being configured
NTFS file permissions not allowing read/exec access to the IIS worker process identity (ASPNET in my environment)
Of these:
Definitely not applicable
Also not applicable; I am not hosting the EXE in DCOM or COM+, just a simple COM out-of-process activation
This looks likely; however, I checked the permissions, and NTFS reports that the Users group (which ASPNET is a member of) does indeed have read/exec access to the file
I tried calling the EXE from a unit test fixture, which is executed in my admin-level account rather than the IIS worker process account, and it worked fine, so the error is definitely something to do with permissions. I'm not sure what to do next. Can anyone suggest things I can check?
My test environment is Windows XP / IIS 5.1
UPDATE:
The IIS virtual directory is configured for Anonymous+Windows access; the WCF service uses only Anonymous authentication, the Windows authentication is for the VS debugger. Task Manager reports that the aspnet_wp.exe process is definitely running in the ASPNET account.
I explicitly granted Read and Execute access to the ASPNET and IUSR_<machine> accounts on all the COM exes and dlls involved. This made no difference.
I explicitly granted Local Launch and Local Activation access to the ASPNET and IUSR_<machine> accounts on the relevant interfaces in the DCOM configuration. This made no difference either.
As I see it I have 3 options:
Keep trying to get this working somehow.
Go the whole hog and host the EXE in COM+.
Give up. Tell users that the WCF service must be configured to run in a 32-bit app pool on 64-bit Windows.
Your error is an Unauthorized access exception. Therefore, the problem is probably rights related.
You could check what the security context of the 32bit worker process is.
Also check your event log, they may be information there about what account is being used.