java - 软件即服务 (SaaS) 的应用程序设计

标签 java dns distributed saas java-ee-7

所以我目前正在设计 SaaS 应用程序。我的设计有一个小问题。 假设我在 www.mycompany.com 下部署了一个应用程序。用户购买订阅并因此可以访问该应用程序。 现在我想要的是一种每当用户购买订阅时创建此应用程序的新实例的“方法”,例如:

约翰拥有 Vega 公司。当他购买访问/使用我的应用程序的许可证时,就会创建一个新实例,可以通过 www.vega.mycompany.com 访问该实例。 创建他的帐户后,将部署应用程序的新实例,创建新数据库并将其与我的应用程序的新创建实例链接。

其背后的原因是:

  1. John 可能会生成大量数据,因此拥有多个较小的数据库比为每个客户提供一个数据库更好。
  2. John 可能会存储他不希望与其他用户存储在同一数据库中的敏感数据。

我想用 Java 开发应用程序。我用来创建 SaaS 应用程序新实例的管理应用程序也将用 Java 开发。 现在我的问题是:

  1. 我如何才能真正实现这一目标?每当创建新帐户时,我是否只需在应用程序容器(例如 Tomcat)中部署相同的 WAR 文件?
  2. 如何从管理员应用程序创建“vega”子域 - 这可能吗?
  3. 如果出现错误或者我想简单地更新某些内容,并且我有该应用程序的 1000 个实例,我该如何顺利完成更新?

最佳答案

我现在正在研究类似的问题/解决方案,尽管它是用 C# 编写的,但它将在带有 Mono 的 Linux 中运行,我相信我的解决方案与语言无关。

首先 - 开发像你我一样的 SaaS 应用程序 - 为每个新客户都需要一个新实例并不是真正的最佳实践(据我所知)。由于您提到的问题 - 设置新环境并处理许多并发实例,其中包括更新或可能将它们移动到不同的服务器/基础设施。

对我来说,这个决定是由于应用程序的初始设计不好、数据设计更简单以及最终更好的安全性,因为现在可以只授予每个客户对其数据库的小子集的权限,并且没有 SQL 注入(inject)或者我这边的其他错误可以改变这一点 - 因为权限是在数据库级别强制执行的。 (你仍然可能存在错误,我完全意识到这一点)

我的解决方案:

使用docker containers 。它比传统的虚拟机轻量级,为您提供额外的抽象和安全性,例如,允许用户上传文件……此外,部署新容器相当简单且快速,因此您可以在部署后几秒钟内完成。用户已注册。

我在主机上使用 Nginx 服务器作为反向代理,它将请求转发到每个客户的相应容器。这里的问题是在更新配置文件后重新启动Nginx,而不丢失任何流量,这有点棘手。

更新应用程序也很容易,因为您只需发布新版本的镜像,停止所有正在运行的容器并使用新镜像重新启动它们。然而,要做到这一点,容器不能保存任何数据,请记住这一点。 - 这里的问题又是如何以一种用户不会注意到的方式更新它,对我来说 - 因为我的客户只在一个时区,这很容易 - 只需将其安排在凌晨 4 点,祈祷没有人疯狂到醒来并在那时工作:)

这可能无法为您提供 99,999% 的可用性,但这不是我的目标,而且为了轻松管理这些容器,这是一个很好的权衡。其他优点是 - 您可以在任何 Linux 机器上测试生产环境,并且可以将代码移动到任何您想要的地方,只需更改 Nginx 反向代理配置即可。

关于java - 软件即服务 (SaaS) 的应用程序设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26239850/

相关文章:

php - PHP 分布式开发的最佳实践

python - 是否可以在某些工作列表上运行 dask/分布式作业

java - 如何删除 JPanel 中由 ArrayList 指定的项目

node.js - 对 NodeJS 中的任何请求使用自定义 DNS 解析器

java - 实例化通用类数组

docker - 无法使用新的 1.10 DNS SD 访问容器

dns - 无法在谷歌应用程序中为 .net 域生成 DKIM 记录

database - 保持本地缓存在分布式系统中看到相同的 "version"数据的策略

java - 对集合执行模式搜索和范围搜索时使用 GWT 的 google guava2

java - 如何从键盘获取或删除 UTF-8 字符