Tomcat Azure

 

I've created a webapp in Azure and uploaded a war file in D:homesitewwwrootwebapps folder. I use an app service plan with a standard pricing tier. I've done the settings to activate Java and Tomcat in Application Settings menu: java version: Java 8; java minor version: Newest; Web Container: Newest Tomcat. The Apache Tomcat ® software is an open source implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies. The Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket specifications are developed under the Java Community Process. The Apache Tomcat software is developed in an open and participatory environment. Don’t just monitor – observe and optimize your Tomcat environment from within Azure Monitor Blue Medora’s monitoring-integration-as-a-service (MIaaS) BindPlane solution enables you to gain deeper insights into the performance and status of your Tomcat database environment by harnessing the power of Azure Monitor.

Azure makes it easy to deploy and scale Java apps, using the tools you know and love. You can easily get started following below linkhttps://docs.microsoft.com/en-us/java/azure/

There are multiple approaches to run Java app on Azure App Services. One such would be to use Application Settings for enabling Java and Web Container.

After Enabling above options,

  • Tomcat is an open source web server designed to host and run Java-based web applications. It is a lightweight server that provides good performance for applications running in production.
  • Bitnami has partnered with Azure to make Tomcat available in the Microsoft Azure. Launch Tomcat with one click from the Bitnami Launchpad for Microsoft Azure. It is free and it takes only a minute. Follow the next steps to get started.
  • Navigate to kudu Console https://<Your_App_Name>.scm.azurewebsites.net/DebugConsole
  • Go to D:homesitewwwroot folder and you should find a webapps folder inside it.
  • You can drop your app’s .war file inside webapps folder (as in below image)
  • It would explode automatically and your app should be up and running

Here is how it works internally, Request reaches one of your worker instance and hits IIS which in-turn forwards it to Tomcat.

After couple of days, you might want to Add/Change tomcat config while using existing approach. You should be able to find tomcat config files in D:Program Files (x86)apache-tomcat-x.x.xxconf but unfortunately these files are not editable.

Scienario : By Default, Tomcat doesn’t print time taken for request in site access log. Here i would alter tomcat config using a workaround for above approach to print time_taken.

  • Create a web.config file inside D:homesitewwwroot with below content in it

web.config is an IIS configuration file and we are using it to pass extra config in arguments to tomcat when it starts tomcat for the first request.

Note: Here i have set processPath to D:Program Files (x86)apache-tomcat-8.5.20binstartup.bat. Change it as per your requirement

As you can see above, we are passing D:homesitewwwrootconfserver.xml as our new tomcat config file.

  • Create new server.xml file at above mentioned location and copy content fromD:Program Files (x86)apache-tomcat-x.x.xxconfserver.xml

Alter its value to obtain required config. I have added %T in pattern for site_access_log as below

Here is my site_access_log with time_taken printed in it.

Troubleshoot:

  1. App did not start after above configuration. Make sure your app is using 64-bit java/platform. In above web.config file we have added few extra CATALINA_OPTS that doesn’t go well on 32-bit.

Reference:

https://docs.microsoft.com/en-us/iis/extensions/httpplatformhandler/httpplatformhandler-configuration-reference

-->

This guide describes what you should be aware of when you want to migrate an existing Tomcat application to run on Azure Spring Cloud.

Pre-migration

To ensure a successful migration, before you start, complete the assessment and inventory steps described in the following sections.

Switch to a supported platform

Azure Spring Cloud offers specific versions of Java SE. To ensure compatibility, migrate your application to one of the supported versions of its current environment before you continue with any of the remaining steps. Be sure to fully test the resulting configuration. Use the latest stable release of your Linux distribution in such tests.

Note

This validation is especially important if your current server is running on an unsupported JDK (such as Oracle JDK or IBM OpenJ9).

To obtain your current Java version, sign in to your production server and run the following command:

Determine whether and how the file system is used

Any usage of the file system on the application server will require reconfiguration or, in rare cases, architectural changes. You may identify some or all of the following scenarios.

Read-only static content

If your application currently serves static content, you'll need an alternate location for it. You may wish to consider moving static content to Azure Blob Storage and adding Azure CDN for lightning-fast downloads globally. For more information, see Static website hosting in Azure Storage and Quickstart: Integrate an Azure storage account with Azure CDN.

Dynamically published static content

Tomcat Azure Paas

If your application allows for static content that is uploaded/produced by your application but is immutable after its creation, you can use Azure Blob Storage and Azure CDN as described above, with an Azure Function to handle uploads and CDN refresh. We've provided a sample implementation for your use at Uploading and CDN-preloading static content with Azure Functions.

Identify the Application Build/Dependency System

Identify what tool(s) are used to build/package the application, including downloading all the dependencies.

