Wednesday, August 11, 2004
« Things VB can do that C# can't | Main | My blog featured on MSDN »

There is this broad-reaching debate that has been going on for months about remoting, Web services, Enterprise Services, DCOM and so forth. In short, it is a debate about the best technology to use when implementing client/server communication in .NET.

 

I’ve weighed in on this debate a few times with blog entries about Web services, trust boundaries and related concepts. I’ve also had discussions about these topics with various people such as Clemens Vasters, Juval Lowy, Ingo Rammer, Don Box and Michele Leroux Bustamante. (all the “experts” tend to speak at many of the same events, and get into these discussions on a regular basis)

 

It is very easy to provide a sound bite like “if you aren’t doing Enterprise Services you are creating toys” or something to that effect. But that is a serious oversimplification of an important issue.

 

Because of this, I thought I’d give a try at summarizing my thoughts on the topic, since it comes up with Magenic’s clients quite often as well.

 

Before we get into the article itself, I want to bring up a quote that I find instructive:

 

“The complexity is always in the interfaces” – Craig Andrie

 

Years ago I worked with Craig and this was almost like a mantra with him. And he was right. Within a small bit of code like a procedure, nothing is ever hard. But when that small bit of code needs to use or be used by other code, we have an interface. All of a sudden things become more complex. And when groups of code (objects or components) use or are used by other groups of code things are even more complex. And when we look at SOA we’re talking about entire applications using or being used by other applications. Just think what this does to the complexity!

Terminology

I think a lot of the problem with the debate comes because of a lack of clear terminology. So here are the definitions I’ll use in the rest of this article:

 

Term

Meaning

Layer

A logical grouping of similar functionality within an application. Often layers are separate .NET assemblies, though this is not a requirement.

Tier

A physical grouping of functionality within an application. There is a cross-process or cross-network boundary between tiers, providing physical isolation and separation between them.

Application

A complete unit of software providing functionality within a problem domain. Applications are composed of layers, and may be separated into tiers.

Service

A specific type of application interface that specifically allows other applications to access some or all of the functionality of the application exposing the service. Often this interface is in the form of XML. Often this XML interface follows the Web services specifications.

 

I realize that these definitions may or may not match those used by others. The fact is that all of these terms are so overloaded that intelligent conversation is impossible without some type of definition/clarification. If you dislike these terms, please feel free to mentally mass-substitute them for your favorite overloaded term in the above table and throughout the remainder of this article J.

 

First, note that there are really only three entities here: applications, tiers and layers.

 

Second, note that services are just a type of interface that an application may expose. If an application only exposes a service interface, I suppose we could call the application itself a service, but I suggest that this only returns us to overloading terms for no benefit.

 

A corollary to the above points is that services don’t provide functionality. Applications do. Services merely provide an access point for an application’s functionality.

 

Finally, note that services are exposed for use by other applications, not other tiers or layers within a specific application. In other words, services don’t create tiers, they create external interfaces to an application. Conversely, tiers don’t create external interfaces, they are used exclusively within the context of an application.

Layers

In Chapter 1 of my .NET Business Objects books I spend a fair amount of time discussing the difference between physical and logical n-tier architecture. By using the layer and tier terminology perhaps I can summarize here more easily.

 

An application should always be architected as a set of layers. Typically these layers will include:

 

  • Presentation
  • Business logic
  • Data access
  • Data management

 

The idea behind this layering concept is two-fold.

 

First, we are grouping similar application functionality together to provide for easier development, maintenance, reuse and readability.

 

Second, we are grouping application functionality such that external services (such as transactional support, or UI rendering) can be provided to specific parts of our code. Again, this makes development and maintenance easier, since (for example) our business logic code isn’t contaminated by the complexity of transactional processing during data access operations. Reducing the amount of external technology used within each layer reduces the surface area of the API that a developer in that layer needs to learn.

 

In many cases each layer will be a separate assembly, or even a separate technology. For instance, the data access layer may be in its own DLL. The data management layer may be the JET database engine.

Tiers

