Key Takeaways
- Microsoft provides all the needed tools for building serverless applications as well as Continuous Deployment tooling. Currently, there is support both in Azure DevOps and GitHub Actions.
- Besides Spring Boot, Azure provides support for Quarkus, Micronaut. JHipster supports deployment to Azure out of the box as well.
- Using "lift and shift" one can easily transform a classical Spring Boot application deployed on Tomcat into a "serverless" Azure App. The MVC Controllers would need to be rewritten, the complex part would be on the DB side, where additional effort should be put to obtain similar behaviour.
- Both Java 8 and 11 are properly supported on Azure.
- Choosing carefully the tools used one can assure that moving from Azure to another cloud provider is stress-free
Microsoft seems to prove over and over again its focus on cloud and the Java ecosystem is the new normal. Even though Java is amongst the supported languages for Azure functions for some time now, Julien Dubois experimented with Spring Boot and Azure to see what this combination means for Azure serverless computing. InfoQ reached out to him to explore further his experience putting together a Spring Boot application on Azure.
InfoQ: Thank you for taking the time to answer some questions for our readers. Can we start by asking you to introduce yourselves and describe your roles and day-to-day at Microsoft?
Julien Dubois: I’ve been in the Java community for more than 20 years, and I’m mostly known as the creator of JHipster and as a Java Champion. Professionally, I’m leading the Java Cloud Developers Advocacy team at Microsoft. The role of my team, within the Developer Relations organization, is to reach out to Java developers in order to make Azure the best platform for them. Day-to-day, this means working with various Java communities and partners to gather feedback, improve the documentation and work with our engineering teams to enhance our products and services.
InfoQ: It seems that Microsoft is becoming a powerhouse of Java developers. What brought you to Microsoft?
Julien Dubois: As of today, Microsoft employs 11 Java Champions, and we have great support and plans for Java. Also, Microsoft is not just Azure: we have lots of Java developers working for LinkedIn or Minecraft!
I came to Microsoft firstly because it’s a company that made me dream when I was a kid, and as I wanted to work remotely for a US company. I love the company values and spirit, and as someone who enjoys technology, it’s one of the best places to grow and learn.
InfoQ: What did your coming to Microsoft meant for JHipster? Was it influenced in any way?
Julien Dubois: Being the creator of JHipster was definitely a strength when I got hired, then I have a professional life at Microsoft which is very different from my OSS life with JHipster. I clearly have less time today to work on JHipster, but that’s not totally the fault of my role at Microsoft. I had a fourth child last year, and with COVID-19 this means I didn’t have a lot of free time. The great thing with JHipster is that this allowed other people to grow in the community, and in the end the project is probably stronger and more stable.
InfoQ: It seems that Microsoft is getting close to becoming a first-class citizen of the Java and cloud ecosystem. Is this the case?
Julien Dubois: I believe it’s already the case. We use Java in a wide number of products within Microsoft, including Azure, where it’s definitely a first-class citizen. For instance, we have Java support in Azure App Service, which is our PaaS offer, as well in Azure Functions, which is our serverless offer. I’ve been deeply involved in Azure Spring Cloud, which is a Spring-specific offer that we jointly built with the Spring team, from VMware. So yes, we have a deep involvement in Java, and it’s going to go much stronger in the near future.
InfoQ: The serverless movement is gaining momentum. How do you feel about it? How close to production readiness is it?
Julien Dubois: We have already a lot of customers in production on Azure Functions, including huge clients running Java workloads. I’ve seen very exciting things in this space, but I believe it’s only the beginning. Initially, Java is not a great fit for serverless, and there are still a lot of improvements that can be done in the future to reduce the cost of serverless functions, to improve their cold start time, to monitor them better and scale them better. One of the favorite parts of my job is to work with the engineering team in charge of serverless on Azure.
InfoQ: What are the tools Microsoft built to enter this space? What tool would you need from the offer of other cloud providers? Is it possible to integrate with other providers as well?
Julien Dubois: We have a runtime, language-specific workers (for ex the Java worker), a CLI, as well as IDE plugins. They are all open source. Those build on the same foundations as Azure App Service, our PaaS offering, which provides a lot of production-proven features, as well as a few limitations: this allowed us to enter this space very fast, with a very complete offer, but it works in a way which might be surprising to people coming from other cloud providers. The main difference is that your function can be called by different clients at the same time: we allow you to use multiple threads, like a traditional application in fact. This improves performance and cost a lot, and is usually a good thing for people using Java, which suffers from its cold start-up time.
Concerning interoperability with other cloud providers, let me talk like an old Spring user. We work closely with the Spring team, so you can deploy your workloads using Spring Cloud Function. There are some very small differences between providers here, and in fact, I’m currently working on fixing one, but basically you should be able to run the same Spring Boot code on any cloud provider using that abstraction. Spring is providing here what they have always done, like in the old J2EE days: an abstraction that allows you to change providers without modifying your code.
InfoQ: Did you use any other providers except Azure? How do they feel in comparison?
Julien Dubois: In my past life as a consultant, I’ve used a lot of them. The most obvious ones are naturally AWS, GCP and Heroku, but I’ve also spent a lot of time with smaller providers who provide simple VMs and networking solutions.
First of all, I’m clearly a PaaS person: I don’t like to maintain VMs, Kubernetes clusters or SQL databases. I believe there are today excellent PaaS solutions, for a very cheap price, and doing anything by hand is a waste of time, and also a poor production choice. You just can’t compete with what the big cloud providers can propose. Now, all the big cloud providers have their own advantages and I’ve had excellent experiences with some Azure competitors. JHipster Online, runs on GCP as they have been sponsoring us from the start. Most of the JHipster users usually start by using Heroku, as their free tier is good enough for them, thanks to the Heroku team which did an awesome job to fine-tune it. Those are all great options, and we are lucky that Java runs so well on so many different platforms.
InfoQ: Azure Functions documentation states that a HTTP-native programming language will allow the development of Azure Functions. What does that actually mean in Java? What do you need to do to write a Java Azure Function?
Julien Dubois: In fact here are two ways to run a Java function on Azure. There’s the classical way: we have an official Java worker, with great documentation and API. This is what most people are using, and it’s the one I recommend as you will also have JDK support and better monitoring. Your cold-start performance should also be quite good, as we do a number of tricks to improve it, including pre-warming some machines in advance.
Then, there is the non-official way, which is the one you mention by talking about HTTP, with a new feature called “Azure Functions custom handlers”. With this method, our HTTP broker only understands that it talks with an HTTP server, so it doesn’t know anything about your application: this removes all possibilities of tuning and monitoring on our side, but it allows you to develop your application the way you want. What everybody is trying to do today, including me, is to build Java functions using GraalVM native images. This already works well for a number of cases, including using Spring Cloud Functions. There’s still a long road before that can be used safely into production, but if you like to use the latest and greatest technology that’s certainly a lot of fun.
InfoQ: Java 8 is one of the supported programming languages for Azure Functions. How was the experience of using it?
Julien Dubois: Oh, we are already on Java 11, as it’s the new LTS version. If it was just me, we would also have Java 14 support, but most customers today are still on Java 8, so we are not rushing on this. The biggest improvement we’ve had on this side is to have Linux support. It may look surprising, but we have customers who are doing some specific tunings that require Java on Linux, and for historical reasons we initially were only providing Java on Windows.
Also, please note that we work with Azul systems in order to have a supported and patched JDK, which is extremely important to our customers and ourselves, as we take security very seriously.
InfoQ: You managed to deploy a serverless Spring Boot application on Azure. Can you please describe the experience for us?
Julien Dubois: In fact I did it in two different ways. Firstly, I used the official method of using Spring Cloud Function to deploy a Spring Boot application to Azure Functions. This code has become the official sample application on Azure. This works well, then this solution can be improved as we need a specific configuration class for this, and I’m currently working with the Azure engineering team and the Spring Boot team to improve this.
Secondly, I tried to use the new “Azure Functions custom handler” to build the same function with GraalVM. I did this with the help of my friends from the Spring and GraalVM teams, and it does work fine. Please note that I haven’t used it extensively in production, so I wouldn’t recommend it if you want to use some serious workload. Then, this allowed me to uncover a couple of weird behaviors in Azure Functions, and I have reported this internally, so we are actively fixing those.
InfoQ: Did it work out of the box, or was additional effort required?
Julien Dubois: For the official, supported method, there is an Azure-specific configuration file to be aware of when you use Spring Cloud Function, but overall this didn’t require any specific effort.
For using GraalVM that’s another story, as nobody had done it before. Most of the hard work had already been done by the Spring and GraalVM team, but I think it took me a couple of days to have everything running smoothly. Of course, now you can use my GitHub repo, which is fully documented, and you should have the same result much faster.
InfoQ: It seems that Microsoft has now all the necessary bits for a whole Continuous Deployment flow. Is that the case?
Julien Dubois: In fact you have two options offered by Microsoft. The main current offer is called Azure DevOps, and it’s very complete and very powerful, so this is the one we would recommend to everyone. On JHipster, we used it for several months, as it has got a very generous free tier for OSS projects, and that was hugely successful. It is of course fully integrated into Azure and the whole Microsoft stack.
Then, you might know that GitHub has this new service called GitHub Actions. This one is showing tremendous growth as everybody on GitHub is using it. It is still currently less powerful than Azure DevOps, but it is moving very fast, and it has the huge benefit of being integrated into GitHub. This is the main reason why we migrated the JHipster CI/CD pipeline to GitHub Actions: we have a huge number of contributors, with many permissions to set up, and as the organization administrator that was much easier for me. Also, it is totally sufficient for our use cases, and today we are very happy with this solution.
InfoQ: This seems rather similar to Quarkus and Amazon Lambda. Did you have the chance to experiment with this combination as well? How do they compare to Spring Boot and Azure?
Julien Dubois: I didn’t try Quarkus on Lambda, but I did try Quarkus on Azure! In fact, we do similar work with the Spring, Quarkus and Micronaut teams so the three main Java frameworks are equally supported on our services. Now, all of them work in a very similar way on the JVM, and the experience should be pretty close. The main area of experimentation at the moment, and where there is a huge potential, is running those frameworks with GraalVM on Azure Functions. This would definitely be a game-changer, then it’s really complicated to have the level of support that we provide with the JVM, which means that at least in the short term there will be a lot more responsibilities on the developer side. Let me give an example: we provide our JVM users with a managed OS and JVM, so if there is a security issue on the JVM, we’re going to patch it for you: you will not notice anything, and as we use a supported JVM version from Azul systems, we might even patch it before the security issue is public. On the opposite, if you want to do the same with GraalVM, at the moment you are on your own: it would be your responsibility to upgrade and patch your binary, as all we will see on the Azure side is a binary.
InfoQ: What would be the best suited scenario for a serverless app with Azure? Would you use it if you would need to build something from scratch now? Why?
Julien Dubois: We currently have many different clients, with very different scenarios, who have a successful experience. So it’s hard to tell about a “best” scenario, but at least I can talk about one of our big and interesting use cases. It’s a very well-known French company that does a service which is used by a lot of people, literally tens of millions, but that usage varies a lot depending on the time or the day. Typically people use this service a lot in the evening, and that usage can grow a lot depending on some public events or announcements. I had the opportunity to visit them before COVID-19, as their office is close to ours, and during peak hours their usage is incredible. Those people are running Java and Spring on top of Azure Functions, and their pool of instances just grows and shrinks automatically depending on usage, without them doing any maintenance. In the end, they focus on their code and on their business features, and then everything just works and handles load without them doing anything, so it’s definitely a great scenario. I believe it removes a lot of trouble for them, and makes them gain a lot of money.
InfoQ: How complicated would it be to migrate a production-ready application to the serverless model with Azure?
Julien Dubois: As I’m a Java person, let’s talk about a classical Spring Boot application running on Tomcat, which would be a very usual scenario. There are two ways of migrating this to a serverless model: you could do what we call “lift and shift”, and you could re-architect everything.
With “lift and shift”, one of the troubles you will have is that you will need to port all your Spring MVC Controllers to become Spring Cloud functions. There are different ways and tricks to achieve this, and you will have some limitations, but that should work without spending too much money. Also, you wouldn’t touch your business code too much, so nothing important should break.
Then, an Azure Function works in a very different way from a classical Spring Boot application: you can still benefit from a Hibernate second-level cache or from a database connection pool, but you can easily understand that they will not be as efficient, as their time to live will be much lower. Using a distributed cache will be a huge trouble here. Also, your function can scale up a lot better than your one-node Tomcat server, so maybe your database will not work as well as before, as it wasn’t built for that sort of load. You could use instead of a database like CosmosDB, or a caching solution like Redis, which are two very widely used options on Azure. This is a lot more work, but that’s the only way to get all the benefits from a serverless platform. This is what we call “re-architecting”, the need to transform your whole application and its services in order to take full advantage of the cloud platform.
InfoQ: How about from another cloud provider?
Julien Dubois: I can mainly talk about Amazon Lambda here, but I believe many other serverless providers work the same. There is a huge difference between Azure Functions and Amazon Lambda: with Azure, your application is started and runs for a few minutes, and during that time multiple clients can access it, and its background threads work as usual. On Amazon you would have one execution per client, and background threads probably wouldn’t work very well. So with Azure the behavior you have is like a “normal” application, with the difference that it doesn’t run for very long. This means most existing applications will run the same, and as you should have designed your application to handle failure, the fact that it runs only a few minutes (and not days or weeks) shouldn’t be a big issue. This is why the “lift and shift” scenario works quite well with Azure, and other cloud providers will probably require you to do a full re-architecture of your application. Then, even with Azure, re-architecture is the only way to get the most of your serverless application, so there is no magic solution here.
InfoQ: How easy it would be to move your app to another provider? Would developing an app in the Azure space mean a vendor lock?
Julien Dubois: It depends on which services you use, and which framework you use! Concerning frameworks, as we discussed earlier, there are solutions like Spring Cloud Function, Quarkus and Micronaut that give you an abstraction on top of your cloud provider. In Java you would probably use one of those frameworks anyway, which means most of your code should run the same on all platforms. Then, concerning services, it’s clear that if you use CosmosDB, which is an excellent but Microsoft-only solution, you will have trouble moving to another cloud vendor. This is why, when I do demos with JHipster, I use services like MySQL, which run everywhere the same. And when I want to use CosmosDB, I use their MongoDB API: this way I can easily migrate to another cloud provider that supports MongoDB.
Then, trying to be vendor-neutral will limit you a lot, and you probably won’t be able to use many advanced features from your cloud provider. This is like people trying to use a database using only standard SQL. You are losing a lot, and for the wrong reason: the migration cost won’t be in using another API, but in moving all your data from one service to the other.
InfoQ: Let’s crunch the two projects you are involved with together: would it be possible to mix JHipster and Azure together for development purposes? How would you envision that?
Julien Dubois: Oh, we do already support deploying JHipster to Azure! We officially support Azure Spring Cloud and Azure App Service, which are the two main options for Java developers. Then, JHipster’s Kubernetes support works on Azure Kubernetes Service without us doing any specific work. Of course I would like to go further, and one of the ideas I’m toying with is to have much better Terraform support in JHipster: this would allow to generate much more complex infrastructures on Azure.
InfoQ: Any hints for those just getting started with Azure Functions?
Julien Dubois: I would recommend building a simple serverless application like you can do with Azure Static Web Apps. This only works with JavaScript at the moment, but this is free and simple to use, so it’s a great way to test and learn when you start. Also, you have some great documentation on our Microsoft Learn website.
The most complicated things here are the concepts, and then applying this to another language shouldn’t be a big issue.
About the Interviewee
Julien Dubois, manager of the Java developer advocacy team at Microsoft, has been experimenting with Spring Boot and Azure to see what this combination means for Azure serverless computing. Julien Dubois is the creator and lead developer of the JHipster project and is a Java Champion. In the past 20 years, he has mainly worked with Java and Spring technologies as an architect and as a consultant, working for many different customers across all industries. As he loves to share his passion, Julien Dubois wrote a book on the Spring Framework, spoke at more than 100 international conferences, and created several popular open-source projects.