Inventory external resources

External resources, such as data sources, JMS message brokers, and others are injected via Java Naming and Directory Interface (JNDI). Some such resources may require migration or reconfiguration.

Inside your application

Inspect the META-INF/context.xml file. Look for <Resource> elements inside the <Context> element.

On the application server(s)

Inspect the $CATALINA_BASE/conf/context.xml and $CATALINA_BASE/conf/server.xml files as well as the .xml files found in $CATALINA_BASE/conf/[engine-name]/[host-name] directories.

In context.xml files, JNDI resources will be described by the <Resource> elements inside the top-level <Context> element.

In server.xml files, JNDI resources will be described by the <Resource> elements inside the <GlobalNamingResources> element.

Datasources

Datasources are JNDI resources with the type attribute set to javax.sql.DataSource. For each datasource, document the following information:

  • What is the datasource name?
  • What is the connection pool configuration?
  • Where can I find the JDBC driver JAR file?

For more information, see JNDI Datasource HOW-TO in the Tomcat documentation.

Azure

All other external resources

It isn't feasible to document every possible external dependency in this guide. It's your team's responsibility to verify that you can satisfy every external dependency of your application after the migration.

Inventory secrets

Passwords and secure strings

Check all properties and configuration files on the production server(s) for any secret strings and passwords. Be sure to check server.xml and context.xml in $CATALINA_BASE/conf. You may also find configuration files containing passwords or credentials inside your application in META-INF/context.xml.

Inventory certificates

Document all the certificates used for public SSL endpoints or communication with backend databases and other systems. You can view all certificates on the production server(s) by running the following command:

Determine whether your application contains OS-specific code

If your application contains any code with dependencies on the host OS, then you'll need to refactor it to remove those dependencies. For example, you may need to replace any use of / or in file system paths with File.Separator or Paths.get.

Identify all outside processes and daemons running on the production servers

If you have any processes running outside the application server, such as monitoring daemons, you'll need to eliminate them or migrate them elsewhere.

Determine whether Tomcat is connected to a web server

Tomcat can be connected to a static web server, such as Apache, via a tomcat connector, such as mod_jk. Inspect the workers.properties file in the conf directory to determine whether such a connection exists.

Special cases

Certain production scenarios may require additional changes or impose additional limitations. While such scenarios can be infrequent, it's important to ensure that they're either inapplicable to your application or correctly resolved.

Determine if the application uses filters

Inspect the application's web.xml file for any configured filters.

Determine whether your application relies on scheduled jobs

Scheduled jobs, such as Quartz Scheduler tasks or Unix cron jobs, should NOT be used with Azure Spring Cloud. Azure Spring Cloud will not prevent you from deploying an application containing scheduled tasks internally. However, if your application is scaled out, the same scheduled job may run more than once per scheduled period. This situation can lead to unintended consequences.

Inventory any scheduled tasks running on the production server(s), inside or outside your application code.

Determine whether non-HTTP connectors are used

Azure Spring Cloud supports only HTTP connections on a single, non-customizable HTTP port. If your application requires additional ports or additional protocols, do not use Azure Spring Cloud.

To identify HTTP connectors used by your application, look for <Connector> elements inside the server.xml file in your Tomcat configuration.

Determine whether SSL session tracking is used

On Azure Spring Cloud, the SSL session will terminate prior to reaching your application code, so you can't use SSL session tracking. You will need to switch to using Spring Session instead.

Determine whether Tomcat realms are used

On Azure Spring Cloud, Spring Security must be used in place of Tomcat realms. Inspect your server.xml file to inventory any configured realms.

Determine whether servlet filters are used

Inspect the web.xml file in the application for any <filter> elements. For a list of available filters, see the Tomcat filter documentation.

Migration

Remove connection to web server, if present

If Tomcat is connected to a static web server, typically to Apache via mod_jk, disable that connection so that Tomcat runs as a standalone server, creating web redirects from the standard server as needed. Consider migrating static web content to Azure Storage with Azure Content Delivery Network (CDN). For more information, see Static website hosting in Azure Storage and Quickstart: Integrate an Azure Storage account with Azure CDN.

Update to Tomcat 9

If your current application is running on a version of Tomcat prior to 9, migrate to Tomcat 9 and verify that the application is fully functional. For more information, see the Tomcat 9 Migration Guide.

Switch to Maven or Gradle

Spring Boot and Spring Cloud require Maven or Gradle for build and dependency management. If your application uses another build or dependency management system, switch to the current version of Maven before proceeding. While Gradle is also supported, we will use Maven throughout the steps of this guide. Should you decide to use Gradle, adapt the instructions accordingly.

Create a POM file for your application, and make sure the application builds and runs with full functionality before proceeding.

