﻿{"id":176,"date":"2022-05-19T15:16:07","date_gmt":"2022-05-19T09:46:07","guid":{"rendered":"https:\/\/blogs.infosys.com\/engineering-services\/?p=176"},"modified":"2022-12-09T14:33:47","modified_gmt":"2022-12-09T09:03:47","slug":"building-high-available-and-high-performance-applications-with-springboot","status":"publish","type":"post","link":"https:\/\/blogs.infosys.com\/engineering-services\/iot\/building-high-available-and-high-performance-applications-with-springboot.html","title":{"rendered":"Building high available and high performance applications with springboot"},"content":{"rendered":"<p>Today any real world application requires a service which is scalable to handle more and more users and is highly available. For example if a person is buying its favorite game from a popular site and after spending 20 minutes in selecting color, size and pricing, webpage fails to confirm if the shopping was success or not. How would you rate the user experience?<\/p>\n<p>While in today\u2019s world, when one talks about IoT solution, more often the focal point is what \u2018things\u2019 can be connected in the network. But what if the \u2018connection\u2019 between things is not scalable enough or not available all the time. Having a reliable connection (or set of services) is the backbone of IoT solution. For creating high available and high performance production grade applications (or services), spring boot provides number of great tools. Making use of those tools in optimized way may result in highly efficient, secure and responsive APIs<\/p>\n<p>1.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Health endpoint \u2013<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-194\" src=\"https:\/\/blogs.infosys.com\/engineering-services\/wp-content\/themes\/infosys-blog\/images\/Sample-Image.jpg\" alt=\"\" width=\"549\" height=\"260\" \/><\/p>\n<p>Having a health endpoint helps in monitoring a production ready app at anytime. This could also be in use by load balancer. Based on the health endpoint response, load balancer may be routing the user requests. So a load balancer may not act properly if health endpoints are not implemented. Adding a dependency \u2018spring-boot-starter-actuator\u2019 will provide the endpoint by default. this is how a health endpoint typically looks like-<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-197\" src=\"https:\/\/blogs.infosys.com\/engineering-services\/wp-content\/themes\/infosys-blog\/images\/Sample-Image.jpg\" alt=\"\" width=\"622\" height=\"130\" \/><\/p>\n<p>Apart from health endpoints, there are number of similar endpoints which may provide operational information of the springboot APIs<\/p>\n<p>2.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Returning \u2018informative\u2019 status codes<\/p>\n<p>While browsing a popular website or mobile app, many of us might have seen messages saying \u2018some error occurred\u2019 or \u2018something went wrong\u2019. This could be because the API did not return a specific response to a request.\u00a0 Instead if the API returned a response like \u2018401 Unauthorized\u2019 gives more info which may be lot easier to resolve for a developer. With spring boot, one may even further customize the responses so as to provide more specific information. So instead of just returning the following response codes-<\/p>\n<p>200 OK<\/p>\n<p>500 internal server error<\/p>\n<p>Good practice would be to expand the range of response codes to include few more like-<\/p>\n<p>201 \u2013 a new resource was created<\/p>\n<p>400 \u2013 Bad Request<\/p>\n<p>401 \u2013 Unauthorized<\/p>\n<p>404 \u2013 Requested resource was not found<\/p>\n<p>and many more<\/p>\n<p>Even the above list is not complete and one may take advantage of \u2018ResponeEntity\u2019 like below-<\/p>\n<p>return ResponseEntity.status(HttpStatus.CREATED).body(&#8220;HTTP Status will be CREATED (CODE 201)\\n&#8221;)<\/p>\n<p>3.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Securing the API<\/p>\n<p>Some of the APIs could be meant for public consumption like knowing a weather of a place. Response of these APIs do not have any private information of person or business or government. But many of the APIs would contain information which must be protected. So while creating an API, a developer needs to ensure to add appropriate authentication mechanism. Which means the url of a service\/API can be known but service is available only after authenticating the client.<\/p>\n<p>There are multiple ways to secure the endpoint. One simple method is to add basic authentication. More sophisticated ways like ADFS could be used for more sensitive APIs. Also one needs to implement authorization for an API because desired response could be different for different users as per roles assigned within organization.<\/p>\n<p>If an API is implemented with basic authentication, while making request from postman, one needs to select \u2018Authorization\u2019 tab, then select Type as \u2018Basic Auth\u2019 and fill in Username and Password. If credentials are incorrect, API returns \u2018401 unauthorized\u2019 in the response.<\/p>\n<p>4.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Understanding LAZY and EAGER loading to improve performance<\/p>\n<p>Knowing when to load related objects can help optimize the performance of APIs. \u2018LAZY\u2019 is more efficient and is recommended unless there is specific requirement to do EAGER.<\/p>\n<p>LAZY = fetch when needed<\/p>\n<p>EAGER = fetch immediately<\/p>\n<p>5.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Handle simultaneous requests<\/p>\n<p>Most of the real-time applications have number of users simultaneously sending requests to the server. Now the challenge is to provide good user experience in such scenarios. If the request is simple GET request, it may not cause any issue as it is simply reading data from db and return success. But if the request is POST and is writing data to the DB, API may fail. Reason is that table could be auto incrementing the primary key value. So in case of multiple requests, primary key for 2 request could be same and db may likely complain about duplicate key.<\/p>\n<p>To avoid such scenarios, one needs to make use of \u2018synchronized\u2019 keyword. How it works is that it serializes the multiple requests which will result in slightly degraded performance. So to have optimal solution, one needs to ensure that only minimal and relevant section of the code is \u2018synchronized\u2019<\/p>\n<p>6.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Connections to DB to boost performance<\/p>\n<p>As spring boot does auto configuration, so it provides a default value for many of the configuration properties. Each service may have different number of concurrent users and different performance requirements, so it is important to understand the default configuration and change the configuration as per application requirement<\/p>\n<p>spring.datasource.hikari.maximumPoolSize=10<\/p>\n<p>spring.datasource.hikari.idleTimeout=120000<\/p>\n<p>spring.datasource.hikari.connectionTimeout=120000<\/p>\n<p>For example, the maximumPoolSize defines the maximum number of connections to database and default value is set to 10. While running application at peak load, if it throws errors like \u2018unable to acquire JDBC connection\u2019 then one needs to look at this property and optimize the value and retest.<\/p>\n<p>7.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Optimizing configuration to further boost performance<\/p>\n<p>One more thing worth checking is that how string parameters are sent to server.<\/p>\n<p>For example, for sql server, look at below property-<\/p>\n<p>sendStringParametersAsUnicode=false;<\/p>\n<p>Setting the above property is likely going to improve the performance of APIs. To understand more why such optimization is required, one can directly run the query in db and compare the timing taken by running same query through application code. If there is significant difference in timing, then this is the property to look at.<\/p>\n<p>8.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Adding indexing to improve performance<\/p>\n<p>Since adding an index requires extra disk space, one must add indices only. Indexing enhances the performance by storing additional information which returns a much quicker response while searching. Apart from this, in general also all queries should be optimized as much as possible. Simple way of achieving is to try to run the queries directly in the database first and then select the optimized one and add to application code<\/p>\n<p>9.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Making use of Inspect as much as possible<\/p>\n<p>For a web application, opening Inspect window can give lot of useful information about functional and performance issues. Inspect gives you information on how much times it took to get response, what parameters were sent in request body and what is complete response.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-196\" src=\"https:\/\/blogs.infosys.com\/engineering-services\/wp-content\/themes\/infosys-blog\/images\/Sample-Image.jpg\" alt=\"\" width=\"396\" height=\"167\" \/><\/p>\n<p>10.\u00a0\u00a0 Other best practices<\/p>\n<p>Apart the above mentioned, one needs to look at various other good practices for application development like logging of request\/response objects as per requirement, exception handling (spring boot provides various annotations), use of devtools for faster development, documentation generation etc.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today any real world application requires a service which is scalable to handle more [&hellip;]<\/p>\n","protected":false},"author":247,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[35],"tags":[38,39,37],"coauthors":[36],"class_list":["post-176","post","type-post","status-publish","format-standard","hentry","category-iot","tag-microservices","tag-performance","tag-springboot"],"acf":[],"_links":{"self":[{"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/posts\/176","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/users\/247"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/comments?post=176"}],"version-history":[{"count":11,"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/posts\/176\/revisions"}],"predecessor-version":[{"id":255,"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/posts\/176\/revisions\/255"}],"wp:attachment":[{"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/media?parent=176"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/categories?post=176"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/tags?post=176"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.infosys.com\/engineering-services\/wp-json\/wp\/v2\/coauthors?post=176"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}