Tiers represent a physical deployment scenario for parts of an application. A tier is isolated from other tiers by a process or network boundary. Keeping in mind that cross-process and cross-network communication is expensive, we must always pay special attention to any communication between tiers to make sure that it is efficient given these constraints. I find it useful to view tier boundaries as barriers. Communication through the barriers is expensive.

 

Specifically, communication between tiers must be (relatively) infrequent, and coarse-grained. In other words, send few requests between tiers, and make sure each request does a relatively large amount of work on the other side of the process/network barrier.

Layers and Tiers

It is important to understand the relationship between layers and tiers.

 

Layers are deployed onto tiers. A layer does not span tiers. In other words, there is never a case where part of a layer runs on one tier and part of the layer runs on another tier. If you think you have such a case, then you have two layers – one running on each tier.

 

Due to the fact that layers are a discrete unit, we know that we can never have more tiers than layers. In other words, if we have n layers, then we have n or less tiers.

 

Note that thus far we have not specified that communication between layers must be efficient. Only communication between tiers is inherently expensive. Communication between layers could be very frequent and fine-grained.

 

However, notice also that tier boundaries are also layer boundaries. This means that some inter-layer communication does need to be designed to be infrequent and coarse-grained.

 

For all practical purposes we can only insert tiers between layers that have been designed for efficient communication. This means that it is not true that n layers can automatically be deployed on n tiers. In fact, the number of potential tiers is entirely dependant on the design of inter-layer communication.

 

This means we have to provide terminology for inter-layer communication:

 

Term

Meaning

Fine-grained

Communication between layers involves the use of properties, methods, events, delegates, data binding and so forth. In other words, there’s a lot of communication, and each call between layers only does a little work.

Coarse-grained

Communication between layers involves the use of a very few methods. Each method is designed to do a relatively large amount of work.

 

If we have n layers, we have n-1 layer interfaces. Of those interfaces, some number m will be course-grained. This means that we can have at most m+1 tiers.

 

In most applications, the layer interface between the presentation and business logic layers is fine-grained. Microsoft has provided us with powerful data binding capabilities that are very hard to give up. This means that m is virtually never n-1, but rather starts at n-2.

 

In most modern applications, we use SQL Server or Oracle for data management. The result is that the layer interface between data access and data management is typically course-grained (using stored procedures).

 

I recommend making the layer interface between the business logic and data access also be course-grained. This provides for flexibility in placement of these layers into different tiers so we can achieve different levels of performance, scalability, fault-tolerance and security as required.

 

In a web environment, the presentation is really just the browser, and the actual UI code runs on the web server. Note that this is, by definition, two tiers – and thus two or more layers. The interaction between web presentation and web UI is coarse-grained, so this works.

 

In the end, this means we have some clearly defined potential tier boundaries that map directly to the course-grained layer interfaces in our design. These include:

 

  • Presentation <-> UI (web only)
  • Business logic <-> Data access
  • Data access <-> Data management

 

Thus, for most web apps m is 3 and for most Windows apps m is 2. So we’re talking about n layers being spread (potentially) across 3 or 4 physical tiers.

Protocols and Hosts

Now that we have an idea how layers and tiers are related, let’s consider this from another angle. Remember that layers are not only logical groupings of domain functionality, but also are grouped by technological dependency. This means that, when possible, all code required database transactions will be in the same layer (and thus the same tier). Likewise, all code consuming data binding will be in the same layer, and so forth.

 

The net result of this is that a layer must be deployed somewhere that the technological dependencies of that layer can be satisfied. Conversely, it means that layers that have few dependencies have few hard restrictions on deployment.

 

Given that tiers are physical constructs (as opposed to the logical nature of layers), we can bind technological capabilities to tiers. What we’re doing in this case is defining a host for tiers, which in turn contain layers. In the final analysis, we’re defining host environments in which layers of our application can run.

 

We also know that we have communication between tiers, which is really communication between layers. Communication occurs over specific protocols that provide appropriate functionality to meet our communication requirements. The requirements between different layers of our application may vary based on functionality, performance, scalability, security and so forth. For the purposes of this article, the word protocol is a high-level concept, encompassing technologies like DCOM, Remoting, etc.

 

