In a traditional layered architecture, service is literally synonymous with business logic layer. It's the layer between UI and Data. Therefore, all business rules go into services. The data layer should only understand basic CRUD operations, and the UI layer should deal only with the mapping of presentation DTOs to and from the business objects.
In an RPC-style distributed architecture (SOAP, UDDI, BPEL, etc.), the service is the logical version of a physical endpoint. It is essentially a collection of operations that the maintainer wishes to provide as a public API. Various best practices guides explain that a service operation should in fact be a business-level operation and not CRUD, and I tend to agree.
However, because routing everything through an actual remote service can seriously hurt performance, it's normally best not to have these services actually implement the business logic themselves; instead, they should wrap an "internal" set of business objects. A single service might involve one or several business objects.
In an MVP/MVC/MVVM/MV* architecture, services don't exist at all. Or if they do, the term is used to refer to any generic object that can be injected into a controller or view model. The business logic is in your model. If you want to create "service objects" to orchestrate complicated operations, that's seen as an implementation detail. A lot of people, sadly, implement MVC like this, but it's considered an anti-pattern (Anemic Domain Model) because the model itself does nothing, it's just a bunch of properties for the UI.
Some people mistakenly think that taking a 100-line controller method and shoving it all into a service somehow makes for a better architecture. It really doesn't; all it does is add another, probably unnecessary layer of indirection. Practically speaking, the controller is still doing the work, it's just doing so through a poorly named "helper" object. I highly recommend Jimmy Bogard's Wicked Domain Models presentation for a clear example of how to turn an anemic domain model into a useful one. It involves careful examination of the models you're exposing and which operations are actually valid in a business context.
For example, if your database contains Orders, and you have a column for Total Amount, your application probably shouldn't be allowed to actually change that field to an arbitrary value, because (a) it's history and (b) it's supposed to be determined by what's in the order as well as perhaps some other time-sensitive data/rules. Creating a service to manage Orders does not necessarily solve this problem, because user code can still grab the actual Order object and change the amount on it. Instead, the order itself should be responsible for ensuring that it can only be altered in safe and consistent ways.
In DDD, services are meant specifically for the situation when you have an operation that doesn't properly belong to any aggregate root. You have to be careful here, because often the need for a service can imply that you didn't use the correct roots. But assuming you did, a service is used to coordinate operations across multiple roots, or sometimes to handle concerns that don't involve the domain model at all (such as, perhaps, writing information to a BI/OLAP database).
One notable aspect of the DDD service is that it is allowed to use transaction scripts. When working on large applications, you're very likely to eventually run into instances where it's just way easier to accomplish something with a T-SQL or PL/SQL procedure than it is to fuss with the domain model. This is OK, and it belongs in a Service.
This is a radical departure from the layered-architecture definition of services. A service layer encapsulates domain objects; a DDD service encapsulates whatever isn't in the domain objects and doesn't make sense to be.
In a Service-Oriented Architecture, a service is considered to be the technical authority for a business capability. That means that it is the exclusive owner of a certain subset of the business data and nothing else is allowed to touch that data - not even to just read it.
By necessity, services are actually an end-to-end proposition in an SOA. Meaning, a service isn't so much a specific component as an entire stack, and your entire application (or your entire business) is a set of these services running side-by-side with no intersection except at the messaging and UI layers. Each service has its own data, its own business rules, and its own UI. They don't need to orchestrate with each other because they are supposed to be business-aligned - and, like the business itself, each service has its own set of responsibilities and operates more or less independently of the others.
So, by the SOA definition, every piece of business logic anywhere is contained within the service, but then again, so is the entire system. Services in an SOA can have components, and they can have endpoints, but it's fairly dangerous to call any piece of code a service because it conflicts with what the original "S" is supposed to mean.
Since SOA is generally pretty keen on messaging, the operations that you might have packaged in a service before are generally encapsulated in handlers, but the multiplicity is different. Each handler handles one message type, one operation. It's a strict interpretation of the Single Responsibility Principle, but makes for great maintainability because every possible operation is in its own class. So you don't really need centralized business logic, because commands represents business operations rather than technical ones.
Ultimately, in any architecture you choose, there is going to be some component or layer that has most of the business logic. After all, if business logic is scattered all over the place then you just have spaghetti code. But whether or not you call that component a service, and how it's designed in terms of things like number or size of operations, depends on your architectural goals.
There's no right or wrong answer, only what applies to your situation.
Best Answer
I like where you are going with this curiosity, so I'm going to bring up something else I see.
To follow not only "Separation of Concerns", but also "Persistence Ignorance", it is almost always a Very Bad Idea to allow your UI layer to call into your business/data side with a "Get All" (Or even close) method. I realize there may be a constraint or two like
Where UserId == LoggedInUser
, but that is still too close.The reason being, suddenly you have clever UI Developers using the "Get All" method, and performing business/Data-Access logic on the UI to separate out information, pick and filter through, etc.
Even if you tell yourself that will never happen, or that you're the only one in the next 100 years that will touch this code and you Promise yourself you'll never do that, you still shouldn't open the UI up to such power.
Now imagine some time in the future a single UI Control needs to display JUST the Answered (or pending) tickets. What do you do now? You have to "Get All" and perform your filtering logic on the UI side?
I wouldn't even put that into the Business Logic. This is about data separation. You should have as finite queries as possible in your Data-Access layer, and expose only those required results to your Business Logic. Your Business Logic in this case may just be a wrapper to return a Data-Access result, but that's okay. That's the BLL's responsibility to determine the Persistence object and route calls.
Now, if you need a list on your UI side that shows "All" Tickets for a user, it may be prudent to have that "Get All" method where the only filter is the UserId. However, it may be more prudent to combine the Pending and Answered Queries. Why?
What if in the future you add a "Deleted", "Removed", "In-Flux", "New" or any other kind of status? Now you have to re-write code because all you wanted to do is show a Combined List of Pending and Answered questions.
So give your UI less control over massive lists, and instead allow it to pull back only the limited information it needs, and alter/combine from there.