spring-attic / spring-cloud-aws

All development has moved to https://github.com/awspring/spring-cloud-aws Integration for Amazon Web Services APIs with Spring
https://awspring.io/
Apache License 2.0
590 stars 373 forks source link

Support Servlet API and Spring MVC microservices #260

Closed ceefour closed 5 years ago

ceefour commented 7 years ago

I'd like to propose support for Servlet API and Spring MVC. Specifically, in order to do this there are incremental enhancements needed, each one builds upon previous:

  1. A standard way and best practices to deploy arbitrary event processing (like SCF)

    • For example, since startup time is more important in cloud functions than regular Spring Boot, there could be a guide that mention best practices on how to reduce startup time
      • Tooling (e.g. spring-cloud-function-maven-plugin) to trade runtime time vs. build time. For example, classpath scanning can be moved to build time, so at runtime there's much less work to do. This may require support in other Spring components.
      • A nice side effect is these optimizations can be used in regular Spring projects
    • Guide on how to optimize the "warm" container state, i.e. reusing Hibernate connections/connection pool
    • Guide for restrictions and gotchas that need to be followed (i.e. 50 MB limit, threading, shared stuff, filesystem, etc.)
    • Guide to optimize/preload classpath scanning
  2. Serve/wrap Servlet applications. For AWS, there is initial work in aws-serverless-java-container-spring made by @SAPessi of AWSLabs

    • What it does is simulating a Servlet 3.1 API "container" (tradeoff is some restrictions and some AWS benefits not possible with Servlet)
  3. Extend support for serving Spring MVC controllers.

    • This is already possible as proof-of-concept (thanks @joeyvmason!): Developing Serverless Applications with Spring MVC and AWS Lambda and serverless-spring-boilerplate, however very far from optimized i.e. 20+ second startup time (which is normal for some Spring Boot applications but is bad for lambda functions, the default timeout is 6 seconds although it can be increased to 60 seconds).
    • This potentially allows Spring to run many Java web frameworks not on top of servlet container anymore, but on top of serverless. See Zappa for successful example in Python world, that can run microservice frameworks like Flask, Bottle, Pyramid, but also full-stack Django apps, mostly without any code change. Please see Zappa's presentation slides to get a feel why this is important and such a game changer.
      • Of course the "other" web framework will need to ensure behave well in a serverless environment, but this will be much easier if Spring Boot components already laid the foundation to enable this support smoothly.
    • I also did a proof-of-concept that this can work: https://github.com/ceefour/wicket8serverless

      It's using Kotlin + Spring Boot + Web 1.5.6 and @martin-g's Wicket 8.0.0-M7 + Wicket Bootstrap 2.0.0-M6. Not slimmed versions of these frameworks, but the entire Spring Boot loader, Spring MVC dispatcherServlet and Wicket+Wicket Bootstrap installed as servlet Filter. It's definitely buggy and lots of gotchas, but initial work is in https://github.com/ceefour/aws-serverless-java-container/tree/spring-boot and hopefully @SAPessi will accept my pull request. :) The package is 24 MB but it's possible to reduce it more by configuring shade to minimizeJar, however my initial minimizeJar efforts resulted in CNF exceptions so I disabled minimizeJar.

      Deployed result is here: https://im9ntgimlc.execute-api.us-east-1.amazonaws.com/prod/

      Of course as expected, the startup time leaves so much to be desired: (there's not even Hibernate yet)

      image

      27 whole seconds just for startup. However, after it's warm, subsequent requests only take 300 ms which is still slow in serverless world, but can be optimized.

  4. Tooling to help local development. For example @Serverless annotation, if given, will enable checks during local development to detect restricted features in serverless environment and give WARN or even ERROR log or throw exception.

  5. Helpful extras to help Spring app developers modify Spring Boot/MVC apps to serverless programming model. To illustrate the kind of extras possible, allow me to quote Zappa's feature list:

    • Automatic support for all AWS event sources, allowing you to build robust "hybrid" applications
    • Automatic support for hundreds of pre-compiled and pre-optimized C-extentions packages (SciPy, etc.)
    • Support for applications which use multiple cookies simultaneously (i.e., anything with a login)
    • Free, auto-renewing SSL certificates from Let's Encrypt
    • CI integration
    • Automatic support for "global" (multi-region) applications
    • HTTP logging in the Common Log Format
    • Automatic "keep-warm"
    • Intelligent application and variable caching
    • Zero-effort CORS
    • Automatic and intelligent project initializion (zappa init)
    • Multiple environment variable sources (local, S3)
    • Multiple "secure endpoint" authentication methods (API Key, IAM, custom authorizers)
    • Content-Type aliases
    • Highly customizable configurations
    • Managed IAM credientials with the option to supply custom credentials
    • Package optimization
    • VPC-awareness
    • Ability to deploy HTTP-less, event-driven applications
    • Custom error-reporting (ex, to Sentry or Raygun)
    • Remote command invocation (include raw Python)

In the past, Java EE (and still to some extent Spring Boot) has been regarded to some people as hard to develop, hard to deploy, hard to maintain (DevOps, scaling, etc.), and expensive to operate (requiring servers etc.) Spring Boot is making it easy to develop. And Kotlin and upcoming Java 9 also makes the entire Spring Boot experience pleasant.

If existing Spring Boot apps can be supported with minimal change, that means app developers gain benefits such as easy deployment, automatic scalability, zero maintenance, stability, less vendor lock-in (i.e. Spring Boot app can be moved from AWS Lambda to other cloud providers and vice versa; and can still be deployed on PaaS like Pivotal Web Services; and regular instances). Assuming other cloud providers follow suit with AWS features (they usually do). This will make Spring much more attractive and increase adoption.

I sincerely hope that this enhancement proposal can be considered. You guys rock. Thank you! :)

This is originally from https://github.com/spring-projects/spring-boot/issues/10136 and https://github.com/spring-cloud/spring-cloud-function/issues/107, I hope it's okay to repost it here (with some adjustments).

spencergibb commented 5 years ago

I think this is better in spring cloud function.