It is important to note that the concept of a host and a protocol are different but interrelated. They are interrelated because some of our technological host options put restrictions on the protocols available.

 

In .NET there are three categorical types of host: Enterprise Services, IIS or custom. All three hosts can accommodate ServicedComponents, and the IIS and custom hosts can accommodate Services Without Components (SWC).

 

The following table illustrates the relationships:

 

Host

Protocols

Technologies

Enterprise Services
(Server Application)

DCOM

Simple .NET assembly

ServicedComponent

IIS

Web services
Remoting

Simple .NET assembly

ServicedComponent
SWC

Custom

Remoting
Web services (w/ WSE)
DCOM

Simple .NET assembly

ServicedComponent
SWC

 

The important thing to note here is that we can easily host ServicedComponent objects or Services Without Components in an IIS host, using Web services or Remoting as the communication protocol.

 

The all three hosts can host simple .NET assemblies. For IIS and Remoting this is a native capability. However, Enterprise Services can host normal .NET assemblies by having a ServicedComponent dynamically load .NET assemblies and invoke types in those assemblies. Using this technique it is possible to create a scenario where Enterprise Services can act as a generic host for .NET assemblies. I do this in my .NET Business Objects books for instance.

Hosts

What we’re left with is a choice of three hosts. If we choose Enterprise Services as the host then we’ve implicitly chosen DCOM as our protocol. If we choose IIS as a host we can use Web services or Remoting, and also choose to use or not use the features of Enterprise Services. If we choose a custom host we can choose Web services, Remoting or DCOM as a protocol, and again we can choose to use or not use Enterprise Services features.

 

Whether you need to use specific Enterprise Services features is a whole topic unto itself. I have written some articles on the topic, the most broad-reaching of which is this one.

 

However, there are some things to consider beyond specific features (like distributed transactions, pooled objects, etc.). Specifically, we need to consider broader host issues like stability, scalability and manageability.

 

Of the three hosts, Enterprise Services (COM+) is the oldest and most mature. It stands to reason that it is probably the most stable and reliable.

 

The next oldest host is IIS, which we know is highly scalable and manageable, since it is used to run a great many web sites, some of which are very high volume.

 

Finally there’s the custom host option. I generally recommend against this except in very specific situations, because writing and testing your own host is hard. Additionally, it is unlikely that you can match the reliability, stability and other attributes of Enterprise Services or IIS.

 

So do we choose Enterprise Services or IIS as a host? To some degree this depends on the protocol. Remember that Enterprise Services dictates DCOM as the protocol, which may or may not work for you.

Protocols

Our three primary protocols are DCOM, Web services and Remoting.

 

DCOM is the oldest, and offers some very nice security features. It is tightly integrated with Windows and with Enterprise Services and provides very good performance. By using Application Center Server you can implement server farms and get good scalability.

 

On the other hand, DCOM doesn’t go through firewalls or other complex networking environments well at all. Additionally, DCOM requires COM registration of the server components onto your client machines. Between the networking complexity and the deployment nightmares, DCOM is often very unattractive.

 

However, as with all technologies it is very important to weigh the pros of performance, security and integration against the cons of complexity and deployment.

 

Web services is the most hyped of the technologies, and the one getting the most attention by key product teams within Microsoft. If you cut through the hype, it is still an attractive technology due to the ongoing work to enhance the technology with new features and capabilities.

 

The upside to Web services is that it is an open standard, and so is particularly attractive for application integration. However, that openness has very little meaning between layers or tiers of a single application. So we need to examine Web services using other criteria.

 

Web services is not high performance, or low bandwidth.

 

Web services use the XmlSerializer to convert objects to/from XML, and that serializer is extremely limited in its capabilities. To pass complex .NET types through Web services you’ll need to manually use the BinaryFormatter and Base64 encode the byte stream. While achievable, it is a bit of a hack to do this.

 

However, by using WSE we can get good security and reliability features. Also Web services are strategic due to the focus on them by many vendors, most notably Microsoft.

 

Again, we need to evaluate the performance and feature limitations of Web services against the security, reliability and strategic direction of the technology. Additionally keeping in mind that hacks exist to overcome the worst of the feature limitations in the technology, allowing Web services to have similar functionality to DCOM or Remoting.

 

