A Spring Boot and MongoDB application story
üPDATE : there's a follow up to this post here, where we migrate this application to Spring Webflux and the new CosmosDB SQL SDK to go full reactive, and study the pros/cons of this migration.
This blog post comes from a discussion with a client, who uses JHipster extensively to generate Spring Boot microservices, using MongoDB databases. As he is an Azure customer, we had several questions:
- Can he host his whole architecture "as a service"? The Spring Boot applications would be automatically managed and scaled by Azure Web Apps, as well as his databases, using CosmosDB. That means a lot less work, stress and issues for him!
- CosmosDB supports the MongoDB API, but how good is this support? Can he just use his current applications with CosmosDB?
- What is the performance of CosmosDB, and what is the expected price?
So I created a sample Spring Boot + MongoDB application, available at https://github.com/jdubois/jhipster-cosmosdb-mongodb. This application is build with JHipster and uses one of our sample models, called the "bug tracker", and which is available here.
Migrating from MongoDB to CosmosDB
我们的应用程序并非易事:它具有多个集合,它们之间具有关系。 但是,CosmosDB支持所有这些API调用,因此迁移到CosmosDB非常简单:只需使用正确的连接字符串即可,仅此而已!
First I created a CosmosDB instance using the Azure Portal, and made sure it used the MongoDB API:
然后,选择该实例以获取到我的CosmosDB实例的连接字符串:
And all I needed to do, in this commit, was to use that connection string with Spring Boot.
请注意,我们在这里使用Spring Data MongoDB,它与CosmosDB完美配合。
Number of collections and pricing considerations
生成的数据库有8个集合:
请注意,其中两个收藏dbchangelog和蒙哥比洛克由JHipster使用来自动更新数据库(如果您来自SQL数据库世界,您可能知道Liquibase会做同样的事情)。 此外,我们有2个由JHipster创建的收藏集,jhi_authority和jhi_persistent_audit_event,但并非100%有用。
使用CosmosDB,您既可以按收款方式付款,也可以按数据库付款:默认配置是按收款方式付款,并且如果您没有价格问题,也建议您这样做,因为它将帮助您更好地扩展应用程序。 但是,在那种情况下,我们刚刚注意到的4个集合并不是真正有用,它们会花费您金钱。
因此,如果您从MongoDB迁移到CosmosDB,那么要处理的重要事情之一就是集合的数量:仅保留真正有用的集合,否则,这将使您的金钱毫无商业价值。
Deploying to Azure Web Apps
As explained on the JHipster documentation, this is just a matter of adding the right plugin, which is done in this commit.
We are using here Azure w ^eb Apps as we want to have fully-managed applications. Please note that this allows to "scale up" (= use a bigger server) or "scale out" (= add more servers on the fly), and we will use that later option to scale without coding anything.
First tests, with 100 users
It was surprisingly easy to deploy our application, but does it scale well? For this, let's use the Gatling load testing tool, as JHipster automatically generated a load testing configuration in src/test/gatling.
我们将专注于产品实体:
- As soon as the entity is used, CosmosDB will generate a collection for it. Be careful, as by default it will have 1,000 RU/s, so it costs some money.
- This entity also has an issue: it is not paginated! Pagination is useful from a business perspective (if we have 10,000 projects, showing them all to the end-user is not possible), but also from a performance point of view. As we have a limited number of request units per second, let's not waste them by requesting too many data! So we limited the request to 20 projects, in this commit.
我们的第一个测试仅使用100个并发用户,我们的峰值是每秒21个请求。 这不是很大的负担,所以一切都很好:
Going to 500 users
由于第一个测试太简单了,我们决定将系统推向500个用户。 一切进展顺利,我们达到了136个请求/秒的峰值,但是该应用程序开始出现一些问题。
实际上,由于身份验证过程花费了太多时间,系统发出了一些缓慢的请求:
Reaching 1,000 users
为了提高性能,我们决定将RU /秒升级到5,000,以进行身份验证和项目采集。 这是按付款项付款的好处:您可以根据业务需求选择要优先处理的付款项。
这使我们可以达到1,000个用户,但是仍然存在身份验证问题,这可能是因为此过程对于一个Web应用程序实例而言过于昂贵。 这就是为什么第一个请求很慢,然后我们更快的原因,峰值为308个请求/秒:
Up to 10,000 users
使用先前的配置,不可能超过2500个用户,因为应用程序服务器无法处理该负载。 Azure Web App的好处是,您可以使用它通过一个简单的屏幕来自动缩放Web应用程序:
当我们在多台服务器之间共享身份验证时,这解决了身份验证问题,该问题需要一些处理能力。 这也使我们能够支持更多并发请求。
使用此设置,我们可以达到10,000个活动用户:
此外,我们的峰值是1,029请求/秒:
但是,这里有2%的错误,因为我们达到10,000个用户的速度太快,导致系统无法正确处理所有错误。
Reaching 900 request/second without any issue
因为这里的问题是身份验证过程,并且只使用原始的Web应用程序功能,所以我们再次对1,000个用户进行了类似的测试,但是这次每个请求的处理量增加了10倍。 在这里,我们有一个非常流畅和稳定的应用程序,它始终如一地每秒交付900个请求:
Conclusions and thoughts
我们的测试表明:
- 使用MongoDB API运行CosmosDB在API级别上效果很好,并且完全能够扩展以处理负载Azure Web Apps允许轻松托管和扩展Spring Boot应用程序
我们已经从100个用户增加到10,000个用户,没有太多麻烦,除了我们必须增加CosmosDB的请求单位数量,并为Azure Web Apps配置自动缩放。 这使我们能够像往常一样继续使用Spring Boot和Spring Data MongoDB:两者都具有许多人喜欢的对开发人员友好的简洁API。 如果需要的话,只要我们愿意为此付费,我们可能会走得更远并处理更多的用户:好消息是可伸缩性很好并且似乎是线性的。