Эта запись в блоге - одна из серии, посвященной использованию действий Docker в OpenWhisk для поддержки дополнительных сред выполнения.

Давайте посмотрим на написание бессерверных функций для OpenWhisk с использованием Rust.

Rust - это язык системного программирования, который работает невероятно быстро, предотвращает сбои и гарантирует безопасность потоков.

Популярность Rust растет с момента его запуска в 2010 году. Rust - популярный язык для написания микросервисов из-за акцента на безопасности и сильной поддержке параллелизма.

На данный момент ни одна из основных бессерверных платформ не поддерживает Rust. OpenWhisk не включает это как среду выполнения по умолчанию. Однако недавние обновления OpenWhisk предоставляют возможность для написания бессерверных функций с помощью Rust.

Давайте перепишем пример из предыдущего поста на Rust и посмотрим, как запустить его, используя этот новый подход ...

Вы видели этот пост, в котором объясняется, как работают действия на основе Docker? Предполагается, что вы уже прочитали это сообщение в первую очередь.

Действия на языке Rust

Rust имеет систему сборки, которая поддерживает создание статических двоичных файлов. Эти двоичные файлы содержат исходный код приложения и зависимые библиотеки.

Используя тот же подход, что и в примере на Go, объединение этого двоичного файла в zip-файл позволяет нам перезаписать заглушку времени выполнения перед вызовом.

Исполняемые двоичные файлы будут выполняться вызывающим на основе Python для каждого вызова. Параметры запроса будут переданы в виде строки JSON с использованием первого аргумента командной строки. Вызывающий ожидает, что результат действия будет записан в стандартный вывод в виде строки JSON.

Исходный код действия

Вот простая функция Rust, которая возвращает строку приветствия из входного параметра. Он анализирует строку JSON, указанную в командной строке, для поиска параметра name. Если его нет, по умолчанию используется stranger. Он возвращает объект JSON со строкой приветствия (msg) путем записи в консоль.

Настроить проект

Используя инструмент управления пакетами Rust, создайте новый проект для нашей бессерверной функции.

Добавьте приведенный выше исходный код в src/main.rs файл.

$ cargo new action; cd action      
Created library `action` project 
$ mv src/lib.rs src/main.rs 
$ vim src/main.rs 
$ tree . 
. 
├── Cargo.toml 
└── src     
└── main.rs  
1 directory, 2 files

Эта функция использует ящик rustc-serialize для обработки и создания JSON.

Добавьте этот идентификатор к зависимостям проекта, перечисленным в Cargo.toml.

Скомпилируйте и запустите двоичный файл, чтобы проверить, работает ли он должным образом.

$ cargo run     
Updating registry `https://github.com/rust-lang/crates.io-index`    Compiling rustc-serialize v0.3.22    
Compiling action v0.1.0 (file:///private/tmp/test/action)     Finished debug [unoptimized + debuginfo] target(s) in 7.0 secs      Running `target/debug/action` 
{"message":"Hello, stranger!"} 
$ cargo run '{"name": "James"}'     
Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs      Running `target/debug/action {\"name\":\ \"James\"}` {"message":"Hello, James!"}

Прежде чем мы сможем развернуть этот двоичный файл в OpenWhisk, он должен быть скомпилирован для архитектуры платформы.

Кросс-компиляция локально

Компилятор Rust внутренне использует LLVM, что позволяет генерировать машинный код для различных архитектур. Кросс-компиляция для разных платформ требует установки правильного компилятора, компоновщика и библиотек для этой архитектуры.

Rust недавно выпустил менеджер цепочки инструментов, чтобы упростить этот процесс.

Установите набор инструментов Rust для x86_64-unknown-linux-musl среды выполнения.

$ rustup target add x86_64-unknown-linux-musl 
info: downloading component 'rust-std' for 'x86_64-unknown-linux-musl' 
info: installing component 'rust-std' for 'x86_64-unknown-linux-musl'

Добавьте файл конфигурации, чтобы установить правильный компоновщик для среды выполнения.

$ cat .cargo/config 
[target.x86_64-unknown-linux-musl] 
linker = "x86_64-linux-musl-gcc"

Теперь мы можем скомпилировать двоичный файл для правильной среды.

$ cargo build --target=x86_64-unknown-linux-musl --release    Compiling rustc-serialize v0.3.22  
Compiling action v0.1.0 (file:///Users/james/code/bluemix/openwhisk-languages/rust/action)  
Finished release [optimized] target(s) in 9.30 secs

Проверка типа файла показывает, что мы создали статический двоичный файл для платформы Linux x86_64.

$ file target/x86_64-unknown-linux-musl/release/action target/x86_64-unknown-linux-musl/release/action: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, not stripped

Кросс-компиляция с использованием Docker

Если вы не хотите устанавливать набор инструментов разработки Rust, можно использовать Docker для запуска контейнера с настроенной средой.

$ docker pull ekidd/rust-musl-builder 
$ docker run -it -v $(pwd):/home/rust/src ekidd/rust-musl-builder cargo build --release  
Updating registry `https://github.com/rust-lang/crates.io-index`  Downloading rustc-serialize v0.3.22  
Compiling action v0.1.0 (file:///home/rust/src)  
Finished release [optimized] target(s) in 1.80 secs 
$ file target/x86_64-unknown-linux-musl/release/action target/x86_64-unknown-linux-musl/release/action: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, not stripped

Создать и развернуть архив

Добавьте двоичный файл в zip-файл, убедившись, что файл имеет имя exec в архиве.

Используйте wsk командную строку, чтобы создать новое действие Docker с использованием этого архива.

$ cp target/x86_64-unknown-linux-musl/release/action exec 
$ zip action.zip exec  
adding: exec (deflated 64%) 
$ wsk action create rust_test action.zip --docker 
ok: created action rust_test

Вызов действия

Протестируйте действие из командной строки, чтобы убедиться, что оно работает.

$ wsk action invoke rust_test --blocking --result 
{  "msg": "Hello, Stranger!" } 
$ wsk action invoke rust_test --blocking --result --param name James 
{  "msg": "Hello, James!" }

Успех 😎.