Finally we have Remoting. Remoting is a core .NET technology, and is very comparable to RMI in the Java space.

 

Remoting makes it very easy for us to pass complex .NET types across the network, either by reference (like DCOM) or by value. As such, it is the optimal choice if you want to easily interact with objects across the network in .NET.

 

On the other hand, Microsoft recommends against using Remoting across the network. Primarily this is because Remoting has no equivalent to WSE and so it is difficult to secure the communications channel. Additionally, because Microsoft’s focus is on Web services, Remoting is not getting a whole lot of new features going forward. Thus, it is not a long-term strategic technology.

 

Again, we need to evaluate this technology be weighing its superior feature set for today against its lack of long-term strategic value. Personally I consider the long-term risk manageable assuming you are employing intelligent application designs that shield you from potential protocol changes.

 

This last point is important in any case. Consider that DCOM is also not strategic, so using it must be done with care. Also consider that Web services will undergo major changes when Indigo comes out. Again, shielding your code from specific implementations is of critical importance.

 

In the end, if you do your job well, you’ll shield yourself from any of the three underlying protocols so you can more easily move to Indigo or something else in the future as needed. Thus, the long-term strategic detriment on DCOM and Remoting is minimized, as is the strategic strength of Web services.

 

So in the end what do you do? Choose intelligently.

 

For the vast majority of applications out there, I recommend against using physical tiers to start with. Use layers – gain maintainability and reuse. But don’t use tiers. Tiers are complex, expensive and slow. Just say no.

 

But if you must use physical tiers, then for the vast majority of low to medium volume applications I tend to recommend using Remoting in an IIS host (with the Http channel and BinaryFormatter), potentially using Enterprise Services features like distributed transactions if needed.

 

For high volume applications you are probably best off using DCOM with an Enterprise Services host – even if you use no Enterprise Services features. Why? Because this combination is more than two times older than Web Services or Remoting and its strengths and limitations and foibles are well understood.

 

Note that I am not recommending the use of Web services for cross-tier communication. Maybe I’ll change my view on this when Indigo comes out – assuming Indigo provides the features of Remoting with the performance of DCOM. But today it provides neither the features nor performance that make it compelling to me.


Thursday, August 12, 2004 3:20:16 AM (Central Standard Time, UTC-06:00)
If you don't use physical tiers (no app server), how can connection pooling be used. I thought the connection pool was maintained on the machine that opens the database connection (normally the app server)?
Karl Holbrook
Thursday, August 12, 2004 9:19:01 AM (Central Standard Time, UTC-06:00)
Excellent summary of layers, tiers, and applications and the issues involved with selecting the appropriate inter-tier communication technology for a distributed application.

I am almost finished with your C# Business Objects book. I implemented a similar distributed architecture built upon VB6/COM+ a few years ago and am in the process of migrating it to .NET (and trying to correct some of the short comings of the earlier system in the process). Since our system has some Rich Client UI components and could potentially run across a WAN, I have been very interested in following this 'conversation'.

A couple comments:

1) I'm not sure I understand why you are so intent on defining 'Services' as being an inter-application interface only. I can see value in internal services that are exposed by one layer of an application for the benefit of another. Isn't this similar to what Rich Turner is advocating?

2) I have no doubt that Remoting is faster in a LAN distribution scenario, isn't that edge lost in a WAN scenario when SSL must be used to ensure privacy?

Thanks for your excellent insight. I'm looking forward to watching the responses to your posting (both here and in the other blogs).
Todd Breyman
Thursday, August 12, 2004 9:58:56 AM (Central Standard Time, UTC-06:00)
Great blog posting. Thanks for the level headed perspective.

I posted my 2 cents feedback: http://dotnetjunkies.com/WebLog/sstewart/archive/2004/08/12/21842.aspx

