I've been working on building a set of enterprise services using WCF 4 within my organization and could use some guidance. The setup/architecture I've designed thus far is similar to a lightweight custom ESB. I have one main "broker" service (using wsHttp), that connects to three underlying netTcp services. Both the broker and underlying services share a common assembly that contains the model, as well as the contract interfaces. In the broker service I can choose which operations from the underlying services I want to expose. The idea is that potentially we can have a core of set of services and few different brokers on top of them depending on the business need. We plan on hosting everything (including the netTcp services) in IIS 7.5 leveraging AppFabric and WAS.
Here's my question, is such a design good practice and will it scale? These services should be able to handle thousands of transactions per day.
I've played around with the routing in WCF 4 in lieu of the broker service concept I've mentioned, however, have not seen much value in it as it just simply does a redirect.
I'm also trying to figure out how to optimize the proxies that the broker service (assuming this practice is advisable) has to the underlying services. Right now I simply have the proxies as private members within the brokers main class. Example:
private UnderlyingServiceClient _underlyingServiceClient = new UnderlyingServiceClient();
I've considered caching the proxy, however, am concerned that if I run into a fault that the entire proxy at that point would be faulted and cannot be reused (unless I catch the fault and simply re-instantiate).
My goal with these services is to ensure that the client consuming them can get "in and out" as quickly as possible. A quick request-reply.
Any input/feedback would be greatly appreciated.
If i understand you correctly, you have a handful of "backend" services, possibly on separate computers. Then you have one "fontend" service, which basically acts like a proxy to the backend, but fully customizable in code. We are doing this exact setup with a few computers in a rack. Our frontend is IIS7, backend is a bunch of wcf services on several machines.
One, will it scale? Well, adding more processing power on the backend is pretty easy, and writing some load balancing code isn't too bad either. For us, the problem was the frontend was getting bogged down, even though it was only acting as a proxy. We ended up adding a couple more front end computers, "brokers" as you call them. That works very well. People have suggested that I use Microsoft ForeFront for automatic load balancing, but I have not researched it yet.
Two, should you cache the proxy? I would say definitely yes, but it kind of sucks. These channels DO fault occasionally. I have a thread always running in the background. Every 3 seconds, it wakes up, checks all the wcf services and wcf clients in the app. Any that are faulted get destroyed and recreated.
check host channels: ...
while(true)
{
try{if(MyServiceHost.State!=System.ServiceModel.CommunicationState.Opened) {ReCreate();}} catch{}
System.Threading.Thread.Sleep(3000);
}
check client channels: ...
private static ChannelFactory<IMath> mathClientFactory = new ChannelFactory<IMath>(bindingHttpBin);
while(true)
{
try
{
if(MyServiceClient.State==System.ServiceModel.CommunicationState.Faulted)
{
EndpointAddress ea = new EndpointAddress(ub.Uri);
ch = WcfDynamicLan.mathClientFactory.CreateChannel(ea);
}
}
catch{}
System.Threading.Thread.Sleep(3000);
}
On the client, I not only cache the channel, but also cache the ChannelFactory. This is just for convenience though to make the code for creating a new channel shorter.
Related
I have a .Net core application that consists of some background tasks (hosted services) and WEB APIs (which controls and get statuses of those background tasks). Other applications (e.g. clients) communicate with this service through these WEB API endpoints. We want this service to be highly available i.e. if a service crashes then another instance should start doing the work automatically. Also, the client applications should be able to switch to the next service automatically (clients should call the APIs of the new instance, instead of the old one).
The other important requirement is that the task (computation) this service performed in the background can’t be shared between two instances. We have to make sure only one instance does this task at a given time.
What I have done up to now is, I ran two instances of the same service and use a SQL server-based distributed locking mechanism (SqlDistributedLock) to acquire a lock. If a service could acquire a lock then goes and do the operation while the other node waiting to acquire the lock. If one service crashed the next node could be able to acquire the lock. On the client-side, I used Polly based retry mechanism to switch the calling URL to the next node to find the working node.
But this design has an issue, if the node which acquired the lock loses the connectivity to the SQL server then the second service managed to acquire the lock and started doing the work while the first service is also in the middle of doing the same.
I think I need some sought of leader election (seems done it wrongly), Can anyone help me with a better solution for this kind of a problem?
This problem is not specific to .Net or any other framework. So please make your question more general so as to make it more accessible. Generally the solution to this problem lies in the domain of Enterprise Integration Patterns, so consult the references as the status quo may change.
At first sight and based on my own experience developing distributed systems, I suggest two solutions:
use a load balancer or gateway to distribute requests between your service instances.
use a shared message queue broker to put requests in and let each service instance dequeue a request for processing.
Either is fine and I can use both for my own designs.
I have a WCF service with ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple). I want to use ThreadStatic variable to srore data.
I start worrying about is it possible two parallel requests for the same or different operationContracts get handled by the same thread serverside, because if this happens my ThreadStatic variable will get overriden.(I.e. something like the thread changing between HttpHandlers and HttpModules in ASP.NET)
I made a spike service with the same ServiceBehaviour and maxConcurrentCalls="2". After that a wcf client called the service with 50 parallel requests and my worry did not occur. However this is not a 100% proof.
Thank in advance!
Irrespective of the ConcurrencyMode, a ThreadStatic value will persist when your request terminates and the thread is returned to the thread pool. The same thread can be reused for a subsequent request, which will therefore be able to see your ThreadStatic value.
Obviously this won't be true for two concurrent requests, because by definition they will be executed on different threads.
From comments:
Also by definition MSDN says: 'The service instance is multi-threaded. No synchronization guarantees are made. Because other threads can change your service object at any time, you must handle synchronization and state consistency at all times.' So it is not so obvious:)
This means that a single instance of your service class can be accessed concurrently by multiple requests. So you would need to handle synchronization for any accesses to instance members of the service class.
However ThreadStatic members are by definition only used by one thread (and hence one request) at a time, so don't need synchronization.
The direct answer to your question is Joe's answer.
However you mention in the comments you are using an ambient design pattern. That pattern is already implemented in WCF as the OperationContext and is specifically designed to be extensible. I highly recommend using OperationContext over any custom thread storage.
See Where to store data for current WCF call? Is ThreadStatic safe?
I wanted to add to Joe's answer here because I would recommend that you use some sort of correlation for your requests if you're needing to store state. The threading model will become very convoluted and unreliable in production.
Further, now imagine you have two IIS servers hosting this service and a hardware or software load balancer forward facing so that you can consume it. To ensure that the correct state is gathered you'll need correlation because you never know which server the service will be started on. In the post below I mocked up a simplified version of how that might work. One thing to keep in mind is that the SessionState would need to be kept in a shared location to all instances of the service, an AppFabric Cache server for example.
Global Variable between two WCF Methods
I am very new to remoting in flex. I am using flex 4.5 and talking to a web application built by someone else on the team using AMF. They have used Zend_AMF to serialize and unserialize the data.
One of the main issues I am facing at the moment is that I will need to talk to a lot of services (about 60 or so).
From examples on remoting I have seen online and from adobe, it seems that I need to define a remoting object for EACH service:
<mx:RemoteObject id="testservice" fault="testservice_faultHandler(event)" showBusyCursor="true" destination="account"/>
With so many services, I think I might have to define about 60 of those, which I don't think is very elegant.
At the same time, I have been playing with Pinta to test out the AMF endpoint. Pinta seems to be able to allow one to define an arbitary amount of services, methods and parameters without any of these limitations. Digging through the source, I find that they have actually drilled down deep into the remoting and are handling a lot of low level stuff.
So, the question is, is there a way to approach this problem without having to define loads or remoteobjects and without having to go down too deep and start having to handling low level remoting events ourselves?
Cheers
It seems unusual for an application to require that many RemoteObjects. I've worked on extremely large applications, and we typically end up with no more than ~6-10 RemoteObject declarations.
Although you don't give a lot of specifics in your post about the variations of RemoteObjects, I suspect you may be confusing RemoteObject with Operation.
You typically declare a RemoteObject instance for every end-point in your application. However, that endpoint can (and normally does) expose many different methods to be invoked. Each of these server-side methods gets results in a client-side Operation.
You can explicitly declare these if you wish, however the RemoteObject builds Operations for you if you don't declare them:
var remoteObject:RemoteObject;
// creates an operation for the saveAccount RPC call, and invokes it,
// returning the AsyncToken
var token:AsyncToken = remoteObject.saveAccount(account);
token.addResponder(this);
//... etc
If you're interacting with a single server layer, you can often get away with a single RemoteObject, pointing to a single destination on the API, which exposes many methods. This is approach is often referred to as an API Façade, and can be very useful, if backed with a solid dependency injection discipline on the API.
Another common approach is to segregate your API methods by logical business area, eg., AccountService, ShoppingCartService, etc. This has the benefit of being able to mix & match protocols between services (eg., AccountService may run over HTTPS).
How you choose to split up these RemoteObjects is up to you. However, 60 in a single applications sounds a bit suspect to me.
Hi i am creating an API using WCF. My question can be broken down into two seperate ones
1) I have quite a few calls, for instance i have calls relating to the customer, products, orders, employees.
My question is should all this go into one public interface class e.g
public interface IRestService
public class RestService : IRestService
Or should I have one for each call e.g
public interface ICustomer
public class Customer : ICustomer
public interface IProducts
public class Products: IProducts
2) If you have an API which will be accessed by tens of thousands of users and thousands of users concurrently, how would you set up, what will your web config settings be for instance in terms of throttling. Also what setting would you give your InstanceContextMode, or ConcurrencyMode. Finally what type of binding would it be, bearing in mind websites and mobile phones can access the api.
For the sake of good practice, I would break up the API into separate interfaces so you have the option of splitting them into separate implementations in the future. You can still have just one service class implement all of the interfaces, like this:
public class RestService : ICustomer, IProducts, IOrders
However, it sounds as if you'd probably want to make them separate implementations anyway.
In terms of concurrency settings, ask yourself what resources need to be used on each call. If your service class's constructor can be written without any lengthy startup, then use PerCall. If you need to initialize expensive resources, then I'd recommend InstanceContextMode.Single with ConcurrencytMode.Multiple and make sure you write thread-safe code. Eg: make sure you lock() on any class properties or other shared resources before you use them.
Database connections would not count as "expensive to initialize", though, because ADO will do connection pooling for you and eliminate that overhead.
Your throttling settings will be revealed by testing, as Ladislav mentions. You'd want to stress-test your service and use the results to get an idea of how many machines you'd need to service your anticipated load. Then you'll need a dedicated load balancer to route requests as either round-robin, or something that checks the health of each server. Load balancers can be set up to GET a "systemhealth.asp" page and check the results. If you return an "OK" then that machine stays in the pool, or can be temporarily removed from the pool if it times out or returns any other status.
Your binding would need to be WebHTTPBinding for REST. BasicHTTPBinding is meant for SOAP interfaces and doesn't support [WebGet], for example.
If it doesn't have to be a REST service, then you can get a bit more performance by using NetTcpBinding.
If you really have few operations, single service can be used. Generally services are logical collection of related operations but the number of operations should be limited. Usually if your service have more than 20 operations you should think about refactoring.
Do you plan to use REST service? I guess you do because of your first interface example. In such case you need WebHttpBinding (or similar custom binding) with default InstanceContextMode (PerCall) and ConcurrencyMode (Single) values. Only other meaningful combination for REST service is InstanceContextMode.Single and ConcurrencyMode.Multiple but it will create your service as singleton which can have impact on your service implementation. My rule of thumb: Don't use singleton service unless you really need it.
Throttling configuration is dependend on your service implementation and on performance of your servers. What does thousands concurrent users really mean for you? Processing thousands of requests concurrently requires good server cluster with load balancer or hosting in Azure (cloud). All is also dependend on the speed of processing (operation implementation) and size of messages. The correct setting for MaxConcurrentInstances and MaxConcurrentCalls (should be same for PerCall instancing) should be revealed by performance testing. Default values for service throttling have changed in WCF 4.
I'm wondering if it is a good approach in the ASP.NET project if I set a field which "holds" a connection to a DB as a static field (Entity Framework)
public class DBConnector
{
public static AdServiceDB db;
....
}
That means it'll be only one object for entire application to communicate with a DB. I'm also wondering about if that object will be refreshing data changes from DB tables, or maybe it shouldn't be static and I shoud create a connection dyniamically. What do You think ?
With connection pooling in .NET, generally creating a new connection for each request is acceptable. I'd evaluate the performance of creating a new one each time, and if it isn't a bottleneck, then avoid using the static approach. I have tried it before, and while I haven't run into any issues, it doesn't seem to help much.
A singleton connection to a database that is used across multiple web page requests from multiple users presents a large risk of cross-contamination of personal information across users. It doesn't matter what the performance impact is, this is a huge security risk.
If you don't have users or personal information, perhaps this doesn't apply to your project right now, but always keep it in mind. Databases and the information they contain tend to evolve in the direction of more specifics and more details over time.
This is why you should not use a singleton design pattern with your database connection
Hope it helps
Is using a singleton for the connection a good idea in ASP.NET website
Bad idea. Besides the potential mistakes you could make by not closing connections properly and so forth, accessing a static object makes it very difficult to unit test your code. I'd suggest using a class that implements an interface, and then use dependency injection to get an instance of that class wherever you need it. If you determine that you want it to be a singleton, that can be determined in your DI bindings, not as a foundational point of your architecture.
I would say no.
A database connection should be created when needed to run a query and cleaned up after that query is done and the results are fetched.
If you use a single static instance to control all access to the DB, you may lose out on the automatic Connection Pooling that .NET provides (which could impact performance).
I think the recommendation is to "refresh often."
Since none of the answers have been marked as an answer and I don't believe any have really addressed question or issue thereof...
In ASP.NET, you have Global or HttpApplication. The way this works is that IIS will cache instances of your "application" (that is an instance of your Global class). Normally (default settings in IIS) you could have up to 10 instances of Global and IIS will pick any one of these instances in order to satisfy a request.
Further, keep in mind that, there could be multiple requests at any given moment in time. Which means multiple instances of your Global class will be used. These instances could be ones that were previously instantiated and cached or new instances (depending on the load your IIS server is seeing).
IIS also has a notion of App Pools and worker processes. A Worker process will host your application and all the instances of your Global classes (as discussed earlier). So this translates to an App Domain (in .NET terms).
Just to re-cap before moving on…
Multiple instances of your Global class will exist in the Worker process for your application (in IIS). Each one waiting to be called upon by IIS to satisfy a request. IIS will pick any one of these instances. They are effectively threads that have been cached by IIS and each thread has an instance of your Global class. When a request comes in, one of these threads is called upon to handle the request-response cycle. If multiple requests arrive simultaneously, then multiple threads (each contains an instance of your Global class) will be called upon to satisfy each of those requests.
Moving on…
Since there will be only one instance of a static class per App Domain you'll effectively have one instances of your class shared across all (up to 10) instances of Global. This is a bad idea because when multiple simultaneous requests hit your server they'll either be blocked (if your class’s methods use locks) or threads will be stepping on each other’s toes. In other words, this approach is not inherently thread-safe and if you make it thread safe using thread synchronization primitives then you’re unnecessarily blocking threads, negatively impacting performance and scalability of your web application, with no gain whatsoever.
The real solution (and I use this in all my ASP.NET apps) is to have an instance of your BLL or DAL (as the case may be) per instance of Global. This will ensure the following:
1. Multiple threads are not an issue since IIS guarantees one request-response per instance of Global) at any given moment in time. So you’re code is inherently threads-safe.
2. You only have up to 10 instances of your BLL/DAL up and running at any given moment in time ensuring that you're not constantly creating and disposing instances of (typically) large objects to satisfy each request, which on busy sites is huge
3. You get really good performance well due to #2 above.
You do have to ensure that your BLL/DAL is truly stateless or that you reset any state at the start of each Request-Response cycle. You can use the BeginRequest event in Global to do that is you need to.
If you go down this route, be sure to read my blog post on this
Instantiating Business Layers – ASP.NET