mongodb scala_使用Scala,Spray,MongoDB,Docker和Ansible进行微服务开发

mongodb scala

本文试图提供一种构建微服务的可能方法。 我们将使用Scala作为编程语言。 API将是SprayAkka提供的RESTful JSON。 MongoDB将用作数据库。 完成所有操作后,我们会将其打包到Docker容器中。 Vagrant with Ansible将照顾我们的环境和配置管理需求。

我们将提供图书服务。 它应该能够执行以下操作:

  • 列出所有书籍
  • 检索与一本书有关的所有信息
  • 更新现有书籍
  • 删除现有书籍

本文不会尝试教有关Scala,Spray,Akka,MongoDB,Docker,Vagrant,Ansible, TDD等的所有知识。没有哪一篇文章可以做到这一点。 目的是显示开发服务时可能使用的流程和设置。 实际上,本文的大部分内容与其他类型的开发同样相关。 Docker的用途比微服务要广泛得多,Ansible和CM通常可用于任何类型的配置,而Vagrant对于快速创建虚拟机非常有用。

环境

我们将使用Ubuntu作为开发服务器。 设置服务器的最简单方法是使用Vagrant 。 如果尚未安装,请下载并安装。 您还需要Git用源代码克隆存储库。 本文的其余部分将不需要任何其他手动安装。

让我们从克隆仓库开始。

git clone https://github.com/vfarcic/books-service.git
cd books-service

接下来,我们将使用Vagrant创建一个Ubuntu服务器。 定义如下:

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.synced_folder ".", "/vagrant"
  config.vm.provision "shell", path: "bootstrap.sh"
  config.vm.provider "virtualbox" do |v|
    v.memory = 2048
  end
  config.vm.define :dev do |dev|
    dev.vm.provision :shell, inline: 'ansible-playbook /vagrant/ansible/dev.yml -c local'
  end
  config.vm.define :prod do |prod|
    prod.vm.provision :shell, inline: 'ansible-playbook /vagrant/ansible/prod.yml -c local'
  end
end

我们将盒子(OS)定义为Ubuntu。 Sync文件夹为/ vagrant,这意味着主机上当前目录内的所有内容都将作为VM中的/ vagrant目录提供。 我们将需要使用Ansible安装其余的东西,因此我们通过bootstrap.sh脚本为其配置VM。 最后,此Vagrantfile定义了两个VM: devprod 。 他们每个人都将运行Ansible,以确保所有内容均已正确安装。

使用Ansible的首选方法是将配置分为多个角色。 在我们的例子中, ansible / roles目录中有四个角色。 一个将确保已安装Scala和SBT,另一个将确保Docker已启动并正在运行,另一个将确保运行MongoDB容器。 最后一个角色(书籍)将在以后用于将我们正在构建的服务部署到生产VM。

例如,下面是mongodb角色的定义。

- name: Directory is present
  file:
    path=/data/db
    state=directory
  tags: [mongodb]

- name: Container is running
  docker:
    name=mongodb
    image=dockerfile/mongodb
    ports=27017:27017
    volumes=/data/db:/data/db
  tags: [mongodb]

对于那些曾经使用Docker的人来说,这应该是不言自明的。 该角色可确保目录存在并且mongodb容器正在运行。 我们将Playbook ansible / dev.yml捆绑在一起。

- hosts: localhost
  remote_user: vagrant
  sudo: yes
  roles:
    - scala
    - docker
    - mongodb

作为前面的示例,该示例也应该是不言自明的。 每次运行此剧本时,都会执行角色scala,docker和mongodb中的所有任务。

一般来说,Ansible和Configuration Management的好处是它们不会盲目运行脚本,而是仅在需要时才执行。 如果您第二次运行配置,Ansible将检测到一切正常,并且不执行任何操作。 另一方面,例如,如果您删除目录/ data / db ,则Ansible将检测到该目录不存在并重新创建。

