代码级干货 | 如何利用Docker与Rails API gem构建微服务

美好的一周又到了收尾的一天,今天小数给大家带来的是一篇代码级干货文章,与大家分享一些利用Rails API以微服务形式设置应用的经验与心得。

为何选择Docker加Rails API?

在我效力的企业中,我们一直在利用Docker为全部工程师构建开发环境。在这种情况下,新人加入后能够快速拥有与之对应的容器工作环境。与大多数长久使用整体应用的企业一样,我们同样希望充分发挥微服务架构带来的松散耦合、高紧凑性与独立部署等固有优势。

我曾经利用Rails作为API构建过几款应用——坦率地讲,这种作法有点矫枉过正,因为我们其实没必要使用其中的全部视图逻辑与额外中间件。Rails API gem集成于Rails 5版本当中,此版本目前处于beta测试阶段。我曾经打算利用Docker完成上述工作,但却在设置过程中遇到了困难,所以在今天的文章中,我将利用Rails 4完成设置并将rails-api gem作为关联性添加至Gemfile当中。

大家可能会问,为什么要将Rails API作为微服务架构中的技术堆栈。我认为具体答案取决于技术团队的实际专长方向。互联网上曾经就要不要投身微服务以及应该具体使用哪些技术产生过激烈的争论。可以看到,很多朋友利用Node.js、Go、Scala或者Java等其它卓越技术完成了任务。我曾经拿出过一段时间体验这些方案,也认同它们的出色表现,但我所的在团队更熟悉Rails。因此出于快速开发的考量,我们做出了这样的决定。如果非要再选一种潜在方案,我个人更倾向于Node.js,因为我们的很多新应用都以其为基础构建而成。在我看来,这一转型项目的最终目标在于确保每项服务都拥有小巧的体积,从而能够在必要时实现轻松重写。

从Docker起步

设置工作

今天的教程面向Mac用户,但大家也可以在Linux发行版或者Windows平台上实现类似的操作。首先在终端中为项目创建一个目录。我将把项目命名为“inventory manager”,但大家也可以随意选择自己喜欢的名称。

接下来在项目root目录下创建几个文件。

设置 Dockerfile

Dockerfile负责容纳我们Docker容器环境的全部设置。

那么我们该在文件中添加怎样的内容?在这里我们利用Ruby的最新版本(2.3.0)创建一套镜像,而后在该容器上运行apt软件包管理命令。我们将利用MySQL客户端库进行开发。此后,我们将把本地Gemfile与Gemfile.lock添加至容器的文件系统当中,再安装其关联性。最后,我们将项目目录内的全部内容添加至容器内。

设置 docker-compose.yml

我们需要设置docker-compose.yml文件,从而确保Docker Compose工具能够对Rails API应用及我们的MySQL容器间的通信进行编排。

这套配置建立起一套mysql容器,外加一套由Dockerfile构建而成的名为web的容器,后者在端口9292上运行Puma webserver。接下来,我们可以将这一Rails应用容器连接至mysql容器,从而保证二者能够彼此通信。

设置 Gemfile

在Gemfile当中,我们将添加Rails gem、Rails API gem、mysql客户端适配器、Puma webserver以及Active Model Serializers(用于JSON格式的响应信息)。

创建Docker镜像

现在进行Docker镜像的创建。

运行Docker build命令,从而利用Dockerfile构建镜像并安装gem。 Docker镜像已经成功创建完成

一旦Gemfile或者Dockerfile内容出现变更,大家将需要再次运行这条命令以重构Docker镜像。大家可以利用以下命令查看已经创建的镜像:

创建Rails API应用结构

接下来,我们在Docker镜像中运行Rails API命令以创建应用结构。在我们的 docker-compose.yml文件内,将“web”作为命令执行的目标容器。

创建Rails API应用结构

设置数据库

现在需要对database.yml文件进行设置,完成后即可进行数据迁移。

主机为“db”,我们已经在docker-compose.yml file文件中定义了该名称。这一主机值必须与我们在docker-compose.yml文件中定义的数据库容器保持一致。

测试Web应用的运行情况

现在应用结构已经构建完成,下面运行Web服务器以检查能够正常查看Rails状态页面。

在各自容器中运行数据库与Web应用,而后运行Puma server以监听端口9292

我的docker-machine ip运行在端口192.168.59.100上。大家应确保运行docker-machine ip以找到正确的docker ip(本示例直接使用docker ip作为别名)。

下一步

现在我们的应用已经开始正常运行,以此为基础大家可以随意创建数据模型以及控制器等等。

我们可以通过这种方式创建更多微服务,并确保不同应用之间利用JSON通过http经由同一Docker主机的不同web服务器端口实现彼此通信。我们也可以使用消息收发机制实现不同服务间的通信,例如RabbitMQ。

原文作者:Charles Wang