BTW - Remoting over IIS is an awesome approach, but it seems everybody I work for or with is only designing "high volume" applications today - or so they think ;-)
Thursday, August 12, 2004 10:50:08 AM (Central Standard Time, UTC-06:00)
Excellent post Rocky! This same discussion comes up almost everyday on the projects that I am involved in as well, and sometimes turns into heated arguments just because people are not using the same terminology, and/or can't agree on the terminology from the start. So it almost feels like directing them to your blog to read this post before getting into any discussion with them.

Also a comment on SOA - My personal experience is that most people that don't agree with the way you describe SOA, are the people who don't have the experience - people who have never actually designed and implemented a distributed application. Just because the hype around SOA makes it seem like you should now implement all enterprise applications using a Service-Oriented Architecture, doesn't mean it is as simple as just using Web Services and that you don't have to worry about layers, tiers, protocols, etc. SOA is not revolutionary; it just helps us with one aspect of application architecture...

Also with Indigo coming, some people, and sad to say some Microsoft employees, are saying that we should abandon .NET Remoting right away because it is dead. Once again, they should all read your posts, and understand that the biggest effort of an application architecture is in designing/architecting for any of these technologies/protocols to be replaced, swapped-out one day. We can never do this 100%, but at least try and minimize the impact in the places where we are expecting it.

This way we get the maximum benefit right now, and we can switch to the "better" technology whenever it arrives and has been deemed "stable"...

Anton van der Merwe
Thursday, August 12, 2004 1:07:18 PM (Central Standard Time, UTC-06:00)
Todd, to answer you questions:

1) Re: No services between layers.

This is a terminology issue, not a design issue. In my mind there's little to no difference between a course-grained interface and a set of services. However, the term "service" is so hyped right now, that using it in more than one location within an architecture/design discussion is certain doom.

To put it another way, when I talk about using a course-grained interface between the business layer and data access layer, you could say I'm talking about having the data access layer expose a set of services (like I do with the DataPortal in the Business Objects books). But I avoid doing that because it further overloads the term "service" and makes productive conversation almost impossible.

Thus, services are for between applications only.

2) Re: Remoting and SSL.

Certainly using SSL has huge overhead. That overhead may be large enough to render meaningless the difference in overhead between using binary or XML data transfer.

But it has no impact on the feature set differences between the XmlSerializer (Web services) and the BinaryFormatter (Remoting). If you need the features, then Remoting is still something to consider. However, so are Web services, assuming you manually use the BinaryFormatter so you are transferring byte arrays across the Web service.

Given WSE 2.0, I'd strongly consider using Web services and manually calling the BinaryFormatter if my clients are outside my firewall. WSE has some nice security features that may be more efficient than SSL. For a CSLA .NET environment this is not a difficult switch, because the client-side and server-side DataPortal objects can easily be adjusted to do the BinaryFormatter calls and to use Web services as the underlying protocol rather than Remoting.

Rocky
Thursday, August 12, 2004 5:51:01 PM (Central Standard Time, UTC-06:00)
The thing you don't really consider is if you have decided to have a tier called Application Server how easy is it to scale that tier. In my limited experience this is very difficult withe Enterprise Services and brings in CLBS, etc. Web Services you get to use the well known load balancing technique that we currently use for the Web. Remoting can be lumped in here also if you limit yourself to SingleCall.

Great article though!

Chris
Chris Kinsman
Thursday, August 12, 2004 11:44:07 PM (Central Standard Time, UTC-06:00)
Pingback:

http://www.codinghorror.com/blog/archives/000049.html

Also Chris, great PDF on Smart Client, I recognize your name from it. We're doing a lot of SC as an organization, and there's a surprising amount of variance in the implementation paths people choose..

http://www.vergentsoftware.com/downloads/webvswinjax.pdf&e=7620
Friday, August 13, 2004 8:20:21 AM (Central Standard Time, UTC-06:00)
Good point Chris. I do mention in the article that you can use Application Center Server to load balance Enterprise Services, but I should have explicitly mentioned the easier solutions for Remoting and Web services.

I also should have put the SingleCall requirement as part of my recommend use of Remoting - along with the IIS host, Http channel and BinaryFormatter. It is the combination of these things that makes Remoting useful in a production setting.

Rocky
Friday, August 13, 2004 8:33:51 AM (Central Standard Time, UTC-06:00)
Karl, regarding connection pooling we have to consider whether we're talking about a Windows or Web application.

