I have a question to ask. Some time ago I was working on a project as a junior Java developer. It was a Java Enterprise Web App which uses Spring and Hibernate frameworks. I didn't completely understand the architecture of the project and I had only a small contribution to the project. But it was a multi module maven project and each module was built and deployed as a WAR file separately in the Oracle Web logic 12c. They didn't use docker and I don't know how the modules interact with each other (it might be REST or something). My question is: can we consider this type of multi module maven project that each module is deployed separately a microservice architecture?
Also, could you please inform me about a good book to start learning microservice architecture in Java?
Yes. Not using docker (or any other containers) does not necessarily mean that the architecture is not a micro-services based one. It can perfectly be as you are describing: multiple "WARs" (modules) communicating through REST APIs or gRPC or similar.
I agree, this is certainly microservice architecture, as a single overall application is broken out into seperate running instanes. Spring makes it very easy for separate microservices to communicate with each other via REST APIs, Eureka and Feign Clients. Idk about a book on microservices, but a simple project is always a good way to learn. Those might not sound meaningful to you but i recommend finding a simple eureka feign client tutorial online, and doing your own version of it. I did that and was able to deploy the same spring service to both my laptop and a pi, call these microservices repeatedly from another microservice on my laptop (the method i was calling just returned the environment hostname) and see that eureka was passing the call to each one in turn, giving me alertnating results. This demonstrates how easy you can horizontally scale using this architecture (i.e. if i need more power i can just keep deploying new instances of that getHostname microservice and no matter what device they are on eureka can link them up)
It is difficult to say about architecture style with given information.
Docker or without docker is not a constraint for microservice architecture style.
If you want to study microservice in Java than I suggest that you may refer to "Microservice Patterns - Chris Richardson".
I have been testing out microservices lately using springboot to create microservice projects. The more i understand about the setup the more questions i am confronted with.
How are all the microservices that are running, managed? How do developers manage, deploy or update microservices via a central location?
When deploying multiple instances of a microservice, do you leave the port to be decided during runtime, or should it be predefined?
I am sure there will be much more questions popping up later.
Links used:
http://www.springboottutorial.com/creating-microservices-with-spring-boot-part-1-getting-started
https://fernandoabcampos.wordpress.com/2016/02/04/microservice-architecture-step-by-step-tutorial/
Thanks in advance.
Microservices do tend to go out of control sooner than later. With so many services floating around, you need to think of deployment and monitoring strategies ahead of time.
Both of these are not an easy problem, but you have quite a few tools available at your disposal.
Start with CI/CD. Search around it and you will find a way around. One option is to make use of Jenkins for Blue/Green deployments
In this case jenkins will be one central place where you manage your deployments (but this is just an example, we do have quite a lot of tools build around this that may help you better based on your needs)
Other part of this problem lies in when where you tend to deploy stuff? Different cloud providers have their own specific ways of handling microservices and it depends on your host really. But one alternative is to make use containers.
If you go with raw containers like dockers directly you will have to take care of mapping ports (if they are deployed on same host machine) but then you can use abstraction on top of this like if you are on AWS then you can consider ECS or docker swarms or I personally prefer Kubernetes. You do not need to worry about the ports on which they are and can directly talk to your service over a load balancer. There is lot that is missing in here and you really need to pick one such tool and dig deep, but there are options out there for you to explore.
Next is monitoring, if you are going with kubernetes, you do get lot of monitoring tools out of the box that will help you access the service logs query them etc. But you also need to make sure that from development perspective you do provide for correlations id's, api metrics, response times, because you will need them to debug issues when its comes to microservices specially one related with latencies. If you are not on kubernetes you can still get all these features added but individually, like ELK stack for log monitoring (as you do not want to go to each service to check for logs), zipkin for tracking , API gateway and loadbalancers for service discovery and talking to containers.
Hope this helps you get started.
you can start with the following:
Monitoring :
Start with spring-boot-admin and prometheus.
https://github.com/codecentric/spring-boot-admin
Deployment:
Start with docker and docker-compose and move to kubernetes.
Few examples for docker compose:
https://github.com/jinternals/spring-cloud-stream
https://github.com/jinternals/spring-micrometer-demo
There are container services/container management systems available for example Amazon ECS, Azure container services, Kubernetes etc which take care of automated deployment by centralised repositories like Amazon ECR etc, automated scale up/down of microservice instances, take advantage of dynamic port allocations to run multiple instance of same service on a single instance/host and also give you a centralised dashboard to monitor resource usage and infrastructure events.
You can make use of any one to get answers to all of your questions as all of them provide most of the functionalities needed for managing your microservices.
I just started in a new team. My task right now is to bring an old application to their new microservice framework (mostly Java). It runs in quite a complex environment, like consuming other web services, messaging via several queues, and providing an public API for other services to use.
The new thing for me is that their development process doesn't involve an actually running the application even once. Instead they solely do testing: unit tests and integration tests. For the integration tests they employ a couple of docker container that mimic their actual production system. There is no staging system - only the production system, where I have no access.
To me it feels weird to never actually run the application. Is this common? Have you guys encountered the same? Is this considered a good practice?
Edit: For the system it is not critical that it runs 24/7 without interruption. An outage after a new deployment is not nice but if monitored and handled (e.g. switch back to an older version) it's not a big problem.
We have a quite large monolithic app (java/spring) and we are considering splitting it up to microservices and using spring-cloud to utilize existing solution for some common problems (discovery, redundancy etc.). Currently we run one instance (with different modules) per client.
Some of our clients are small and one VPS handles it and others are larger and might use multiple servers.
The problem is that this "pack" of microservices should be isolated for each environment - they might be slightly different.
As I am reading through resources about Cloud Foundry - which looks really great - it seems that it would be best to run an cloud foundry instance per client and I am afraid that that is overkill and quite a lot of work to get one client running (which I would like to automate as much as possible).
Ideal Solution
BEGIN
We provide servers with heterogenous OS, possible containers (VM/docker/jail/...) with restrictions where they may rur and finally services with restrictions in which containers they may run.
When creating new environment I just provide list of services to run in it and the Solution creates containers, deploys services in them and sets up communication channels (message broker) between them.
It should also handle upgrades, monitoring, etc.
END
What approach would you recommend? Or please could you share your experience from building similar thing?
Thanks
You could provide each customer with their own space in a single CF instance where all the microservices are deployed.
I'm reading some documentation about the micro-services architecture (through this link for example) and I was wondering what is exactly a service in this case.
In IT, everything could be called a service:
- a SPRING REST application launched through the java command like:
java -jar build/libs/gs-rest-service-0.1.0.jar
It could also be a classes corresponding to the business layer in a DDD
It could be simply something related to the domain studied, like providing something to somebody
and many others... (android background running services etc...)
But in microservices, what does it mean? And what kind of technologies / tools are used to create a "service running by himself" in the Java EE stack for example? It's only related to webservices?
Exactly, that's the beauty of microservices model! You can start thinking about microservices when you design your maven multi-module project, for example. Low coupling, clear separation of concerns, may be even asynchronous communication. When you feel more confident you extract them in into apps and run in a one host, next step - run in different hosts. It's up to you to decide how exactly they should be deployed, it's related to goals you want to achieve (fault-tolerance vs low latency, etc.) and DevOps resources you have (because more separation you have more maintenance you need).
Regarding Java EE stack - nothing specific, just usual jar or war file running using java -jar or application servers like Tomcat.
Another direction is to use tools like Docker + CoreOs / kubernetes / ..., Mesos + Marathon, etc., but they are suitable for any languages / frameworks in microservices.
Edit:
Microservices can use a combination of synchronous (REST, SOAP) and asynchronous protocols (messaging queues like ActiveMQ, RabbitMQ, etc). It's up to you to decide how to combine them. My example: labs.bench.co/2014/12/10/microservices-at-bench-intro
Previous answers are great.
Microservices architecture is just a functional decomposition design.
I suggest you to read this blog post : Microservice Design Patterns
From a technical point of view, there is a a lot of tools like Docker (to run each microservice as a linux container) and Kubernetes to orchestrate them as a service (here is a Kubernetes sample).
My own definition:
A microservice is a stand-alone, decoupled component that handles a single business concern, and is consumable from other services.
Others might agree or disagree, and there is a lot of interesting discussion on this topic that make it a great study point for software engineers.
From a technical standpoint:
You can create microservices in almost any technology: Java EE, Java + Spring, Python, Rails, Grails, Node.js and so forth. From what I have seen, it seems most commonly applied in the domain of web apps and back-end service-oriented ecosystems. In the article you reference, the NetFlix model is a very interesting thing to study, because you can see all the elements of a microservice architecture in depth: service discovery, circuit-breaking, monitoring, dynamic configuration, and so on.
Some things you might want to check out, if you are Java-oriented:
Spring Cloud allows you to use some of these same NetFlix components with a minimum of hand-coding: http://cloud.spring.io/spring-cloud-netflix/
An actual operational example on github (not mine, but I have used it in my own learning on the topic): https://github.com/ewolff/microservice
From a conceptual point of view, your question hints at a notorious microservice design dilemma. There is not necessarily a "correct" level of granularity for a microservice. The idea is to choose a level of granularity that has meaning within your business domain. If you implement microservices at a very low level of granularity, (e.g. the CRUD level), then you will almost certainly end up with very chatty services and you will probably have to build more meaningful composite services over top. If you choose too high a level of granularity, you could end up with a more monolithic application which may require refactoring into microservice-sized pieces later.
I would start with Your last question - It's only related to webservices?
That's debatable. I would say, NO. It's related to webservice (but not only to it.)
Martin fowler describes microservices as a small subset of SOA, after all microservices are services, and SOA is a very generic and broad term.
Below are some of the important aspects of Microservices:
Each service (or a set of few) should have it's own data store.
Services are organized around the business needs or functionality.
Each service is independent so they can be implemented in any language. Leads to polyglot programming culture in team.
Service can take request from client or from other services as well.
They are usually event driven and asynchronous so scaling becomes easier.
Services are dumb as they only do one thing (but they should be self sufficient to monitor themselves)
They can be helpful in continuous deployment or delivery as implement to deploy cycle is really small.
They are very small so there is not much of network overhead in deploying them. So they can be deployed across a cluster of nodes in few minutes.
Also, I want to stress that, above are NOT only true about microservices. Companies like google, netflix, and Amazon have been doing similar thing even before the term was coined.
Service to microservice is Java is to JavaScript. Don't think about it that way. Instead microservice can be thought of as the following:
A small problem domain.
Built and deployed by itself.
Runs in its own process.
Integrates via well-known interfaces.
Owns its own data storage.
A Microservice is basically a self contained process that provides a unique and single business capability. We don't create web Microservice, business logic Microservice, or datebase Microservice.
Why Microservice?
Microservice make our system loosely coupled, i.e. if we need to update, repair, or replace a Microservice, we don't need to rebuild our entire application, just swap out the part that needs it.
To built each Microservice can use different languages and tools. Microservices communicate with well defined interface
The communication should be stateless for scalability(copies of Microservice) and reliability(one copy fail other copy can serve), the most common methods for communication between Microservices are HTTP and messaging.
Each Microservice should have it's own datastore.
Small team capable to work on design, web development, coding, database admin and operations.
source
Microservices is a software architectural style that require functional decomposition of an application.
Usually, it involves a monolithic application is broken down into multiple smaller services, each deployed in its own archive, and then composed as a single application using standard lightweight communication, such as REST over HTTP or some async communication (of course, at some point micro services are written from scratch).
The term “micro” in microservices is no indication of the line of code in the service, it only indicates the scope is limited to a single functionality.
Each service is fully autonomous and full-stack. Thus changing a service implementation has no impact to other services as they communicate using well-defined interfaces. There are several advantages of such an application, but its not a free lunch and requires a significant effort in NoOps.
It's important to focus on that that each service must have the properties of:
Single purpose — each service should focus on one single purpose and do it well.
Loose coupling — services know little about each other. A change to one service should not require changing the others. Communication between services should happen only through public service interfaces.
High cohesion — each service encapsulates all related behaviors and data together. If we need to build a new feature, all the changes should be localized to just one single service.