让我们启动开发虚拟机 ! 第一次可能要花一些时间,因为Vagrant需要下载整个Ubuntu发行版,安装少量软件包并下载MongoDB的Docker映像。 每次下一次运行都会更快。

vagrant up dev
vagrant ssh dev
ll /vagrant

流浪汉创建一个新的VM或使现有的VM栩栩如生。 使用vagrant ssh,我们可以输入新创建的框。 最后, ll / vagrant列出该目录中的所有文件,以证明我们的所有本地文件在VM中都可用。

而已。 我们的带有Scala,SBT和MongoDB容器的开发环境已经准备就绪。 现在是时候发展我们的图书服务了。

图书服务

我爱ScalaAkka 。 Scala是一种非常强大的语言,而Akka是我最喜欢的用于构建消息驱动的JVM应用程序的框架。 虽然它是从Scala诞生的,但是Akka也可以与Java一起使用。

Spray是用于构建基于REST / HTTP的应用程序的简单但功能强大的工具包。 它是异步的,使用Akka actor,并且具有用于定义HTTP路由的出色的DSL(起初很奇怪)。

TDD方式,我们在实现之前进行测试。 这是用于检索所有书籍列表的路径测试的示例。

"GET /api/v1/books" should {

  "return OK" in {
    Get("/api/v1/books") ~> route ~> check {
      response.status must equalTo(OK)
    }
  }

  "return all books" in {
    val expected = insertBooks(3).map { book =>
      BookReduced(book._id, book.title, book.author)
    }
    Get("/api/v1/books") ~> route ~> check {
      response.entity must not equalTo None
      val books = responseAs[List[BookReduced]]
      books must haveSize(expected.size)
      books must equalTo(expected)
    }
  }

}

这些是非常基本的测试,有望显示测试基于喷雾的API应该采取的方向。 首先,我们确保路线返回代码200(确定)。 在向数据库插入少量示例书之后,第二个规范验证了是否正确检索了它们。 包含所有测试的完整源代码可以在ServiceSpec.scala中找到。

我们将如何实施这些测试? 这是基于上述测试提供实现的代码。

val route = pathPrefix("api" / "v1" / "books") {
  get {
    complete(
      collection.find().toList.map(grater[BookReduced].asObject(_))
    )
   }
}

那很简单。 我们在complete语句中定义路由/ api / v1 / booksGET方法和响应。 在这种情况下,我们将从数据库中检索所有书籍,并将它们转换为BookReduced案例类。 可以在ServiceActor.scala中找到具有所有方法(GET,PUT,DELETE)的完整源代码。

这里介绍的测试和实现都经过了简化,在现实世界中,还有更多工作要做。 实际上,复杂的路线和场景是Spray真正发亮的地方。

在开发过程中,您可以快速模式运行测试。

[在虚拟机内部]

cd /vagrant
sbt ~test-quick

每当源代码更改时,所有受影响的测试都将自动重新运行。 我倾向于始终在终端窗口中显示测试结果,并不断获得我正在处理的代码质量的反馈。

测试,构建和部署

与其他任何应用程序一样,应对此应用程序进行测试,构建和部署。

让我们使用该服务创建一个Docker容器。 创建容器所需的定义可以在Dockerfile中找到。

[在虚拟机内部]

cd /vagrant
sbt assembly
sudo docker build -t vfarcic/books-service .
sudo docker push vfarcic/books-service

我们组装JAR(测试是组装任务的一部分),构建docker容器并将其推送到Hub。 如果你打算重现这些步骤,请创建帐户hub.docker.com和变化vfarcic到您的用户名。

我们构建的容器包含运行此服务所需的一切。 它基于Ubuntu,具有JDK7,包含MongoDB的实例,并具有我们组装的JAR。 从现在开始,该容器可以在装有Docker的任何计算机上运行。 无需在服务器上安装JDK,MongoDB或任何其他依赖项。 容器是自给自足的,可以在任何地方运行。

