Let us assume application have 10+ Spring Boot micro service. Which is the best way of deploying in production environment for bellow two options?
Using embedded server per service run through the java -jar xyz.jar?
Using the external application server like (Jboss or Tomcat) service are running on their own ports
?
The recommended approach is using the 1st option because :
You can use any of the light weight servers i.e., undertow, etc...
You can dockerize it, scale up as needed.
Easy to maintain and save time and money.
The 2nd option has some limitations like :
You are not using spring boot self deploying feature.
Multiple applications can also be deployed due to which your application may be slower.
Generally 1 would be preferable if you are on modern infrastructure, however there is no "best way" to do deployments. Both approaches have trade offs:
Gives you better isolation and when implement with containers or PAAS allows for immutable deployments which is a big improvement when it comes to testing. The downside is more complicated deployment process that should be automated and higher server resource consumption.
Usually simplifies the architecture and is better suited for manual deployment process. If your organization doesn't buy in into Continuous Delivery this approach will be much easier to live with. The downside is that over time application servers on different environments (DEV, QAT, PROD) will usually end up with a different configuration setup making testing so much harder.
Related
We have just started a new project using Spring boot, which will have a monolithic architecture. There are some talks about using docker for containerizing the application.
Are there any benefits other than easier deployment across different platforms?
I would also like to understand whether auto scaling applies here. If yes, how?
Thanks in advance!
I just would like to add that lots of people tend to focus on the deployment, but the advantages for cyber security are enormous. The process isolation in the bounds of what could be seen as an advanced jail by itself could make the case for Docker.
Another advantage is the complement it provides for you CI/CD efforts and methodologies. By including the process of building imagens in the app building process, one gets better control of the overall process including a better view of the cycles.
Besides that, you also expand the number of ecosystems where you application can be easily installed and run. Added the support of a swarm or kubernets you got yourself access the the current hardened and managed could solutions.
With a stretch we can talk about scalability, if your image is meant to cooperate with replicas of itself, or if you put your containers were the hardware is itself elastic. Scalability also comes in to the discussion when you use means to control hardware usage in order to prevented services for competing for resources. This is also true if you do not have a cluster, as you can also manage hardware usage within a host.
Now it really depends on your needs and ninche. Some environments for instance would benefit in obvious ways even if scalability is not a concern. The inner networks you can create for instance is an excellent excuse to implement Docker, you get process isolation and network isolation inside a small host. Of course Docker is not meant to be a cybersec solution, but it adds up to the ones you already have.
I think it really depends on the scale of your application. The main benefit will certainly be ease of deployments and development, either on premise or on a cloud provider.
If you are running other applications along with Spring, like a database, cache server or other applications, you should have a look at docker-compose. It would really simplify not just the deployment of the Spring app, but also of all its dependencies.
Docker could help a lot also in case you plan to scale your application to multiple nodes, using docker swarm.
As for autoscaling, it is not really supported by docker out of the box, but you could achieve it with other tools on top of docker swarm.
We are developing microservice based application using Jhipster. For that, there are different components should run at the same time i.e, service registry, UAA server, Gateway, and other different services. To run all these components on my PC it consumes all the resources (16 GB of Ram). However, other developers, they don't have sufficient resources on their PC, which is the reason we are facing the problems continues development in the team.
So we are seeking some options for this problem to get efficiency over our development team.
Currently, if someone wants to add/change features on the application, he needs to work with both microservice and gateway(for the frontend).
So, in this case, what happen? suppose multiple developers are working on gateway and service at the same time in the development environment.
How are they going to debug/test? do they have to deploy gateway individually?
We are planning to deploy microservices on our own VPS server and in near future for the production heroku, kubernetes, jenkins, cloudfoundry can be used.
Correct me if I am wrong and is there any better option for smooth development?
I had read Sam Neuman's Microservice book that the problem of the single gateway based application while development.Now I am very curious about how Jhipster came to resolve this problem.
It seems to me that you are trying to work with your microservices as it was a monolith. One of the most important features in the microservice architecture is the ability to work on each microservice independently, which means that you do not need to run the whole infrastructure to develop a feature. Imagine a developer at Netflix who needs to run several hundreds of microservices on their PC to develop a feature - that would be crazy.
Microservices is all about ownership. Usually, different teams work on different microservices or some set of microservices which makes it really important to build good test design to make sure that whenever all the microservices are up and running as one cohesive system everything works as expected.
All that said, when you are developing your microservice you don't have to rely on other microservices. Instead, you better mock all the interactions with other microservices and write tests to check whether your microservice is doing what it has to do. I would suggest you wiremock as it has out-of-the-box support for Spring Boot. Another reason is that it is also supported by Spring Cloud Contract that enables you to use another powerful technique called Consumer Driven Contracts which makes it possible to make sure that contract between two microservices is not broken at any given time.
These are the integration tests (they run on a microservice level) and they have a very fast feedback because of the mocks, on the other hand, you can't guarantee that your application works fine after running all of them. That's why there should be another category of more coarse grained tests, aka end-to-end tests. These tests should be running against the whole application, meaning that all the infrastructure must be up and running and ready to serve your requests. This kind of tests is usually performed automatically by your CI, so you do not need all the microservices running on your PC. This is where you can check whether you API gateway works fine with other services.
So, ideally, your test design should follow the following test pyramid. The more coarse grained tests you have the less amount of them should be kept within the system. There is no silver bullet if to speak about proportions, rough numbers are:
Unit tests - 65%
Integration tests - 25%
End-to-end tests - 10%
P.S: Sorry for not answering your question directly, I had to use the analogy with tests to make it more clear. All I wanted to say is that in general, you don't need to take care of the whole system while developing. You need to take care of your particular microservice and mock out all the interactions with other services.
Developing using a shared gateway makes little sense as it means that you cannot use webpack dev server to hot reload your UI changes. Gateways and microservices can run without the registry just use local application properties and define static zuul routes. If your microservices are well defined, most developers will only need to run a small subset of them to develop new features or fix bugs.
The UAA server can be shared but alternatively you can create a security configuration simulating authentication that you would activate through a specific profile. This way when a developer works on one single web service, she can test it with a simple REST client like curl or swagger without having to worry about tokens.
Another possibility if you want to share the registry is to assign a spring profile per developer but it might be overkill compared to above approach.
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.
There seems to be a current trend in java space to move away from deploying java web applications to a java servlet container (or application server) in the form of a war file (or ear file) and instead package the application as an executable jar with an embedded servlet/HTTP server like jetty. And I mean this more so in the way newer frameworks are influencing how new applications are developed and deployed rather than how applications are delivered to end users (because, for example, I get why Jenkins uses an embedded container, very easy to grab and go). Examples of frameworks adopting the executable jar option:
Dropwizard, Spring Boot, and Play (well it doesn't run on a servlet container but the HTTP server is embedded).
My question is, coming from an environment where we have deployed our (up to this point mostly Struts2) applications to a single tomcat application server, what changes, best practices, or considerations need to be made if we plan on using an embedded container approach? Currently, we have about 10 homegrown applications running on a single tomcat server and for these smallish applications
the ability to share resources and be managed on one server is nice. Our applications are not intended to be distributed to end users to run within their environment. However, moving forward if we decide to leverage a newer java framework, should this approach change? Is the shift to executable jars spurred on by the increasing use of cloud deployments (e.g., Heroku)?
If you've had experience managing multiple applications in the Play style of deployment versus traditional war file deployment on a single application server, please share your insight.
An interesting question. This is just my view on the topic, so take everything with a grain of salt. I have occasionally deployed and managed applications using both servlet containers and embedded servers. I'm sure there are still many good reasons for using servlet containers but I will try to just focus on why they are less popular today.
Short version: Servlet containers are great to manage multiple applications on a single host but don't seem very useful to manage just one single application. With cloud environments, a single application per virtual machine seems preferable and more common. Modern frameworks want to be cloud compatible, therefore the shift to embedded servers.
So I think cloud services are the main reason for abandoning servlet containers. Just like servlet containers let you manage applications, cloud services let you manage virtual machines, instances, data storage and much more. This sounds more complicated, but with cloud environments, there has been a shift to single app machines. This means you can often treat the whole machine like it is the application. Each application runs on a machine with appropriate size. Cloud instances can pop up and vanish at any time which is great for scaling. If an application needs more resources, you create more instances.
Dedicated servers on the other hand usually are powerful but with a fixed size, so you run multiple applications on a single machine to maximize the use of resources. Managing dozens of application - each with their own configurations, web servers, routes and connections etc. - is not fun, so using a servlet container helps you to keep everything manageable and yourself sane. It is harder to scale though. Servlet containers in the cloud don't seem very useful. They would have to be set up for each tiny instance, without providing much value since they only manage a single application.
Also, clouds are cool and non-cloud stuff is boring (if we still believe the hype). Many frameworks try to be scalable by default, so that they can easily be deployed to the clouds. Embedded servers are fast to deploy and run so they seem like a reasonable solution. Servlet containers are usually still supported but require a more complicated set up.
Some other points:
The embedded server could be optimized for the framework or is better integrated with the frameworks tooling (like the play console for example).
Not all cloud environments come with customizable machine images. Instead of writing initialization scripts to download and set up servlet containers, using dedicated software for cloud application deployments is much simpler.
I have yet to find a Tomcat setup that doesn't greet you with a perm gen space error every few redeployments of your app. Taking a bit longer to (re-)start embedded servers is no problem when you can almost instantly switch between staging and production instances without any downtime.
As already mentioned in the question, it's very convenient for the end user to just run the application.
Embedded servers are portable and convenient for development. Today everything is rapid, prototypes and MVPs need to be created and delivered as fast as possible. No one wants to spend too much time setting up an environment for every developer.
I am trying to understand what does JBoss AS can bring into the project, comparing to standalone architecture?
My model application is a solid thing, starting, running and stopping as a whole and solely at the host.
It has a database storage, and communicates to user and other servers, clustering required.
It has web-part. It's just a standard big application.
JBoss for me is a shell for (in general) multiple applications, providing my application with some standard services. This shell is also a solid thing - "get all or nothing", something can be turned on/off (influencing your app unpredictably, or influencing other part of the JBoss) or replaced (very hard and is already kind a hack) with different version or other module.
Standalone application for me is something combined of pieces with glue among them (Spring if you like) with IoC wiring. We can get everything we could have with JBoss, but separately. Spring or other glue serves here like an application server, but it's thinner and we still can replace parts or even Spring itself (IoC wiring is straightforward from coding point of view).
For me, standalone, AS-free approach gives more control and flexibility. And further more, last versions of JBoss AS are purely documented, some features (most interested) are not documented at all.
So, why somebody still choose JBoss - what are benefits?
I favors more standalone application approach, but need more facts to understand better and convince others.
It seems to me that what you are describing is the classic choice between best-of-breed (collecting all the parts and glueing them together your self) versus integrated stack (JBoss wrote all the parts and integrated them for you). This is a debate that will rage on for eternity. If best-of-breed is working for you then stick with it.
JBoss is a J2EE container. Take a look at the J2EE spec if you are unfamiliar with it. Basically Sun's community process came up with an development framework that contains components that you may be interested in when creating large scale apps. J2EE contains multiple sub specs such as Servlets, EJB, JTA, JMS, and a whole host of other alphabet soup technologies. If you aren't using any of these technologies then you do not need a J2EE container. If you are just interested in using Servlets and JSPs then you are better off using a servlet container such as Tomcat, Jetty, Resin, etc.
Providing enterprise features such as scalability, transactional support, federated user management, etc. are difficult. A J2EE container provides a standard level of these features. If you can find them elsewhere to a level that meets your satisfaction then more power to you.
You can also pick and choose if you are running inside JBoss. If you are happy with the JBoss services you can use them or deploy some others if you don't like the one JBoss provides for you.
Starting from the JBoss minimal configuration and building up your own configuration should give you a setup where you don't have services running that you don't need. Personally, I like to know what my AS is running, so I prefer to start from minimal configuration adding only the necessary parts.
I would say the only reason to use JBoss is if you need to access the Java EE services (like Messaging, container-managed transactions and similar).
Keep in mind JBoss is (roughly described) Tomcat plus Java EE services (yes, yes, I know, this is a very simplified approach, just bear with me). I mention this as I would say your decision is:
If you only need IoC and some other capabilites you can get with Spring and Tomcat, go with that
If you application requires Java EE services, use JBoss
Keep in mind you can always start with the basic system (Spring + Tomcat) and move to JBoss if required later on. Nothing forbids that.And probably starting with that approach will show you if you really need the Java EE services or you were over-engineering the solution.