04 Spring Microservices Material
04 Spring Microservices Material
04 Spring Microservices Material
To understand the design differences between monolithic and µServices, let's take
an example of a restaurant table-booking application. This app may have many
services such as customers, bookings, analytic and so on, as well as regular
components such as presentation and database.
The following diagram depicts the monolithic application with different services;
here services are being used with a presentation component. All services, the
presentation component, or any other components are bundled together:
MicroServices Design:
The following third design depicts the µServices. Here, each component represents
autonomy. Each component could be developed, built, tested, and deployed
independently. Here, even the application UI component could also be a client and
consume the µServices. For the purpose of our example, the layer designed is used
within µService.
The API gateway provides the interface where different clients can access the
individual services and solve the following problems:
What to do when you want to send different responses to different clients for
the same service. For example, a booking service could send different
responses to a mobile client (minimal information) and a desktop client
(detailed information) providing different details and something different again
to a third-party client.
Similarly, in the second design figure, we can see a variant of the first figure where
all services could have their own layers and form different APIs, but, as shown in
the figure, these are also all bundled together.
But In µServices, design components are not bundles together and have loose
coupling. Each service has its own layers and DB and is bundled in a separate
archive. All these deployed services provide their specific API such as Customers,
Bookings, or Customer which are ready to consume. Even the UI is also deployed
separately and designed using µService. For this reason, it provides various
advantages over its monolithic design. But It would also be noted that there are
some exceptional cases where monolithic app development is highly successful,
like peer-to-peer e-commerce web applications.
MicroServices:
Evolution Of MicroServices
Many organizations such as Netflix, Amazon, and eBay successfully used the
divide-and-conquer technique to functionally partition their monolithic applications
into smaller atomic units, each performing a single function. These organizations
solved a number of issues they were experiencing with their monolithic
applications. Following the success of these organizations, many other
organizations started adopting this as a common pattern to re factor their
monolithic applications. Later, evangelists termed this pattern as the
MicroServices architecture.
In most cases, layers are physically spreadable, whereas modules within a layer
are hardwired.
As we can note in the preceding diagram, the boundaries are inversed in the
MicroServices architecture. Each vertical slice represents a micro service.
Each microservice has its own presentation layer, business layer, and
database layer. By doing so, changes to one micro service do not impact others.
By adding new cells, the honeycomb grows organically to a big, solid structure.
The content inside each cell is abstracted and not visible outside. Damage
to one cell does not damage other cells, and bees can reconstruct these cells
without impacting the overall honeycomb.
Principles of MicroServices
Source:
http://c2.com/cgi/wiki?PrinciplesOfObjectOrientedDesign
This implies that a unit, either a class, a function, or a service, should have only
one responsibility. At no point should two units share one responsibility or one unit
have more than one responsibility. A unit with more than one responsibility
indicates tight coupling.
As shown in the preceding diagram, Customer, Product, and Order are different
functions of an e- commerce application. Rather than building all of them into one
application, it is better to have three different services, each responsible for
exactly one business function, so that changes to one responsibility will not
impair others.
In the preceding scenario, Customer, Product, and Order will be treated as three
independent MicroServices.
Principle-2: Autonomous
Characteristics Of MicroServices:
In the MicroServices world, services are first-class citizens. Micro services expose
service endpoints as APIs and abstract all their realization details. The internal
implementation logic, architecture, and technologies (including programming
language, database, quality of services mechanisms, and so on) are completely
hidden behind the service API.
Different architectures are used, such as one microservice using the Redis
cache to serve data, while another microservice could use MySQL as a
persistent data store.
At the same time, Hotel Booking needs more ACID transactional characteristics.
Therefore, it is implemented using MySQL and Java.
In these two micro services, the internal implementations are hidden behind
service endpoints defined as REST/JSON over HTTP as MicroServices First Class
Citizens.
The development phase is automated using version control tools such as Git
together with Continuous Integration (CI) tools such as Jenkins, Travis CI, and
so on. Automation of a full build on every code check-in is also achievable with
microservices.
The testing phase will be automated using testing tools such as Selenium,
Cucumber, and other AB testing strategies.As microservices are aligned to
business capabilities, the number of test cases to automate is fewer compared
to monolithic applications, hence regression testing on every build also
becomes possible. As microservices are aligned to business capabilities, the
number of test cases to automate is fewer compared to monolithic applications,
hence regression testing on every build also becomes possible.
The core difference between SOA and MicroServices lies in the size and scope. As
the word "micro" suggests, it has to be significantly smaller than what SOA tends
to be. Microservice is a small(er) independently deployable unit. A SOA can be
either a monolith or it can be comprised of multiple MicroServices. Martin Fowler
says he likes to think SOA to be a superset of MicroServices.
SOA initially started with SOAP, Micro Service architecture uses REST
XML/WSDL API.
In SOA, services share the data storage Each service can have an independent
data storage
Microservices examples
Fly By Points collects points that are accumulated when a customer books a hotel,
flight, or car through the online website. When the customer logs in to the Fly By
Points website, he/she is able to see the points accumulated, personalized offers
that can be availed of by redeeming the points, and upcoming trips if any.
Let's assume that the preceding page is the home page after login. There are two
upcoming trips for Jeo, four personalized offers, and 21,123 loyalty points. When
the user clicks on each of the boxes, the details are queried and displayed.
Note:
1. When the web page is loaded, all the three boxes, Trips, Offers, and Points will
be displayed with details such as points, the number of offers, and the number
of trips.
2. This will be done by each box independently making asynchronous calls to the
respective backend microservices using REST.
3. There is no dependency between the services at the service layer. When the
user clicks on any of the boxes, the screen will be transitioned and will load the
details of the item clicked on. This will be done by making another call to the
respective microservice.
As per this each microservice should have its own code base, and this code base is
not shared with any other microservice. It also means that one microservice has
exactly one code base.
2) Bundling dependencies
Each microservice should bundle all the required dependencies and execution
libraries such as the HTTP listener and so on in the final executable bundle.
3) Externalizing configurations
All services need to talk to some external resources during the life cycle of their
execution. For example, they could be listening or sending messages to a
messaging system, sending an e-mail, persisting data to database, and so on. All
these services should be reachable through a URL without complex communication
requirements.
In the MicroServices world, MicroServices either talk to a messaging system to
send or receive messages, or they could accept or send messages to other service
APIs. In a regular case, these are either HTTP endpoints using REST and JSON or
TCP- or HTTP-based messaging endpoints.
5) Externalizing logs
In development, the microservice may direct the log stream to stdout, whereas in
production, these streams will be captured by the log shippers and sent to a
central log service for storage and analysis.
This principle suggests that processes should be stateless and share nothing. All
MicroServices should be designed as stateless functions. If there is any
requirement to store a state, it should be done with a backing database or in an in-
memory cache.
Not only is this principle valid for MicroServices, but it is also applicable to any
application development.
Apart from application services, most applications provide admin tasks as well.
This principle advises to use the same release bundle as well as an identical
environment for both application services and admin tasks. Admin code should also
be packaged along with the application code.
Not only is this principle valid for microservices, but also it is applicable to any
application development.
This principle advocates a strong isolation between the build, release, and run
stages.
The build stage: refers to compiling and producing binaries by including all the
assets required. The release stage: refers to combining binaries with
environment-specific configuration parameters.
The run stage: refers to running application on a specific execution environment.
In MicroServices, the build will create executable JAR files, including the service
run time such as an HTTP listener. During the release phase, these executa
ble will be combined with release configurations such as production URLs and so
on and create a release version, most probably as a container similar to Docker. In
the run stage, these containers will be deployed on production via a container
scheduler.
Step-1: Configure the application with server port and database configurations as
shown below:
As we are using Hibernate4 to perform the crud with database, we were also have
been configured the hibernate related properties.
This approach has the advantage as n case of an error at any stage, the error will
be propagated back to the caller immediately, leaving the system in a consistent
state.
It is not possible to develop a system with just one approach. A combination of both
approaches is required based on the use cases. In principle, the asynchronous
approach is great for building true, scalable microservice systems. However,
attempting to model everything as asynchronous leads to complex system designs.
This is perhaps a simple query to the backend system to get a result in a request-
response model. This can also be modeled in an asynchronous style by pushing a
message to an input queue, and waiting for a response in an output queue till a
response is received for the given correlation ID. However, though we use
asynchronous messaging, the user is still blocked for the entire duration of the
query.
In the preceding diagram, both Product and Order microservices share one
database and one data model. Shared data models, shared schema, and shared
tables are recipes for disasters when developing microservices. This may be good
at the beginning, but when developing complex microservices, we tend to add
relationships between data models, add join queries, and so on. This can result in
tightly coupled physical data models.
If the services have only a few tables, it may not be worth investing a full instance
of a database like an Oracle database instance. In such cases, a schema level
segregation is good enough to start with:
User interfaces in microservices