8
votes

I want to build a microservice application based on Azure Service Fabric. For some stateful services or actors I want to access the state from outside via web api.

What are the general trade-offs and best practices for such a Service Fabric project regarding to:

  1. using one vs. multiple services in a single application? Therefore if I use one service per application, I will have multiple applications for my project. When is it useful to use one service per application?

  2. using one vs. multiple actors in a single service? When is it useful to have more than one actor per service?

  3. using one stateless web api service for the whole project vs. multiple stateless web services for each stateful service or for each application?

I know these decisions are based on the specific project. But maybe there are general advantages and disadvantages for the three points above.

2
Please see "Should questions include “tags” in their titles?", where the consensus is "no, they should not"!user57508
@AndreasNiedermair I changed the title.CPA

2 Answers

5
votes

Simon Houlton covered the trade-offs around microservices pretty well in his answer, so here are some answers specifically to your Service Fabric questions:

  1. Applications are a grouping construct for services. In theory, services that work together to produce a cohesive set of functionality or accomplish a single business goal are usually grouped into an application. In practice:

    • Upgrades are applied at the application level. Services that generally need to be upgraded together should be in the same application. But you can still upgrade service within an application individually too.
    • Health status is rolled up at the application level so you get an all-up health overview of services within an application.
    • Visual Studio tooling makes it pretty easy to work with an application that has multiple services.
  2. Usually a service is host to multiple instances of one actor type. In other words, you usually map one actor type to one service type. Then you can instantiate multiple instances of that actor type in the service.

  3. Depends on what you want here really. What's the stateless service doing? If you need a single ingress point for your users, then you should have one stateless web api for the whole project. That's pretty standard. Maybe you have a second stateless service listening on a different port just for admins or something. If you have a stateless web api service for each stateful service, then you have to worry about routing users to the right stateless service.
4
votes

It's a tricky one to trade off the different options against each other as they're not necessarily mutually exclusive but here's a bit of start on some of the points you mention, also I know this isn't necessarily tackling your Service Fabric question but I'm hoping it is still useful.

A micro services environment is great from a code perspective, it makes the developers lives easy. By centralising functionality to one service it means they can focus on the problem without thinking of unnecessary dependencies. For example if you were to group all your methods in one project and you had to change the interface you may decide to create a new end point. In this example you may have to consider the consumers of methods that aren't changing, do we want to force them to uplift or are we happy for them to point to the previous version but of course then you're supporting multiple versions.

The big problem is microservices breed isolated knowledge and by taking the approach that the developer of one service doesn't need to know who or what is consuming it means you're unable to answer what can often be a very important question of who or what is consuming this service and do we need to force them to uplift to a new end point. In practical terms this can leave your web servers in a bit of a mess with old services knocking about that don't need to be.

Independent of what your solution is I'd always try and group your logic and place similar methods in the same project. I think you have to accept that you make decisions without full knowledge of how the solution will develop in the future and therefore you may have to shuffle things about.

Another consideration would be management of requirements and parallel development. With micro services you're probably able to manage business requirements much more easily than with a single service. Assume you get given 10 requirements and are requested to deliver 5 in the next month and the other 5 the month after. Say for example the first 5 requirements are focused in business logic a and the next lot in business logic b, if you have two developers you can get them to work on this in parallel without having to branch and merge. This is obviously a nice example to illustrate the point however it's a relatively easy conversation to have if they're split over different services because it's easy to say to the business peeps that your business logic A changes need to go together.

Stateful webservices can be tricky to quickly test, admittedly you can get round this but I always like being able to throw a request a service and get a response, if I have to prep things it slows me down and this can be frustrating when diagnosing live issues.