I've got one question concerning microservices architecture. I am designing a system based on microservices. I've read few articles and I think I understand the idea. However, I don't how microservices should communicate with each other while they have separate business responsibilities....
What I mean is that if I have a system for booking train tickets, I would divide backend application into modules:
Client (login,logout,registration)
Reservations (booking a train seat for user,getting all reservations for user)
ConnectionsDetails
(searching for connections,getting connection details)
Trains
(information about trains- seats number,class etc.)
Now, I can only think that if user search for connections module ConnectionsDetails communicate with Trains module and ask about particular train details. But how could other microservices communicate? If user wants to login - she/he asks directly Client module, if she/he wants to get all her reservations - asks Reservation module DIRECTLY etc...
So my question is, how should modules communicate if they do different things? I'm sorry if my question is trivial or stupid, I'm just starting with microservices.
EDIT:
I didn't mean what tools could I use for communication. My question is about logic. In the example I showed, why one microservice could ask another microservice about sth if client can directly ask the another one? As I said earlier, how they should communicate(about what should they ask each other exactly) if they do separate things?
To find the right contexts, borders and communication channels is imho one of the most difficult parts of a microservice architecture. It is about finding the data you need, how the relationships are and which service is responsible for what (responsible means the only one allowed to change it). Have a look at the Blog from Martin Fowler.
Microservices is not modules. Each service should be an independent service regarding development and deployment. And yes, they may communicate to each other but a client may also communicate to them individually. The Microservice approach is also about using the right tool for the problem. So each service can be implemented in a different programming language. They can use different kind of storage like RDMBS, NoSQL or Key-Value store. An they will be scaled individually - many instances for ConnectionsDetails and fewer for Reservations e.g.
What will happen if one service is not available? Each service should be as fault tolerant as possible and try to decrease it's service gracefully if nothing else is possible. You should think about minimising the needed communication between the services by choosing the right borders, make data independent and maybe introduce caching. Don't forget about the CAP theorem, a microservice approach makes it more visible. Here are some slides about resilience that may help. Do not share the same database or replicate everything between services.
"how should modules communicate if they do different things?". You should choose a language independent way of communication and depending on your problem a synchronous or asynchronous method. As a language independent format JSON or XML are most common. Synchronous communication can be based on REST, asynchronous communication on messaging. The authentication ("Client") is typically a REST service, sending the booked tickets via Email is more a message driven asynchronous service.
As I think that is a major question about classical SOA vs. Microservices.
I guess you can find many opposite answers to that.
so IMHO:
If in your architecture services communicate each other they are not microservices, since there are dependencies between them.
Instead of that if each microservice has all needed functionality (or say components) and do not depend or communicate to each other then they are microservices.
So in your example you have 4 components.
Clients, Reservations, ConnectionsDetails, Trains.
But, microservices may not necessary match them exactly.
As you said "if user search Connection"...
So "Search Connection" that is microservice which includes all needed components (Client, ConnectionDetails, Trains) and is independent.
And finally, how components (not microservices) will communicate to each other is up to you. With microservices you have a luxury to use straight POJO with no transformations, protocols, transport layers at all.
Or you can make communications more formal, which push you back closer to classical SOA rather than microservices.
Related
I am reading a project used microservice. But it seems different from normal microservice.
all microservices deployed in the same docker container, but each microservice has its own HTTP server listened to a random port. normal microservice usage should deploy one microservice on one server.
use only one database, not one microservice one database.
So i have questions as follows.
Is this a distributed system?
What Pros and cons compared with Single Application Service(already seperated to several modules based on DDD) and normal microservice?
Your described application doesn't seem like a matured microservice-based architecture.
Having a common database is not a problem, but it depends how you use it. If you have clear responsibilities and don't access the data of other services, it can be a nice way to reduce administrative overhead for multiple databases. On the other hand the database might become a point of failure. So there is a trade-off to be considered. However, if you directly access data of other microservices and there is no clear concept of responsibility for data, I'd say it is an anti-pattern or a smell. You give up the criteria of independent deployability (data model changes will break consumers).
In the described deployment scenario in one docker container this criteria of independent deployability is not given at all, as well as horizontal scalability. I'd strongly advice against it if you want to reap the benefits of microservices. Otherwise you will end up with the drawbacks of both world: a distributed deployment monolith.
I could imagine the described architecture is in a migration phase towards real microservices (docker container each service), but hasn't matured yet.
I have created a simple blogging application using Spring Boot and RESTful APIs. I have connected the same to a MySQL database to run some SQL queries like those for adding a blog, deleting a blog, etc.
My questions are as follows:
Does it mean that I have used a microservice architecture? When does an architecture become a microservice? (I ask because many similar websites call an application as microservice-based. Other than the main application, e.g., currency exchange instead of blogging, I see no other difference; for e.g., this one - it does have many more aspects, but they are not contributing to its microservice-ness, IMHO).
Can I call an application as horizontally scalable if I am using microservice-based architecture?
Note: The tutorial I followed is here and the GitHub repo is here.
First of all: those aren't exact yes/no questions. I'll give you my opinion, but others will disagree.
You have created what most people would agree qualifies as a Microservice. But a Microservice does not make a Microservice architecture, in the same way that a tree doesn't make a forest.
A Microservice architecture is defined by creating a greater application that consists of several distributed components. What you have done is created a monolith (which is absolutely fine in most cases).
Almost every talk about Microservices that I have attended has featured this advice: start with a monolith, evolve to microservices once you need it.
Regarding the last question: your application is horizontally scalable if it is stateless. If you keep any session state, it can still be horizontally scalable, but you'll need a smart LB managing sticky sessions or distributed sessions. That's when things get interesting, and when you can start thinking about a Microservice architecture.
Common problems are: how can I still show my customers my website, if the order database, cart service, payment provider etc. are down. Service discovery, autoscaling, retry strategies, evolving Rest apis, those are common problems in a Microservice architecture. The more of them you use and need, the more you can claim to have a Microservice architecture.
Not at all. The use of microservices is an advanced architecture pattern that is hard to implement right, but that gives useful benefits in huge projects. This should not be of any concern to a small project, unless you want to test this particular architectural style.
Breaking an application in smaller chunk does increase its scalability, as resources can be increased on a smaller scale. However, statelesness, among other properties, are also key components to a scalable architecture.
First of all, what you showed us dont looks like microsservice at all.
You can say that you have an application that uses microsservices architecture when it is formed by microsservices(oh rly?) with independent functionalities and that can be scalable. Scale one service, means that you will run multiple instances (possible in multiple hosts) and it will be transparent for other services.
A good example to ilustrate that is a web store microsservice based composed by 4 microsservices:
Sale Microsservice
Product Microsservice
Messaging Microsservice
Authentication Microsservice
In a blackfriday event, for example, which theoretically will occur a lot of purchases, you can scale only the Sale Microsservice, saving resources from the other three (of course this means using a bunch of other technologies like proxy, LB ...). If you were using a monolithic architecture would need to scale all your application.
If you are using correctly a microsservice architecture, yes, you can say that your application is horizontally scalable.
I have built few microservices that consume a number of external services. Few of these external services are consumed by more than 1 microservice that I have built. I have built the connectors to these microservices as a library project and have included it as a dependency in all my microservice projects. However I read that all logic for microservices should be self contained and duplication of logic is ok. If that's the case , is it recommended for me to define these connectors within each every microservice instead of having a shared library?
...all logic for microservices should be self-contained and
duplication of logic is ok
I think this is the core of the issue you are struggling with. Is this statement actually true?
A quick google search later:
http://www.simplicityitself.io/our%20team/2015/01/12/sharing-code-between-microservices.html
This article talks about this exact question, which we can now frame as What is the appropriate level of re-use in microservice architecture?
The author provides a list of reasons why developers feel the need to share code, ordered from lowest to highest in terms of coupling and loss of isolation:
Leverage existing technical functionality
Sharing data schemas, using a class, for example, as an enforcement of a shared schema.
Sharing data sources, use of the same database by multiple services.
Though this list covers most of the reasons, I would add another important reason to share code, which is to do with a common framework for rapid standing up of microservices, commonly called the Microservice Chassis pattern.
The author goes onto say:
It is of utmost importance to pin down your motivation for wanting to
share code, as unfortunately there is no right answer to this
question. Like everything else, it’s contextual.
So, all that said, should you centralize your connectors or not?
Well, where do these dependencies fit in on our list? And what degree of coupling can you endure before you're no longer doing microservices but building a monolith instead?
These are not easy questions to answer, but hopefully this will help guide you to the correct conclusion.
We're designing two distinct systems which can be simulated by the following typical example.
Web App #1 - Course catalog (allows updating / populating the course catalog)
Professors
Course (courseCode, professorId, list of Prerequisites, grade scale used)
Prerequisites (courseCode and minimum grade required)
GradeScale (i.e. A-F, 1-100, pass/fail)
Web App #2 - Student catalog (handles students registering for new courses, seeing their transcript, etc)
Student
Transcript (what courses did they take and what final grade)
Data that needs to pass between the two systems (there will be more calls and stuff that needs to be handed back and forth, but this gives the idea that it's a 2-way flow of questions and answers):
Does a student have the pre-reqs needed to take a particular course?
Pulling details from the course catalog to create a full transcript
From reading, it seems our options are:
Create EJBs for the underlying data model, then have the web applications use the EJB interface.
Use a REST or Web Service interface between the two applications.
RMI or other Java remoting?
Which way would you cut this up into JARs/WARs/EARs?
This was initially a comment but it's actually too long.
If you got only simple imperative services (set this, do that, is this valid?), then you can go for an AXIS2/SOAP based web services solution. (you probably won't need the whole bloat of SpringWS). If the app logic is not too twisted, I'd follow KISS principle.
I don't know your system scenario, but if you're using a full fledge RDBMS, it's high probable that the database will reside on its own machine, thus having different pools connecting to it, is not much of a burden. (if you're using a local db on each AS, you're probably going to face some scalability problems later on).
In modern Java EE app servers you can actually use connection pools of one server from another (via jnp:// urls), it's just a matter of JNDI lookup.
If the db engine supports it, oracle alike db links are also a good way to share a database between apps.
You can spare code times by having a business/data layer in a simple java project with all the ORM stuffs, shared across the 2 web dinamic projects, so eventual changes in business logic will reflect onto both apps.
You can also tryout the mixed way (simple imperative Web Services and database share), it really depends on what messages are exchanged between the two applications. You can provide a layer of web services API (SOAP or jsonp based), but take into account execution time of the web service itself (it's not so good to have time consuming ws).
Web Services and EJB are good and probably can do what you need, the real question is: do you really need them ? lately I've seen lots of project starting with the full REST thing, and in many cases it was like killing flies with a bazooka.
If the requirements are simple, then keep it simple.
I do have many years of experience in large J2EE web applications and high transactional core java applications but never had any experience on SOA.
Currently I am working on a new project but the architecture was already done. We (Java developers) develop EJB services which finally sends JAXB based Java objects to C#.net clients to render the UI which is used only within the company 11000 users. The idea is that, there may be internet users around the world in the future and we will be developing an web application based on J2EE which will be using the same services.
Is this a truly a Service Oriented Architecture? Can SOA done in this way using JAXB bound Java objects which can be consumed from many platforms?
I have never done any SOA work so I want to get some terms correct. Thank you.
an architecture to be SOA has to stick to the below rules:
• SOA components are loosely coupled. When we say loosely coupled means every service is self contained and exist in alone logically. For instance we take the ‘payment gateway’ service and attach it to a different system.
• SOA services are black boxes. In SOA services hide there inner complexities. They only interact using messages and send services depending on those messages. By visualizing services as black boxes services become more loosely coupled.
• SOA service should be self defined: - SOA services should be able to define themselves.
• SOA Services are maintained in a listing: - SOA services are maintained in a central
repository. Applications can search the services in the central repository and use them accordingly.
• SOA components can be orchestrated and linked to achieve a particular functionality. SOA services can be used/orchestrated in a plug and play manner.
It does not matter what Technologies/language you are using as long you don't break any of the above rules
for more info:
http://www.codeproject.com/KB/aspnet/SoftArch7.aspx
All SOA means is that "external" components can consume functionality. Usually SOA refers to XML/RESTful interfaces, but that's just convention.
http://en.wikipedia.org/wiki/Service-oriented_architecture
SOA doesn't have anything to do with implementation details such as EJB or JAXB. SOA is all about creating loosely coupled, discreet services (usually web services). These services can then be run by any business logic layer to satisfy a business need.
You can then add a UI layer (say java Swing or SWT) onto the business logic layer to create a client application, similarly you could create a web-app. In each case you are using the same web services. This is SOA.
Is this a truly a Service Oriented Architecture?
SOA is a buzzword. You can also think about it as RBMDC => "Reusable By Many Different Clients" architecture
It has nothing to do with the actual data type (XML, JSON, binary, etc..) nor with the protocol (HTTP, TCP/IP, SOAP, etc..).
What it really boils down to is you have X "business functions" that you expose to be usable by external or internal clients. These business functions are technically labeled services, hence your architecture is Service Oriented.
What you describe in your example is what buzz architects call SOA => the answer is YES.
Yes. Thats exactly what SOA is. Ask yourself these questions:
Are you developing a layer which encapsulates business logic.. maybe interacts with a database while doing so?
Is that layer being designed in such a way that multiple views, or other layers can call on to obtain information?
If you are answer is yes, then thats SOA. You will have multiple clients -> calling on a gateway (may be your web server) -> which directs the request to your service. Then returns the data back.
Once you have developed the gateway then all you need to concentrate on is develop the services and some other module can consume it.
Its wonderful to have loose coupling isn't it?
I was in a project that did exactly what you are doing. C# SOA and Java EJBs at the backend.. :)