完整 Web 应用教程
这是一篇快速的通用教程,帮助你理解一个包含多个组件的应用应该如何进行架构设计。
假设我们要做一个网页版的 HOTDOG or NOT HOTDOG!
应用描述
假设我们要创建一个 Web 应用:展示一组照片列表,并在每张照片旁用一行文字说明它是不是 hotdog,类似这样:
<IMAGE>标签:Hotdog,上传日期:2017-11-12<ANOTHER IMAGE>标签:NOT Hotdog,上传日期:2017-07-08<ANOTHER IMAGE>标签:Hotdog,上传日期:2017-07-07- ....
任何人都可以上传图片;我们非常聪明的人工智能会给这张图片打上 HOTDOG 或 NOT-HOTDOG 的标签;然后我们把图片保存到服务器上,同时把上传日期和标签等信息保存到数据库里。
应用架构
为了实现这个应用,假设我们决定采用以下组件:
- NodeJS WebApp:(包含静态资源、前端应用和 API)
- PHP 图片上传应用:我们可以向它发起 POST 请求,将照片保存到磁盘
- MongoDB:用于存储上传信息(标签、上传日期等)
- PYTHON 图像识别服务:我们可以向它发起 POST 请求,判断图片是 HOTDOG 还是 NOT HOTDOG
+---------------------+
| |
| NodeJS Webapp |
| |
+---------------+------------+--------+-----------------+
| | |
| | |
| | |
| | |
| | |
+-------v-----------+ +----------v----------+ +-----------v---+
| | | | | |
| PHP File Uploader | | Python ImageDetector| | MongoDB |
| | | | | |
+-------------------+ +---------------------+ +---------------+是否需要持久化
CapRover 允许你标记你的 app/database/service 是否包含持久化数据。有持久化需求的应用可以配置“持久化目录(persistent directories)”。当应用崩溃并且 Captain 启动该应用的新实例时,这些目录会被保留。其他所有目录在应用崩溃并由 Captain 启动新实例后都会被清空并重置为默认状态。在我们的例子里:
- WebApp:不需要任何持久化。
- 图片上传应用:需要一个持久化目录,用于把图片保存在磁盘上(例如
/uploaded_files)。 - MongoDB:当然需要持久化(我们在这里存储信息)。我们不希望仅仅因为 MongoDB 崩溃或服务器重启就丢失数据库。
- PYTHON 图像识别应用:不需要在磁盘上保存任何数据。它只是接收图片,做一些图像处理,然后把结果返回给客户端(HOTDOG 或 NOT HOTDOG)。
创建服务:
- NodeJS Web 应用:写完这个应用后,在 Captain 上创建一个 Web 应用,命名为
my-webapp;不要勾选持久化复选框,然后部署应用。 - 图片上传应用:与上面的 Web 应用类似,但创建应用时需要勾选持久化复选框。将该应用命名为
image-uploader。随后进入应用详情页添加一个持久化目录;目录路径是你的应用存储图片的位置,这取决于你的应用实现。在我们的例子里,假设是/uploaded_files。 - MongoDB:使用一键应用安装器创建一个 MongoDB 实例,把这个容器命名为
my-mongodb。容器(数据库)创建完成后,进入详情页你会看到 Captain 自动为该容器分配了一些持久化目录,这些目录就是 MongoDB 保存数据的位置。 - Python 图像识别应用:同样在 Captain 上创建一个新应用。由于它不在磁盘上保存任何信息,不需要设置持久化。将该应用命名为
image-processor。
内部访问
为了让你的 Web 应用正常工作,它需要能够与 MongoDB 实例、图片上传服务、图像识别服务进行通信。如果你想从一个容器访问另一个容器,只需要在容器名之前加上 srv-captain-- 前缀即可。例如,要连接我们命名为 my-mongodb 的 MongoDB 实例,你可以在 NodeJS 应用里(使用 mongoose 库)添加如下代码:
mongoose.connect("mongodb://srv-captain--my-mongodb/mydatabase", { useMongoClient: true });当然,你也可以在 URI 中加入用户名和密码,例如参考这里。
其他服务也同理;如果你想把图片上传到图片上传服务,只需要通过 http://srv-captain--imageuploader 访问它即可。