如何使用Rust来构建微服务?

Rust是一门很棒的语言,也是我在2019年和2020年(截止当前)学的最多的语言。Rust几乎可以和任何语言互操作,同时对于容器和在Kubernetes上运行也非常友好。

今天,我想展示下如何使用Rust构建一个简单的微服务。本文中,我们将使用ActixTokio-Postgress和其他一些库,使用Postgres作为唯一数据源,同时为了便于开发,我们会将其运行在Docker容器中。另外,我还会使用自己开发的Barrel作为数据库迁移工具。代码将全部使用异步和非阻塞IO实现。

总体架构

这里我们采用多层架构,业务规则和REST请求定义在news-contract中实现。SOA约定定义在news-contract + news-service,数据结构(News)定义在news-contract。REST请求的endpoint和服务定义在news-service中。Postgres持久化相关功能定义在news-dao中。

代码结构

我们一个有5个工程,最顶层是一个全局工作空间,作为第一个工程。其余工程有:

  • news-contract:SOA约定部分,这里定义了其他工程使用的News结构体。
  • news-dao:包含响应式持久化代码,基于tokio-postgres实现对News资源的增删改查操作。
  • news-migrations:我们使用barrel和自定义逻辑来创建表结构和初始化测试数据。
  • news-service:这里我们有endpoint、服务实现和包含actix-web框架配置的入口代码。

每个工程都有自己的依赖,定义在其Cargo.toml文件中。

同时,工程中还有2个处理Docker容器的脚本,一个用于运行Postgres,另一个用于运行psql。

数据迁移

现在,让我们来看看如何实现数据迁移(在Postgres SQL中创建表和插入记录)。

首先,我们需要连接运行在Docker容器中的Postgres数据库,创建一个向量,向其中添加所有需要运行的数据迁移逻辑。然后循环执行其中的所有数据迁移逻辑,并检查结果是否正常。

现在,让我们看下一段代码,数据迁移逻辑。

我创建了一个名为NewsMigration的trait,其中包含new函数(用于创建结构体)和run函数(用于运行数据迁移)。如你所见,然后创建了CreateTableNewsMigration结构体,使用impl关键字实现了这个trait。这里我使用了barrel来创建表结构,barrel将会生成Postgres SQL的INSERT语句。最后,我们使用pg_client在Postres中运行生成的脚本。这段代码看上去很绕:&news_table[…],这里我们在传递String类型news_table的引用,将其变成slice之后,传给pg_client的execute函数。

SOA约定

首先让我们来看下约定的第一部分,News结构体。

我们定义了一个名为News的结构体,同时使用了serde和serde_json,以便于该结构体的序列化和反序列化。这个结构体还实现了Display trait,用于打印结构体内容。最后在文件的末尾有一个单元测试,用于测试结构体的打印。

Endpoint和服务

这里我定义了一个基于actix的HttpServer,然后定义了一系列处理器:index、list_news、insert_news、get_news_by_id和delete_news_by_id。服务将会运行在本地的8080端口上。所有的信息都使用log和env_logger creates进行日志记录。

现在让我们来看下endpoint.rs,这里有REST请求的定义。

这里我们使用宏来定义REST操作,例如PUT、DELETE和GET。每个函数处理器都定义成公有且非常简单,仅仅调用对应的服务,将返回结果序列化成json结构返回。

这是服务的实现,这里没有任何REST或者actix框架的依赖。这里是实现校验、业务逻辑和代理请求dao crate的地方。所有函数的增删改查操作都是异步的。

DAO

这里是魔法发生的地方,我们使用了tokio-postgress库。先来看下代码。

这是DAO层的实现。这里有一个名为connect()的函数用于连接Postgres数据库,它使用异步非阻塞的方式实现。然后展示的是如何实现find_by_id功能。在Postgres中ID使用UUID来生成,因此需要将其转成字符串类型,这就是为什么代码中会看见id::text=$1。同样在这一行中,我将从入参获取到的ID转换成了&[&id]传入。DAO层还有很多函数,有兴趣的话可以在我的GitHub上查看完整代码

视频:代码走读和功能演示

https://vimeo.com/384505355

完整代码:

https://github.com/diegopacheco/rust-playground/tree/master/rust-microservice

原文链接:

http://diego-pacheco.blogspot.com/2020/01/building-microservice-with-rust.html

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/zcfz4elwwJk5PtpeD9iZ
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券