Migrate to Spring Boot

The following table shows a summary of necessary migrations and code changes to migrate a Tomcat application to Spring Boot and, subsequently, to Azure Spring Cloud. If any element in the Legacy column is used in the application, it should be replaced with the corresponding element in the Minimum or, ideally, Recommended column.

LegacyWhere to checkMinimum migrationRecommended migration
JDBC via DataSourceserver.xmlSpring Data Datasource with JDBC TemplateConsider Spring Data and JPA, if appropriate.
Servletsweb.xmlEnable Servlet Context Initialization and annotate with @WebServletRewrite as Spring-MVC Controllers (with @RestController)
Filtersweb.xmlEnable Servlet Context Initialization and annotate with @WebFilterSame as Minimum
Java Server Pages (JSPs)web.xml and WAR file contentsJSP Views for Spring MVCHost the view layer separately
Java Message Service (JMS)server.xmlInstantiate connection factory as a Spring BeanUse Spring JMS
Static content (images, JavaScript files, and so on) inside the WAR filestatic content directory (typically /static, /public, or /resources)Move content to /src/main/resourcesSee static content recommendations in Pre-migration.
Static content (images, JavaScript files, etc) outside the WAR fileA path on the local file systemMove content to src/main/resources. Search source code for hard-coded paths and replace with ClassPathResourceSee static content recommendations in Pre-migration.
  1. If your application relies on libraries injected via JNDI resources (such as JDBC drivers), add these libraries as dependencies into your POM file. Remove the libraries from the Tomcat server (typically from the tomcat/lib directory), and verify that the application runs with full functionality before proceeding.

  2. Add the Spring Boot parent POM to your POM file. For more information, see Creating the POM in the Spring Boot documentation.

  3. Add the Spring Boot Tomcat starter as a dependency to your POM file:

    Although this is formerly a Tomcat application, do not add war as target packaging.

  4. Replace Tomcat data sources with Spring data sources. Configure Spring DataSources for all the databases used by the application. If any code executes direct SQL queries, modify it to use JdbcTemplate. See the Spring Framework documentation and Spring Data documentation for additional data access features, such as transaction management and CRUD tooling.

  5. While it is possible to have servlet implementations inside an embedded servlet container, we do not recommend doing so. Instead, replace servlet implementations with Spring Rest controllers. If your application uses a non-Spring MVC framework, replace it with Spring MVC. See Spring MVC annotated controller reference for more information.

  6. Recreate all other JNDI dependencies with Spring beans. Favor using Spring-idiomatic mechanisms, such as using Spring JMS for messaging.

  7. Replace Tomcat Realms with Spring Security. Consider using Azure Active Directory for authorization management via the Spring Boot Starter for Active Directory.

  8. Recreate Servlet filters configured in web.xml with Spring beans or classpath scanning.

  9. If the application contains or references static content, such as images or JavaScript files, these files should be moved to src/main/resources in the project source code. After moving the files, update the source code to remove any local file system references. Use Spring's ClassPathResource class to access such files.

Test the application by running mvn spring-boot:run. Verify that the resulting application runs with full functionality before proceeding.

Create an Azure Spring Cloud instance and apps

Provision an Azure Spring Cloud instance in your Azure subscription, if one does not already exist. Then, create an application there. For more information, see Quickstart: Launch an existing Azure Spring Cloud application using the Azure portal.

Ensure console logging and configure diagnostic settings

Configure your logging so that all output is routed to the console and not to files.

After an application is deployed to Azure Spring Cloud, add a diagnostic setting to make logged events available for consumption, for example via Azure Monitor Log Analytics.

LogStash/ELK Stack

If you use LogStash/ELK Stack for log aggregation, configure the diagnostic setting to stream the console output to an Azure Event Hub. Then, use the LogStash EventHub plugin to ingest logged events into LogStash.

Splunk

If you use Splunk for log aggregation, configure the diagnostic setting to stream the console output to Azure Blob Storage. Then, use the Splunk Add-on for Microsoft Cloud Services to ingest logged events into Splunk.

Configure persistent storage

If any part of your application reads or writes to the local file system, you'll need to configure persistent storage to replace the local file system. For more information, see Use persistent storage in Azure Spring Cloud.

You should write any temporary files to the /tmp directory. For OS independence, you can get this directory by using System.getProperty('java.io.tmpdir'). You can also use java.nio.Files::createTempFile to create temporary files.

Migrate all certificates to KeyVault

Azure Spring Cloud doesn't provide access to the JRE keystore, so you must migrate certificates to Azure KeyVault, and change the application code to access certificates in KeyVault. For more information, see Get started with Key Vault certificates and Azure Key Vault Certificate client library for Java.

Remove application performance management (APM) integrations