In a web application we get connection pooling "automatically" because all the code is already running on a single machine (or small pool of machines).

In a Windows application you do need to run the Data Access layer on a physical tier in order to get database connection pooling. Determining when you need to do this is ambiguous. Typically, using today's database technology you can support well over 100 concurrent users without worrying about scalability. However, if you have over 100 concurrent users then you should consider putting the Data Access layer on an application server to gain database connection pooling.

Rocky
Sunday, August 22, 2004 7:56:24 AM (Central Standard Time, UTC-06:00)
There are so many articles on the net mentioning DCOM limitation and inflexibility of implementation over the networks (LAN or Extranet). That is why the presence of Remoting makes perfect combination for connecting to Business Tiers in Enterprise Services.
Secondly, Remoting provides higher efficiency comparing to Web Services as XML format is less efficient, whereas remoting can be in binary or SOAP or in XML format when communicating through networks.
Now I am really confuse why Microsoft do not recommends Remoting combinations with Enterprise service through network, as Remoting suppose to serve as replacement for DCOM (works like RMI and do not have firewall concern).
Sunday, August 22, 2004 7:59:46 AM (Central Standard Time, UTC-06:00)
There are so many articles on the net mentioning DCOM limitation and inflexibility of implementation over the networks (LAN or Extranet). That is why the presence of Remoting makes perfect combination for connecting to Business Tiers in Enterprise Services.
Secondly, Remoting provides higher efficiency comparing to Web Services as XML format is less efficient, whereas remoting can be in binary or SOAP or in XML format when communicating through networks.
Now I am really confuse why Microsoft do not recommends Remoting combinations with Enterprise service through network, as Remoting suppose to serve as replacement for DCOM (works like RMI and do not have firewall concern).
Monday, August 23, 2004 3:40:30 AM (Central Standard Time, UTC-06:00)
We are developing an intranet-only application ( concurrent user number will not exceed 100, for sure ), with a database server machine and client computers ( with .net framework installed ). And we are planning to use the smart client approach with auto-deployment from a central IIS.
This technology seems to overcome the maintenance problem of the standart fat-client, 2-tier approach.
What is your idea about this? Do you think we need to deal with the three options you mention?
Onder
Wednesday, August 25, 2004 2:37:04 PM (Central Standard Time, UTC-06:00)
I am an advocate of smart client and no-touch deployment in general. Yes, if properly designed the no-touch deployment of a smart client can give you the benefits of a rich/smart/intelligent client without the deployment issues.

Rocky
Wednesday, August 25, 2004 6:40:11 PM (Central Standard Time, UTC-06:00)
Rocky, I was very glad to read your post - we have recently come to the same conclusion about communication between tiers in multi-tier applications, but were slightly concerned that virtually all experts (including Microsoft employees) appear to advocate Web Services for ALL new development (except between App Domains in the same Process).
We have begun using Remoting with IIS as a host (binary formatter over HTTP) and it seems to be very easy to use and much more configurable/extensible than DCOM. It doesn't quite match the performance we got from DCOM with its proprietary binary formatting, but the difference is absolutely irrelevant for our real-world systems (admittedly these are intranet applications, none of which will ever have more that a few hundred simultaneous users).
Incidentally, I can confirm that it works very well with no-touch deployment – this alone is a huge advantage over DCOM where installing/registering components required more access to the local computer than our users will ever have,
It's good to see that we're not entirely alone in our views!

Cathal
Cathal Ryan
Friday, September 17, 2004 1:02:05 PM (Central Standard Time, UTC-06:00)
Thanks Rocky. That remoting "is not a long term strategic technology" was news to me. I'm glad to have seen it so that we don't go down that road. We are at the start of a project and have a chance to maybe "get it right". We inclined to use Enterprise Services since COM+ appears to have a lot of support in Application Center 2000. However, since Application Center 2000 appears to be at the end of it's lifecycle, I'm wondering what will happen in a few years. Any thoughts to where Enterprise Services will be? Is it a safe choice?

Randy

Randy
Comments are closed.