让我们部署(运行)刚刚在其他VM中创建的容器。 这样,我们将模拟部署到生产中。

要创建部署了books服务的生产VM,请运行以下命令。

[从源目录]

vagrant halt dev
vagrant up prod

第一条命令停止开发VM。 每个需要2GB。 如果您有足够的RAM,则可能不需要停止它并可以跳过此命令。 第二个使用已部署的books服务来启动生产VM。

等待一会后,将创建新的VM,安装Ansible并运行playbook prod.yml 。 它安装Docker并运行以前构建并推送到Docker Hub的vfarcic / books-service 。 在运行时,它将公开端口8080,并与主机共享目录/ data / db

让我们尝试一下。 首先,我们应该发送PUT请求以插入一些测试数据。

curl -H 'Content-Type: application/json' -X PUT -d '{"_id": 1, "title": "My First Book", "author": "John Doe", "description": "Not a very good book"}' http://localhost:8080/api/v1/books
curl -H 'Content-Type: application/json' -X PUT -d '{"_id": 2, "title": "My Second Book", "author": "John Doe", "description": "Not a bad as the first book"}' http://localhost:8080/api/v1/books
curl -H 'Content-Type: application/json' -X PUT -d '{"_id": 3, "title": "My Third Book", "author": "John Doe", "description": "Failed writers club"}' http://localhost:8080/api/v1/books

让我们检查服务是否返回正确的数据。

curl -H 'Content-Type: application/json' http://localhost:8080/api/v1/books

我们可以删除一本书。

curl -H 'Content-Type: application/json' -X DELETE http://localhost:8080/api/v1/books/_id/3

我们可以检查已删除的书是否不再存在。

curl -H 'Content-Type: application/json' http://localhost:8080/api/v1/books

最后,我们可以要求一本特定的书。

curl -H 'Content-Type: application/json' http://localhost:8080/api/v1/books/_id/1

这是开发,构建和部署微服务的快速方法。 Docker的优点之一是,它通过将所需的依赖关系减少为零,从而简化了部署。 即使我们构建的服务需要JDK和MongoDB,也无需在目标服务器上安装它们。 一切都是作为Docker进程运行的容器的一部分。

摘要

微服务已经存在了很长时间,但是直到最近,由于尝试提供能够运行数百甚至数千个微服务的环境时出现的问题,它们并未引起足够的重视。 通过微服务获得的收益(分离,更快的开发,可伸缩性等)不如通过部署部署和配置需要付出更多努力而产生的问题大。 像Ansible这样的Docker和CM工具可以减少这种工作量几乎可以忽略不计。 由于解决了部署和配置问题,微服务因其提供的好处而逐渐流行起来。 与整体应用程序相比,开发,构建和部署时间更快。

喷雾是微服务的很好选择。 当Docker容器包含应用程序所需的所有内容时,它们会发光。 对于单个(小型)服务而言,使用大型Web服务器(如JBoss和WebSphere)将是过大的选择。 甚至不需要占用空间更小的Web服务器,例如Tomcat。 玩! 非常适合构建RESTful API。 但是,它仍然包含许多我们不需要的东西。 另一方面,喷雾只会做一件事并且做得很好。 它为RESTful API提供了异步路由功能。

我们可以继续向该服务添加更多功能。 例如,我们可以添加注册和身份验证模块。 但是,这将使我们更接近单片应用程序。 在微服务世界中,新服务将是新应用程序,在Docker新容器的情况下,每个新容器都侦听不同的端口并愉快地响应我们的HTTP请求。

构建微服务时,请尝试以一种或几种方式创建微服务。 通过将它们组合在一起来解决复杂性,而不是构建一个大型的整体应用程序。

翻译自: https://www.javacodegeeks.com/2015/01/microservices-development-with-scala-spray-mongodb-docker-and-ansible.html

mongodb scala

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值