Eliminate any integrations with APM tools/agents. For information on configuring performance management with Azure Monitor, see the Post-migration section.

Tomcat Azure Security

Disable metrics clients and endpoints in your applications

Remove any metrics clients used or any metrics endpoints exposed in your applications.

Deploy the application

Deploy each of the migrated microservices (not including the Spring Cloud Config and Registry servers), as described in Quickstart: Launch an existing Azure Spring Cloud application using the Azure portal.

Configure per-service secrets and externalized settings

You can inject any per-service configuration settings into each service as environment variables. Use the following steps in the Azure portal:

  1. Navigate to the Azure Spring Cloud Instance and select Apps.
  2. Select the service to configure.
  3. Select Configuration.
  4. Enter the variables to configure.
  5. Select Save.

Migrate and enable the identity provider

If any of the Spring Cloud applications require authentication or authorization, ensure they're configured to access the identity provider:

  • If the identity provider is Azure Active Directory, no changes should be necessary.
  • If the identity provider is an on-premises Active Directory forest, consider implementing a hybrid identity solution with Azure Active Directory. For more information, see the Hybrid identity documentation.
  • If the identity provider is another on-premises solution, such as PingFederate, consult the Custom installation of Azure AD Connect topic to configure federation with Azure Active Directory. Alternatively, consider using Spring Security to use your identity provider through OAuth2/OpenID Connect or SAML.

Expose the application

By default, applications deployed to Azure Spring Cloud are not visible externally. You can expose your application by making it public with the following command:

Skip this step if you are using or intend to use a Spring Cloud Gateway (more on this in the following section).

Tomcat Azure Data

Post-migration

Now that you've completed your migration, verify that your application works as you expect. You can then make your application more cloud-native by using the following recommendations.

Azure Tomcat App Service

  • Consider enabling your application to work with Spring Cloud Registry. This will enable your application to be dynamically discovered by other deployed microservices and clients. For more information, see Tutorial: Prepare a Java Spring app for deployment. Then, modify any application clients to use the Spring Client Load balancer. This allows the client to obtain addresses of all the running instances of the application and find an instance that works if another instance become corrupted or unresponsive. For more information, see Spring Tips: Spring Cloud Load Balancer in the Spring Blog.

  • Instead of making your application public, consider adding a Spring Cloud Gateway instance. Spring Cloud Gateway provides a single endpoint for all applications/microservices deployed in your Azure Spring Cloud instance. If a Spring Cloud Gateway is already deployed, ensure that it's configured to route traffic to your newly deployed application.

  • Consider adding a Spring Cloud Config server to centrally manage and version-control configuration for all your Spring Cloud microservices. First, create a Git repository to house the configuration and configure the Azure Spring Cloud instance to use it. For more information, see Tutorial: Set up a Spring Cloud Config Server instance for your service. Then, migrate your configuration using the following steps:

    1. Inside the application's src/main/resources directory, create a bootstrap.yml file with the following contents:

    2. In the configuration Git repository, create a .yml file, where your-application-name is the same as in the preceding step. Move the settings from application.yml file in src/main/resources to the new file you just created. If the settings were previously in a .properties file, converted them to YAML first. You can find online tools or IntelliJ plugins to perform this conversion.

    3. Create an application.yml file in the directory above. You can use this file to define settings and resources that will be shared among all applications on the Azure Spring Cloud instance. Such settings typically include data sources, logging settings, Spring Boot Actuator configuration, and others.

    4. Commit and push these changes to the Git repository.

    5. Remove the application.properties or application.yml file from the application.

  • Consider adding a deployment pipeline for automatic, consistent deployments. Instructions are available for Azure Pipelines, for GitHub Actions, and for Jenkins.

  • Consider using staging deployments to test code changes in production before they're available to some or all of your end users. For more information, see Set up a staging environment in Azure Spring Cloud.

  • Consider adding service bindings to connect your application to supported Azure databases. These service bindings would eliminate the need for you to provide connection information, including credentials, to your Spring Cloud applications.

  • Consider using Distributed Tracing and Azure App Insights to monitor performance and interactions of your applications. For more information, see Use distributed tracing with Azure Spring Cloud.

  • Consider adding Azure Monitor alert rules and action groups to quickly detect and address aberrant conditions. For more information, see Tutorial: Monitor Spring Cloud resources using alerts and action groups.

  • Consider replicating the Azure Spring Cloud deployment in another region for lower latency and higher reliability and fault tolerance. Use Azure Traffic Manager to load balance among deployments or use Azure Front Door to add SSL offloading and Web Application Firewall with DDoS protection.

  • If geo-replication isn't necessary, consider adding an Azure Application Gateway to add SSL offloading and Web Application Firewall with DDoS protection.