We have a couple of custom portlet applications running inside Liferay Portal.
The solution is installed on client’s computer which is entry-level (RAM <= 1 Giga). Due to red tape, it is rather unlikely the client switches to higher-end computers in the short term.
The issue is that the applications are very slow.
What are the hints to optimize Liferay configuration (or optimize the portlet application) so we are able to run decently on entry-level computers?
Or is it a good move to switch the portlets to lighter Portlets Containers alternatives such as Apache Pluto or GateIn?
Or running a portal like Liferay on entry-level computers is not an option? And we should consider porting the existing portlets to separate standard Java Web Applications so to achieve better performance?
Compare the price of tuning, minimizing the footprint and measuring the result to the price of just 1 more Gigabyte of RAM - which you might not even be able to purchase in this size any more.
Then compare the price for porting from a portal environment into Java Web Applications: You can't even be sure that this will result in a lower footprint, as you'll have to redo quite a bit of functionality that Liferay provides out of the box. Identity Management for example. Content Management as another one. This will take time (equaling money) that might be better spent with just a new server.
For ~40€/month you can get a hosted server, including network connectivity, power and even support, that is way more capable of serving an application like this than a server the size of a Raspberry Pi (<40€ total, I've seen Raspberry Pi hosting for less than 40€ per year).
I don't know what you mean with "Red Tape", but I'd say you're definitely going for the wrong target. While there is a point to tune Liferay, I'd not go for this kind of optimization.
You're not mentioning the version you're using - with that hardware I'm assuming that it's an ancient version. Back before the current version, Liferay was largely monolithic. While you can configure quite a bit (cache, deactivate some functionality) they'll not bring drastic advantages. The current version has been modularized and you can remove components that you don't use, lowering the footprint - however, it's not been built for that size of infrastructure.
And when you're running the portal on that kind of hardware, you're not running the database and an extra webserver on the same box as well, right? This would be the first thing to change: Minimize everything that's running outside of Liferay on the same OS/Box.
Related
So, I'm very new to Docker. Let me explain the context to the question.
I have 10 - 20 Spring Boot micro-service applications, each running on different ports on my local machine.
But for migrating to Docker, based on my learning, each of the services must be in a different Docker container so as to quickly deploy or make copies.
For each Docker container, we need to create a new Docker image.
Each Docker image must contain a JRE for the Spring Boot application to run. It is around 200 MB maximum. That means each docker image is, say 350 MB at the maximum.
On the other hand, on my local PC I have only one JRE of 200 MB and each application takes only a few MB of space.
Based on this, I would need 600 MB on my local system, yet need 7 GB for all Docker images.
Is this approach correct? Should "OpenJDK" from DockerHub be added to each image?
Why is the size of the image large even if the target PC may already have the JDK?
Your understanding is not correct.
Docker images are formed with layers; see next diagram:
When you install a JRE in your image, let's suppose its checksum is 91e54dfb1179 in the next picture, it will occupy your disk really.
But, if all your containers are then all based on the same image, and add different things, says, your different microservice application to the thin R/W layer, all containers will share the 91e54dfb1179, so it will not be the n*m relationship.
You need to pay attention to using the same base image for all Java applications as much as possible, and add different things to the thin R/W layer.
The other answers cover Docker layering pretty well, so I just want to add details for you questions
Is this approach correct? Should "OpenJDK" from DockerHub be added to each image?
Yes. If it's not in the image, it won't be in the container. You can save disk space though by reusing as many Layers as possible. So try to write your Dockerfile from "Least likely to change" to "Most likely to change". So when you build your image, the more often you see "Using cache", the better.
Why is the size of the image large even if the target PC may already have the JDK?
Docker wants as little to do with the host as possible. Docker doesn't even want to deal with the host. The first thing it does is create a VM to hide in. Docker images assume the only thing the host will give is empty ram, disk, and CPUs. So each Docker image must also contain it's own OS/kernel. (That is what your initial FROM is doing, picking a base OS image to use) So your final image size is actually OS + tools + app. Image size is a little misleading though, as it is the sum of all layers, which are reused across images.
(Implied) Should each app/micro-service be in its own container?
Ideally, yes. By converting your app into an isolated module, it makes it easier to replace/load-balance that module.
In practice, maybe not (for you). Spring Boot is not a light framework. In fact, it is a framework for module-izing your code (Effectively running a module control system inside a module control system). And now you want to host 10-20 of them? That is probably not going to be able to run on a single server. Docker will force Spring boot to load itself into memory per app; and objects can't be reused across modules now, so those need to be multi-instantiated too! And if you are restricted to 1 production server, horizontal scaling isn't an option. (You will need ~1GB of HEAP (RAM) per Spring Boot, mileage my very based on your code base). And with 10-20 apps, refactoring to make the app lighter for Docker deployment may not be feasible/in-budget. Not to mention, if you can't run a minimal setup locally for testing (insufficient RAM), development effort will get a lot more "fun".
Docker is not a golden hammer. Give it a try, evaluate the pros and cons yourself, and decide if the pros are worth the cons for you and your team(s).
Lagom's answer is great, but I'd like to add that the size of Docker containers should be as small as reasonably possible to ease transfer and storage.
Hence, there are a lot of containers based on the Alpine Linux distribution, which are really small. Try to use them if possible.
Furthermore, do not add every tool imaginable to your container, e.g. you can often do without wget...
Based on this, I would need 600 MB on my local system, yet need 7 GB
for all Docker images.
Is this approach correct? Should "OpenJDK" from DockerHub be added to
each image?
That is correct. While you could wonder if a JRE is not enough.
Why is the size of the image large even if the target PC may already
have the JDK?
You compare things that are not comparable : local environment(that is all but a production machine) VS integration/production environments.
In integration/production environment, the load of your applications may be high and the isolation between applications is generally advised. So here, you want to host a minimal number of application (ui/services) by machine (bare, VM or container) to prevent side effects between application : shared libraries incompatibility, software upgrade side effects, resource starving, chained failures between applications...
While in local environment, the load of your applications is quite low and the isolation between applications is generally not a serious issue. So here you can host multiple applications (ui/services) on your local machine and you can also share some common libraries/dependencies provided by the OS.
While you can do that, is really a good practice to mix and share everything in local ?
I don't think because :
1) the local machine is not a bin : you work on that the whole day. More that is clean more you development is efficient. For example : JDK/JRE may differ between applications hosted in local, some folders used by the application may have the same location, the database version may differ, applications can have different installed java server (Tomcat, Netty, Weblogic) and or with different versions...
Thanks to container, that is not an issue : all is installed and removed according to your requirements.
2) environments (from local to prod) should as close as possible to ease the whole integration-deployment chain and to detect issues early and not only in production.
As a side note, to achieve that in local you need a real machine for developer.
All has a cost but actually that is not expensive
Besides isolation (hardware and software resources), containers bring other advantages as fast deploy/undeploy, scalability and failover friendly (for example : Kubernetes relies on container).
Isolation, fastness, scalability and robustness friendly have a cost: to not share physically any resource between containers (OS, libraries, JVM, ...).
That means that even if you use the exact OS, libraries, JVM in your applications, each application will have to include them in their image.
Is it expensive ?
Not really : official images relies often on Alpine (light Linux OS with limitations but customizable if needed) and what represent a image of 350 MB (value that you quote is that is in the reality) in terms of cost ?
In fact, that is really cheap.
In integration/production, all your services will very probably not been hosted on the same machine, so compare the 350 MB for a container to resources used in traditional VMs for integration/production that contain a complete OS with multiple additional programs installed on. You understand that the resource consumption of containers is not issue. That is even considered as an advantage beyond local environments.
I am working on an enterprise application which earlier used MyEclipse tool for Java / Java EE development, EJB 2.1 and WAS 7.0, recently we migrated to EJB 3.1, Websphere 8.5.5 and Eclipse Kepler. Now, we have noticed the performance of the application has increased and the screens load faster.
Now the problem that I am facing is to compare the earlier application with the one we've upgraded to and identify those areas which has led to speed up of the application. There are no performance metrics recorded for this application till date so I don't have anything to compare with.
All I am thinking was to have the Pre-Upgraded application deployed on a box and the Post-Upgrade application on the other box and record the time of load of all the screens. Now, this is not as subtle as being thought, so would like to know from you guys if there are any tools or strategies to compare two working applications and give performance metrics based on EJB methods time, JSP load time, Business Logic time, Database operations which gives true benefit analysis of the upgrade.
Also, do you guys think upgrade of application server and Integrated Development Environment (Eclipse Kepler) might have contributed to this speed?
If you still have both environments (WAS 7 and WAS 8.5.5) and some load scripts, I'd suggest to use PMI (Performance monitoring infrastructure) in WAS. You can enable metrics that interests you, set data to be saved to the log and run tests on both environments. Then you will be able to see gathered metrics for both environments.
The other option could be free WebSphere Application Server Performance Tuning Toolkit, which can be used to gather the performance data. Available either as standalone (older version) or as plugin to IBM Support Assistant (ISA).
Could upgrade of application server and Integrated
Developement Environment (Eclipse Kepler) might have contributed to
this speed?
Sure. The WAS 8.5.5 is in general faster than v7.0. For example it by default is using genCon garbage collection policy, which in most cases is more efficient that optthroughput.
The dev environment has no impact on application runtime performance, but maybe it is more responsive during development and thats why you have the 'faster' feeling.
I think what you need is benchmarking of both the versions of application and then compare both to see improvement.
for comparing both versions follow below approach,
Deploy both versions on exactly similar hw to create difference instance of 2 versions
Identify workflows/scenarios in which you found improvement and scenarios which are important for your application(mostly used/heavy/important for client etc.)
Carry out performance test/load test on those scenarios on both versions
Measure response time for all pages as well as system metrics i.e. cpu,memory,paging,disk etc.
Based on both versions results, carry out analysis and compare the both the versions.
If required carry out performance tuning and optimization round to improve the results.
This was about strategy.
For tools,
Check Ganglia,munin,graphite,carbon,sar,perfmon,nmon for system metrics (if its a cluster then RRD tools like ganglia,munin are better and if its a single box instance then sar for linux will do and on windows perfmon will do.)
For Load testing, JMeter is better option but you have quite enough funding then go for loadrunner,neoload,rational performance tester and for cloud, try blazemeter
For J2EE level analysis, IBM health center is available (according to me very inefficient to use), JProfiler, yourkit, jvisualvm are available
For WAS, Performance Monitoring Infra. is available with standard options it has low overhead but if you increase the logging counters and levels and it has huge performance impact.
I hope things are clear now :)
We are implementing a bespoke 3rd party J2EE application on a 6 server weblogic cluster (latest versions of Oracle products - running on SuSE). The supplier is suggesting to me that we schedule a restart of each WebLogic instance every week on a Monday morning at 3am.
I'm no weblogic expert and I can't seem to track down any best practice guidelines on the subject of regular restarts, but I'm used to working in environments where other clustered app server instances have uptime is measured in much longer periods than 7 days...
My concern is that this is intended to mask issues in the J2EE app itself. Can anyone point me towards best practice guidance related to Weblogic which I may have missed, or confirm that this may be a legitimate suggestion from the application vendor?
We don't always get perfect codes, no-wrong applications, and best programmers to work with you, in fact, many codes are written by junior programmers with low cost. So it is reasonable there are some bugs in these J2EE applications (depend on OS patch level, java version, application itself, etc). Memory leak is one of the problem to ask regular restart to avoid the applications go down at business time. Some other problems are hide in and can't be easily found out.
That's the reason to recommend to restart the application fortnight, weekly, or daily (I DO see some business java application restart every night).
If you really want to troubleshooting the application, maybe you can install some APM (application performance management) application to help you to find out why the application have memory leak, unstable behavior, etc.
You can search in google or read this URL for a starting : http://en.wikipedia.org/wiki/Application_performance_management
I want to gain more insight regarding the scale of workload a single-server Java Web application deployed to a single Tomcat instance can handle. In particular, let's pretend that I am developing a Wiki application that has a similar usage pattern like Wikipedia. How many simultaneous requests can my server handle reliably before going out of memory or show signs of excess stress if I deploy it on a machine with the following configuration:
4-Core high-end Intel Xeon CPU
8GB RAM
2 HDDs in RAID-1 (No SSDs, no PCIe based Solid State storages)
RedHat or Centos Linux (64-bit)
Java 6 (64-bit)
MySQL 5.1 / InnoDB
Also let's assume that the MySQL DB is installed on the same machine as Tomcat and that all the Wiki data are stored inside the DB. Furthermore, let's pretend that the Java application is built on top of the following stack:
SpringMVC for the front-end
Hibernate/JPA for persistence
Spring for DI and Security, etc.
If you haven't used the exact configuration but have experience in evaluating the scalability of a similar architecture, I would be very interested in hearing about that as well.
Thanks in advance.
EDIT: I think I have not articulated my question properly. I mark the answer with the most up votes as the best answer and I'll rewrite my question in the community wiki area. In short, I just wanted to learn about your experiences on the scale of workload your Java application has been able to handle on one physical server as well as some description regarding the type and architecture of the application itself.
You will need to use group of tools :
Loadtesting Tool - JMeter can be used.
Monitoring Tool - This tool will be used to monitor various numbers of resources load. There are Lot paid as well as free ones. Jprofiler,visualvm,etc
Collection and reporting tool. (Not used any tool)
With above tools you can find optimal value. I would approach it in following way.
will get to know what should be ratio of pages being accessed. What are background processes and their frequency.
Configure my JMeter accordingly (for ratios) , and monitor performance for load applied ( time to serve page ...can be done in JMeter), monitor other resources using Monitor tool. Also check count of error ratio. (NOTE: you need to decide upon what error ratio is not acceptable.)
Keep increasing Load step by step and keep writting various numbers of interest till server fails completely.
You can decide upon optimal value based on many criterias, Low error rate, Max serving time etc.
JMeter supports lot of ways to apply load.
To be honest, it's almost impossible to say. There's probably about 3 ways (of the top of my head to build such a system) and each would have fairly different performance characteristics. You best bet is to build and test.
Firstly try to get some idea of what the estimated volumes you'll have and the latency constraints that you'll need to meet.
Come up with a basic architecture and implement a thin slice end to end through the system (ideally the most common use case). Use a load testing tool like (Grinder or Apache JMeter) to inject load and start measuring the performance. If the performance is acceptable - be conservative your simple implementation will likely include less functionality and be faster than the full system - continue building the system and testing to make sure you don't introduce a major performance bottleneck. If not come up with a different design.
If your code is reasonable the bottleneck will likely be the database and somewhere in the region 100s of db ops per second. If that is insufficient then you may need to think about caching.
Definitely take a look at Spring Insight for performance monitoring and analysis.
English Wikipedia has 14GB data. A 8GB mem cache would have very high hit/miss ratio, and I think harddisk read would be well within its capacity. Therefore, the app is most likely network bound.
English Wikipedia has about 3000 page views per second. It is possible that tomcat can handle the load by careful tuning, and the network has enough throughput to server the traffic.
So the entire wikipedia site can be hosted on one moderate machine? Probably not. Just an idea.
-
http://stats.wikimedia.org/EN/TablesWikipediaEN.htm
http://stats.wikimedia.org/EN/TablesPageViewsMonthly.htm
Tomcat doesn't allow for spreading over multiple machines. If you really are concerned about scalability, you must consider what to do when your application outgrows a single machine.
Will a vps with 360 megs of ram running Linux be able to support a single user developing a java web application that uses Spring, Hibernate, and MySQL for the database? The server will be for development only so the application will not have more then one or two concurrent users.
edit:
By development I mean a server I can deploy and test on. The actual coding will be done on windows, but I want a Linux server to test on as well.
This could work ok, but it depends a lot on your application setup. If you cache a lot, your appserver caching page content, Hibernate caching query results/objects or MySQL caching query results you probably will need more RAM. So if your content is big it might not fit, otherwise it might just fit. If you have absulutely no option of increasing the amount of memory if you find out you need more I would certainly not recommend this setup.
But maybe more to the point: What is your target platform? I would say that your server should match that.
Just for linux testing it probably is easier to either get a cheap pc or run it inside a virtual machine on your development machine (assuming you've got plenty of ram on that one).
Depends on what you're running for your IDE. If you're using Eclipse, you're going to want somewhere around 1Gb of RAM (Eclipse is a memory hog...and slow as all hell if you don't have enough).
If you're using a more efficient (memory wise) IDE, then you should be good to go with that setup for development.
UPDATE
Since no coding is going to happen on the box...you should be just fine with that box to do your testing. Enjoy!
Short answer - I don't think you will have any problems with the amount of ram. I've deployed a rails app to a 256MB VPS and it worked great for development.