Русский
Русский
English
Статистика
Реклама

Yandex cloud

Пишем full stack монолит с помощью Angular Universal NestJS PostgreSQL

10.08.2020 02:14:34 | Автор: admin
Привет, Хабр!

В этой статье мы создадим готовый шаблон-монолит, который можно брать за основу нового fullstack приложения как скелет для навешивания функционала.


Эта статья будет полезна, если вы:


  • Начинающий fullstack-разработчик;
  • Стартапер, который пишет MVP чтобы проверить гипотезу.

Почему выбрал такой стек:


  • Angular: имею много опыта в нем, люблю строгую архитектуру и Typescript из коробки, выходец из .NET
  • NestJS: тот-же язык, та-же архитектура, быстрое написание REST API, возможность в дальнейшем пересесть на Serverless (дешевле виртуалки)
  • PostgreSQL: Собираюсь хоститься в Яндекс.Облаке, на минималках дешевле на 30% чем MongoDB

Прайс яндекса


Прежде чем написать статью, поискал на хабре статьи про подобный кейс, нашел следующее:



Из этого ничего не описывает "скопировал и вставил" или дает ссылки на то что еще нужно дорабатывать.


Оглавление:


1. Создаем Angular приложение и добавляем библиотеку компонентов ng-zorro
2. Устанавливаем NestJS и решаем проблемы с SSR
3. Делаем API на NestJS и подключаем к фронту
4. Подключаем базу данных PostgreSQL



1. Создаем Angular приложение


Установим Angular-CLI чтобы создавать SPA-сайты на Ангуляре:


npm install -g @angular/cli

Создадим Angular приложение с помощью следующей команды:


ng new angular-habr-nestjs

Далее переходим в папку приложения и запускаем, чтобы проверить работоспособность:


cd angular-habr-nestjsng serve --open

Статическое SPA-приложение на Angular


Приложение создалось. Подключаем библиотеку NG-Zorro:


ng add ng-zorro-antd

Далее выбираем следующие конфигурации библиотеки:


? Enable icon dynamic loading [ Detail: https://ng.ant.design/components/icon/en ] Yes? Set up custom theme file [ Detail: https://ng.ant.design/docs/customize-theme/en ] No? Choose your locale code: ru_RU? Choose template to create project: sidemenu

Эта конфигурация заменит содержимое app.component на дизайн с менюшкой слева, футером и хедером и подключит локализацию на русском языке:


Подключили NG-Zorro


В данной статье мы отобразим список данных для наглядности, поэтому добавим простенькую табличку в компоненте src/app/pages/welcome, который сгенерил NG-Zorro:
Пример взят отсюда:
https://ng.ant.design/components/table/en


// welcome.component.html<nz-table #basicTable [nzData]="items$ | async"> <thead> <tr>  <th>Name</th>  <th>Age</th>  <th>Address</th> </tr> </thead> <tbody> <tr *ngFor="let data of basicTable.data">  <td>{{ data.name }}</td>  <td>{{ data.age }}</td>  <td>{{ data.address }}</td> </tr> </tbody></nz-table>

// welcome.module.tsimport { NgModule } from '@angular/core';import { WelcomeRoutingModule } from './welcome-routing.module';import { WelcomeComponent } from './welcome.component';import { NzTableModule } from 'ng-zorro-antd';import { CommonModule } from '@angular/common';@NgModule({ imports: [  WelcomeRoutingModule,  NzTableModule, // Добавили для таблицы  CommonModule // Добавили для пайпа async ], declarations: [WelcomeComponent], exports: [WelcomeComponent]})export class WelcomeModule {}

// welcome.component.tsimport { Component, OnInit } from '@angular/core';import { Observable, of } from 'rxjs';import { HttpClient } from '@angular/common/http';import { share } from 'rxjs/operators';@Component({ selector: 'app-welcome', templateUrl: './welcome.component.html', styleUrls: ['./welcome.component.scss']})export class WelcomeComponent implements OnInit { items$: Observable<Item[]> = of([  {name: 'Вася', age: 24, address: 'Москва'},  {name: 'Петя', age: 23, address: 'Лондон'},  {name: 'Миша', age: 21, address: 'Париж'},  {name: 'Вова', age: 23, address: 'Сидней'} ]); constructor(private http: HttpClient) { } ngOnInit() { } // Сразу напишем метод к бэку, понадобится позже getItems(): Observable<Item[]> {  return this.http.get<Item[]>('/api/items').pipe(share()); }}interface Item { name: string; age: number; address: string;}

Получилось следующее:


Табличка NG-Zorro



2. Устанавливаем NestJS


Далее установим NestJS таким образом, чтобы он предоставил Angular Universal (Server Side Rendering) из коробки и напишем пару ендпоинтов.


ng add @nestjs/ng-universal

После установки, запускаем наш SSR с помощью команды:


npm run serve

И вот уже первый косяк :) У нас появляется следующая ошибка:


TypeError: Cannot read property 'indexOf' of undefined  at D:\Projects\angular-habr-nestjs\node_modules\@nestjs\ng-universal\dist\utils\setup-universal.utils.js:35:43  at D:\Projects\angular-habr-nestjs\dist\server\main.js:107572:13  at View.engine (D:\Projects\angular-habr-nestjs\node_modules\@nestjs\ng-universal\dist\utils\setup-universal.utils.js:30:11)  at View.render (D:\Projects\angular-habr-nestjs\node_modules\express\lib\view.js:135:8)  at tryRender (D:\Projects\angular-habr-nestjs\node_modules\express\lib\application.js:640:10)  at Function.render (D:\Projects\angular-habr-nestjs\node_modules\express\lib\application.js:592:3)  at ServerResponse.render (D:\Projects\angular-habr-nestjs\node_modules\express\lib\response.js:1012:7)  at D:\Projects\angular-habr-nestjs\node_modules\@nestjs\ng-universal\dist\angular-universal.module.js:60:66  at Layer.handle [as handle_request] (D:\Projects\angular-habr-nestjs\node_modules\express\lib\router\layer.js:95:5)  at next (D:\Projects\angular-habr-nestjs\node_modules\express\lib\router\route.js:137:13)

Чтобы решить косяк, зайдем в файл server/app.module.ts и поменяем значение liveReload на false:


import { Module } from '@nestjs/common';import { AngularUniversalModule } from '@nestjs/ng-universal';import { join } from 'path';@Module({ imports: [  AngularUniversalModule.forRoot({   viewsPath: join(process.cwd(), 'dist/browser'),   bundle: require('../server/main'),   liveReload: false  }) ]})export class ApplicationModule {}

Также подтюним конфиг тайпскрипта, так-как эта конфигурация не взлетает с использованием Ivy рендера:


// tsconfig.server.json{ "extends": "./tsconfig.app.json", "compilerOptions": {  "outDir": "./out-tsc/server",  "target": "es2016",  "types": [   "node"  ] }, "files": [  "src/main.server.ts" ], "angularCompilerOptions": {  "enableIvy": false, // Добавили флажок  "entryModule": "./src/app/app.server.module#AppServerModule" }}

После пересоберем приложение командой ng run serve чтобы SSR заработал.


Angular SSR + NestJS


Ура! SSR подрубился, но как видимо в devtools он приходит с кривыми стилями.


Добавим extractCss: true, который позволит выносить стили не в styles.js, а в styles.css:


// angular.json..."architect": {    "build": {     "builder": "@angular-devkit/build-angular:browser",     "options": {      "outputPath": "dist/browser",      "index": "src/index.html",      "main": "src/main.ts",      "polyfills": "src/polyfills.ts",      "tsConfig": "tsconfig.app.json",      "aot": true,      "assets": [       "src/favicon.ico",       "src/assets",       {        "glob": "**/*",        "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/",        "output": "/assets/"       }      ],      "extractCss": true, // Добавили флажок      "styles": [       "./node_modules/ng-zorro-antd/ng-zorro-antd.min.css",       "src/styles.scss"      ],      "scripts": []     },...

Также подключим стили библиотеки в app.component.scss:


// app.component.scss@import "~ng-zorro-antd/ng-zorro-antd.min.css"; // Подключили стили:host { display: flex; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;}.app-layout { height: 100vh;}...

Теперь стили подключены, SSR отдает страничку со стилями, но мы видим что сначала у нас грузится SSR, потом страница моргает и отрисовывается CSR (Client Side Rendering). Это решается следующим способом:


import { NgModule } from '@angular/core';import { Routes, RouterModule } from '@angular/router';const routes: Routes = [ { path: '', pathMatch: 'full', redirectTo: '/welcome' }, { path: 'welcome', loadChildren: () => import('./pages/welcome/welcome.module').then(m => m.WelcomeModule) }];@NgModule({ imports: [RouterModule.forRoot(routes, {initialNavigation: 'enabled', scrollPositionRestoration: 'enabled'})], // Добавили initialNavigation, scrollPositionRestoration exports: [RouterModule]})export class AppRoutingModule { }

  • initialNavigation: 'enabled' дает инструкцию роутингу не отрисовывать страницу, если уже загружена через SSR
  • scrollPositionRestoration: 'enabled' скролит страницу наверх при каждом роутинге.


3. Сделаем пару ендпоинтов на NestJS


Перейдем в папку server и создадим первый контроллер items:


cd servernest g module itemsnest g controller items --no-spec

// items.module.tsimport { Module } from '@nestjs/common';import { ItemsController } from './items.controller';@Module({ controllers: [ItemsController]})export class ItemsModule {}

// items.controller.tsimport { Controller } from '@nestjs/common';@Controller('items')export class ItemsController {}

Контроллер и модуль создались. Создадим метод на получение списка items и на добавление объекта в список:


// server/src/items/items.controller.tsimport { Body, Controller, Get, Post } from '@nestjs/common';class Item { name: string; age: number; address: string;}@Controller('items')export class ItemsController { // для простоты данные взял из Angular private items: Item[] = [  {name: 'Вася', age: 24, address: 'Москва'},  {name: 'Петя', age: 23, address: 'Лондон'},  {name: 'Миша', age: 21, address: 'Париж'},  {name: 'Вова', age: 23, address: 'Сидней'} ]; @Get() getAll(): Item[] {  return this.items; } @Post() create(@Body() newItem: Item): void {  this.items.push(newItem); }}

Попробуем вызвать GET в Postman:


GET запросы апишки NestJS


Отлично, работает! Обратите внимание, вызываем метод GET items с префиксом api, который ставится автоматически в файле server/main.ts при установке NestJS:


// server/main.tsimport { NestFactory } from '@nestjs/core';import { ApplicationModule } from './app.module';async function bootstrap() { const app = await NestFactory.create(ApplicationModule); app.setGlobalPrefix('api'); // Это префикс await app.listen(4200);}bootstrap();

Теперь прикрутим бэк к фронту. Возвращаемся к файлу welcome.component.ts и делаем запрос списка к бэку:


// welcome.component.tsimport { Component, OnInit } from '@angular/core';import { Observable, of } from 'rxjs';import { HttpClient } from '@angular/common/http';import { share } from 'rxjs/operators';@Component({ selector: 'app-welcome', templateUrl: './welcome.component.html', styleUrls: ['./welcome.component.scss']})export class WelcomeComponent implements OnInit { items$: Observable<Item[]> = this.getItems(); // прикрутили вызов бэка constructor(private http: HttpClient) { } ngOnInit() { } getItems(): Observable<Item[]> {  return this.http.get<Item[]>('/api/items').pipe(share()); }}interface Item { name: string; age: number; address: string;}

Можно увидеть что апиха на фронте дергается, но также дергается и в SSR, причем с ошибкой:


Дергание апихи в SSR


Ошибка при запросе в SSR решается следующим способом:


// welcome.component.tsimport { Component, OnInit } from '@angular/core';import { Observable, of } from 'rxjs';import { HttpClient } from '@angular/common/http';import { share } from 'rxjs/operators';@Component({ selector: 'app-welcome', templateUrl: './welcome.component.html', styleUrls: ['./welcome.component.scss']})export class WelcomeComponent implements OnInit { items$: Observable<Item[]> = this.getItems(); // прикрутили вызов бэка constructor(private http: HttpClient) { } ngOnInit() { } getItems(): Observable<Item[]> {  return this.http.get<Item[]>('http://localhost:4200/api/items').pipe(share()); // Прописали полный путь к апихе чтобы SSR не ругался }}interface Item { name: string; age: number; address: string;}

Чтобы исключить двойной запрос к апихе (один на SSR, другой на фронте), нужно проделать следующее:


  • Установим библиотеку @nguniversal/common:

npm i @nguniversal/common

  • В файле app/app.module.ts добавим модуль для запросов из SSR:

// app.module.tsimport { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { AppRoutingModule } from './app-routing.module';import { AppComponent } from './app.component';import { IconsProviderModule } from './icons-provider.module';import { NzLayoutModule } from 'ng-zorro-antd/layout';import { NzMenuModule } from 'ng-zorro-antd/menu';import { FormsModule } from '@angular/forms';import { HttpClientModule } from '@angular/common/http';import { BrowserAnimationsModule } from '@angular/platform-browser/animations';import { NZ_I18N } from 'ng-zorro-antd/i18n';import { ru_RU } from 'ng-zorro-antd/i18n';import { registerLocaleData } from '@angular/common';import ru from '@angular/common/locales/ru';import {TransferHttpCacheModule} from '@nguniversal/common';registerLocaleData(ru);@NgModule({ declarations: [  AppComponent ], imports: [  BrowserModule.withServerTransition({ appId: 'serverApp' }),  TransferHttpCacheModule, // Добавили  AppRoutingModule,  IconsProviderModule,  NzLayoutModule,  NzMenuModule,  FormsModule,  HttpClientModule,  BrowserAnimationsModule ], providers: [{ provide: NZ_I18N, useValue: ru_RU }], bootstrap: [AppComponent]})export class AppModule { }

Схожую операцию проделаем с app.server.module.ts:


// app.server.module.tsimport { NgModule } from '@angular/core';import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';import { AppModule } from './app.module';import { AppComponent } from './app.component';@NgModule({ imports: [  AppModule,  ServerModule,  ServerTransferStateModule, // Добавили ], bootstrap: [AppComponent],})export class AppServerModule {}

Хорошо. Теперь получаем данные из апи в SSR, отрисовываем на форме, отдаем на фронт и тот не делает повторных запросов.


Запроса нет, данные есть!



4. Подключим базу PostgreSQL


Подключим библиотеки для работы с PostgreSQL, также будем использовать TypeORM для работы с базой:


npm i pg typeorm @nestjs/typeorm

Внимание: у вас уже должна быть установлена PostgreSQL с базой внутри.


Описываем конфиг подключения к базе в server/app.module.ts:


// server/app.module.tsimport { Module } from '@nestjs/common';import { AngularUniversalModule } from '@nestjs/ng-universal';import { join } from 'path';import { ItemsController } from './src/items/items.controller';import { TypeOrmModule } from '@nestjs/typeorm';@Module({ imports: [  AngularUniversalModule.forRoot({   viewsPath: join(process.cwd(), 'dist/browser'),   bundle: require('../server/main'),   liveReload: false  }),  TypeOrmModule.forRoot({ // Конфиг подключения к базе   type: 'postgres',   host: 'localhost',   port: 5432,   username: 'postgres',   password: 'admin',   database: 'postgres',   entities: ['dist/**/*.entity{.ts,.js}'],   synchronize: true  }) ], controllers: [ItemsController]})export class ApplicationModule {}

Немного про поля конфига:


  • type: указываем название типа базы данных, к которой подключаемся
  • host и port: место где база хостится
  • username и password: аккаунт для этой базы
  • database: название базы
  • entities: путь, откуда будем брать сущности для схемы нашей базы

По последнему пункту, нужно создать сущность Item для мапинга полей в базу:


// server/src/items/item.entity.tsimport { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn } from 'typeorm/index';@Entity()export class ItemEntity { @PrimaryGeneratedColumn() id: number; @CreateDateColumn() createDate: string; @Column() name: string; @Column() age: number; @Column() address: string;}

Далее свяжем эту сущность с нашей базой.


// items.module.tsimport { Module } from '@nestjs/common';import { TypeOrmModule } from '@nestjs/typeorm';import { ItemEntity } from './item.entity';import { ItemsController } from './items.controller';@Module({ imports: [  TypeOrmModule.forFeature([ItemEntity]) // Подключаем фича-модуль и указываем сущности базы ], controllers: [ItemsController]})export class ItemsModule {}

Теперь укажем в контроллере, что хотим работать с базой, а не кешем:


// items.controller.tsimport { Body, Controller, Get, Post } from '@nestjs/common';import { ItemEntity } from './item.entity';import { InjectRepository } from '@nestjs/typeorm';import { Repository } from 'typeorm/index';interface Item { name: string; age: number; address: string;}@Controller('items')export class ItemsController { constructor(@InjectRepository(ItemEntity)       private readonly itemsRepository: Repository<ItemEntity>) { // Подключили репозиторий } @Get() getAll(): Promise<Item[]> {  return this.itemsRepository.find(); } @Post() create(@Body() newItem: Item): Promise<Item> {  const item = this.itemsRepository.create(newItem);  return this.itemsRepository.save(item); }}

Проверим работу апихи в Postman:


POST к апихе с базой


Работает. Потыкали несколько раз постман, посмотрим что записалось в базе с помощью DBeaver:


Записи в базе


Отлично! В базе есть, посмотрим как выглядит на фронте:


Рабочее fullstack приложение


Готово! Мы сделали fullstack приложение, с которым можно работать дальше.


P.S. Сразу поясню следующее:


  • Вместо Ng-Zorro вы можете использовать любую другую библиотеку, например Angular Material. Мне она лично не зашла из-за сложности разработки;
  • Я знаю, что нужно на бэке использовать сервисы, а не напрямую дергать базу в контроллерах. Эта статья о том, как решив проблемы "влоб" получить MVP с которым можно работать, а не про архитектуру и паттерны;
  • Вместо вписывания на фронте http://localhost:4200/api возможно лучше написать интерсептор и проверять откуда мы стучимся

Полезные ссылки:


Подробнее..

Почему в AWS все так сложно с прайсом и правами? Как избежать политических блокировок и защитить данные в облаке?

10.03.2021 14:15:34 | Автор: admin


Публикуем сессию вопросов и ответов о работе с AWS и другими cloud-провайдерами. Сессия прошла в рамках вебинара Создание эффективной инфраструктуры при помощи облачных решений. На Youtube есть запись вебинара, а в блоге мы уже размещали текстовую расшифровку доклада.


Спикер вебинара Александр Волочнев (Developer Advocate в DataStax Inc.) и Всеволод Севастьянов (TechLead в vene.io) ответили на вопросы о прайсе и правах в AWS, рассказали, как защитить данные и в каких ситуациях лучше выбрать российских облачных провайдеров.


Зачем Openstack от %anyvendor% если есть открытая ванильная версия, разрабатываемая огромным количеством талантливых разработчиков?


Всеволод Севастьянов: Вопрос классный, если уточнить, что такое Openstack, так как есть 15 компаний, которые контрибьютят своих разработчиков на разработку непосредственно самого Openstack (HP, IBM и др.). И то, что они себе устанавливают, это по сути есть Openstack для их клауда с какими-то обертками, свистелками от непосредственно самих вендоров. Что выбирать для себя? Вопрос. Если вы берете Openstack, чтобы поставить на свои сервера, берите Openstack, если вам ничего сверху не надо. Если вы будете работать с HP-шными железками или с вещами, которые они вам предоставляют для облачных вычислений, для нейросетей или для коннекшена к облаку самого HP, берите HP-шный Openstack.


Александр Волочнев: Тут я должен сделать шаг в сторону и сказать, что не все знают, что такое Openstack, у нас вебинар для начинающих разработчиков. Openstack это возможность самому сделать свое собственное облако, то есть это такая система управления всяким железом и всем остальным, где с одной стороны сидите вы сами и запихиваете новые сервера, а с другой стороны люди пользуются этим как облаком. Обычно это для больших компаний актуально, где есть отдел, который делает все то же самое, что делает AWS, и есть отдел, который это все обеспечивает. То есть это такое домашнее облако, и есть несколько его поставщиков. Хороший вопрос, на который сложно однозначно ответить. Это как есть Linux Kernel, есть Ubuntu. Несколько холиварная тема, которую я пока что закрываю.


Почему в AWS все так сложно с прайсом? Сложно понять, сколько в итоге будет стоить проект?


Александр: Сложно, потому что AWS это система, которую инженеры создавали для инженеров. А когда инженеры берутся разрабатывать какую-то систему, они думают о том, чтобы все было технически правильно, а не просто. Большой проект иногда бывает проще разработать и внедрить, чем просчитать. Потому что AWS пошло по пути сверхточного вычисления, плюс у каждого сервиса есть отдельные классы, например, у сервиса хранения Simple Storage есть несколько классов хранения файлов. На одном классе хранения файлов у вас файлы будут храниться чуть подороже, но с вас не будут браться деньги, когда их кто-то скачивает, на других классах файлы будут храниться подешевле, но с вас будут браться деньги, когда их кто-то скачивает, причем первые 100 Гб с вас будут брать одну сумму, последующие 100 Гб с вас будут брать другую сумму. При этом, чтобы окончательно всех запутать, есть еще Intelligent Tiering, когда у вас файлы будут прыгать между слоями в зависимости тот того, как будет вам выгоднее, по мнению AWS.


И это я только про хранение файлов говорю в одной конкретной корзине. Если мы говорим про AWS Lambda, бессерверные приложения, там тоже красиво, потому что отдельно считается время, отдельно считаются запуски и отдельно считается потребление памяти в Гб/мс. На самом деле они хотели как лучше. Они хотели предоставить вам оплату потребления только того, что вы действительно потребили. Но поскольку они отдельно считают коннекшены, отдельно потребление, отдельно то-се, пятое-десятое Когда считаете какой-то проект, во-первых, посчитайте, что тарифицируется. Надо учитывать нюансы. Если вы, например, храните маленький файл в их AWS S3 Glacier, ледник служба длительного хранения файлов на магнитных лентах, самое дешевое хранилище, но не самое быстрое, надо учитывать, что там минимальный размер файла считается 100 с чем-то Кб, то есть надо учитывать, что если вы туда положили файл в 1 Кб, платить вы будете как за 100 Кб. Много нюансов, обсчет сложный. Это характерно для продуктов, разработанных инженерами для инженеров.


В защиту AWS скажу, что у них есть очень мощные инструменты для калькуляции. Вы можете запустить калькуляцию, ввести все ваши данные, и вам скажут с точностью до цента, сколько вы потратите. И потратите вы именно столько при условии, что работать будет все именно так, как вы это описали.


Всеволод: Я могу добавить? В защиту AWS хочу сказать, что там данные потребления непосредственно трафика, ресурсов и т.д. берутся с физического сервера. И этот физический сервер может отвечать за несколько типов данных, и этих серверов может быть много, они могут быть объединены в датацентр или колокейшн, разделены по зонам, вы это все используете, все это надо собрать и в конце дня вам доставить. Это непростая задача сама по себе. То есть причины для задержек есть, и они достаточно объективны. Никто не хочет нажиться на бедных разработчиках.


Как избежать чека в $1000, когда ожидаешь максимум $100-200, и при этом не остаться с заблокированным сервисом в час-пик?


Всеволод: Ответ на этот вопрос кроется в твоем предыдущем ответе, Саша. Смысл в том, что, во-первых, надо пользоваться калькулятором, а во-вторых, надо четко понимать, что вы в облаке делаете. Правильный ответ на этот вопрос приходит с опытом использования самого облака. То есть, условно говоря, с опытом вы знаете, что вот для такого функционала вам нужно две машинки С2 и миллион сообщений в SQS, вы ставите такие данные, калькулятор вам выдает число, вы делаете хардкэп на своих сервисах, то есть не больше миллиона сообщений, и отключаете автоскейлинг. Пожалуйста. У вас чек ровно такой, какой вам нужен. Пользуются ли этим в реальной жизни? Не видел еще. Все используют автоскейлинг и очень удивлены.


Александр: У автоскейлинга всегда можно задать верхнюю границу. Теперь мой вариант ответа. Во-первых, все, что сказал Всеволод. Во-вторых, проблема общая, все приходят с этими вопросами. Как избежать чека? Нужно понимать, что вы потребляете, где у вас точки расходов, потому что есть, например, условно бесплатные сервисы. И во всех точках расходов можно задать верхний предел масштабирования. Вы используете AutoScaling groups? Ну, пожалуйста, можно задать максимальное количество серверов, после которого вы согласны падать.


Создавая AutoScaling group, вы задаете минимальное и максимальное значение. Не ставьте там 100 серверов, поставьте 20, если у вас маленький сервис и вы напрямую не монетизируетесь с пришедших клиентов, и то же самое возможно для всех остальных сервисов. Ставьте ограничения, ставьте лимиты. Это вполне себе работает.


Почему так сложно управлять правами доступа в AWS (IAM)? (Прописывание policy вручную, boundary и т.д.)


Александр: Я сначала отвечу на вопрос почему, а потом на вопрос как. Представьте себе на одной стороне отрезка самокат, а на другой самолет, Boieng 777 или что-то подобное. Самокат прост и интуитивно понятен. Вы можете с первого раза встать на него, поехать и через несколько минут с ним справиться, а пару раз набив шишки уже делать какие-то трюки. Порог вхождения низкий, возможности низкие. Вы не можете на самокат посадить себя, своего пьяного друга и два ведра грибов из леса. Мощность низкая, простое управление.


Мы начинаем говорить про мощные системы. Identity and Access Management для тех, кто может быть не знает, это система управления правами доступа в AWS, очень мощная. Она позволяет вам генерировать такие правила, что пользователю Васе разрешено будет использование такого-то сервиса с редактированием при, не знаю, восходящей фазе луны в три часа ночи после крика петуха, но не будет доступно все остальное время, и т.д. Любая мощная система не может быть простой. Это закон природы. Из хороших новостей. Да, порог вхождения высокий, но когда привыкаешь, все становится хорошо. И все эти штуки нужные, хорошие и правильные.


Boundaries в начале можно не использовать. Для небольших проектов они не критичны. Начинайте с простого. В целом описание правил и политики доступа в IAM это очень классная вещь. Ее здорово настраивать. Сложные системы не могут быть с низким порогом вхождения.


Всеволод: Я слышал, что есть определенные тулзы, позволяющие выкинуть ненужные boundaries, policy, которыми ты никогда не будешь пользоваться, сделать это на начальном этапе, накатить это поверх своего аккаунта. Но насколько я понимаю, AWS такие штуки не рекомендует, поскольку это прямой секьюрити брич, и я их тоже не рекомендую. Проще все это освоить, потыкать и поехать.


Александр: Если вы работаете с простым приложением, вам эти навороты не нужны, используйте простой вариант. Если вы инженер, ответственный за это на серьезном проекте, то потратьте один день на то, чтобы изучить, как оно работает. Там не нужно больше одного дня. Восемь часов и читать, читать, смотреть, смотреть. И потом потихоньку внедрять, разбираться на практике. Все. Это не рокет сайнс. Немножко теории и множко практики, все получится.


Почему биллинг облаков до сих пор не работает в реальном времени? Всегда есть риск, что выйдет чек в тысячи долларов.


Всеволод: Мы уже на этот вопрос отвечали. Даже если собрать данные со всех серверов на это уже надо время. Нет такой страшной проблемы. Единственное, следите за вашими ресурсами. AWS играет честно.


Александр: Биллинг любой системы сложнее велосипеда будет отставать, потому что это чертовски сложно. Есть возможность сделать биллинг быстрым. Но ценой потребления ресурсов с вашего сервера. То есть биллинг у вас будет риал-тайм, а сервер будет работать медленнее. Вы точно этого хотите? Всегда есть риск, что выйдет чек в тысячи долларов. Есть. Так вы границы задавайте. Все. Ставьте ограничение, кеширование, тротлинг на API Gateway.


Всеволод: Справедливости ради стоит отметить, что найти эти AutoScaling groups с первого раза сложно, плюс они по умолчанию настроены очень широко.


Александр: Резюмируя: ставьте ограничения, и не будет у вас чеков в тысячи долларов.


Как подстраховаться от политической блокировки в облаке, и насколько оправдано стремление к гибридному облаку?


Всеволод: Можно не делать вендор-локов. Приходя на AWS и зная, что ваш сервис спорный в политическом плане, вы должны знать, что вендор-лок это плохо. Если вы используете SQS, используйте её через какую-то прокладку вашу, которая может переключиться на ту же Кафку, если вы используете что-то амазоновское, думайте о том, как вы это будете быстро мигрировать, а лучше не используйте ничего вообще, ставьте виртуалки, поднимайте на них базы данных, никаких амазоновских сервисов, все только свое и бэкапы всех данных в другое облако или на какой-нибудь свой собственный провайдер.


Александр: Да, избегайте вендор-лока. То есть жесткой привязки к какому-то конкретному поставщику.


Насколько оправдано стремление к гибридному облаку?


Александр: Очень зависит от вашего проекта. Гибридное облако это когда часть проекта у вас запущена в AWS, а часть проекта запущена в вашем собственном датацентре. И они взаимодействуют друг с другом. Насколько это оправдано? Для небольших и средних проектов, я бы сказал, это не оправдано чаще всего. Для больших проектов это может быть оправдано, так как это может быть оптимальным способом уменьшения расходов. Все зависит от вашего юзкейса. Если вы хотите создать максимальную доступность и пережить падение облака, такое тоже возможно. Но это очень сложно, и для этого нужны очень хорошие спецы. То есть снова для большинства проектов это будет неактуальным. Проще, конечно, одно чистое облако. Любые интеграции буду всегда сложнее.


Всеволод: Хотел еще добавить, что решение о внедрении гибридного проекта должен принимать непосредственно технический директор, так как оно несет CAPEX и накладные расходы, в том числе на человеческие ресурсы.


Александр: CAPEX (capital expences, капитальные расходы) подразумевается, что когда компания покупает новые сервера, она тратит много денег, ставит сервера себе как основные средства. И есть OPEX (operational expences), которые относятся к аренде, и если вы целиком в облаке, у вас все расходы на инфраструктуру являются операционными, и они списываются по-другому. Для некоторых компаний это может быть очень важно с точки зрения бухгалтерии и налогообложения.


Как в облаках организована защита критичных для компании данных, интеллектуальной собственности? Или это целиком забота потребителей облачных сервисов?


Александр: Как говорят AWS и, полагаю, Azure тоже: Security is a shared responsibility. Безопасность это разделенная ответственность. Имеется ввиду, что часть безопасности организовывает облако, но как бы они ни старались, если вы со своей стороны о безопасности не позаботились, они вам ничем помочь не смогут. То есть это общая ответственность. Хотите безопасность, изучайте, как организовать безопасность.


И второй момент надо понимать, что с GCP, с Amazon работают очень серьезные американские правительственные компании, у которых сверх строгие требования по шифрованию и хранению данных. И облака регулярно проходят всевозможные виды аудитов, чтобы подтвердить, что у них есть все необходимое: все виды изоляции, все защиты, шифрования и сертификаты все вообще, что может только потребоваться. И для совсем Advanced-кейсов можно использовать Outpost, то есть можно разворачивать инфраструктуру AWS на базе вашего собственного железа.


Всеволод: Я добавлю, что существуют готовые решения для шифрования и защиты ваших данных, в том числе и баз данных. Существует шифрование дисков, которое даже предоставляется бесплатно, насколько я знаю, Гуглом, насчет Амазона я не уверен. В итоге, сможет ли какой-нибудь блэк хэт с улицы залезть в вашу базу данных, зависит только от вас.


Я рекомендую организовывать бастионы, то есть некоторые сервера-прокси, точки входа, изолировать базу данных внутри кластеров, настраивать сервисы Kubernetes так, чтобы они не отвечали ни на что, кроме white-listed IP или white-listed services, ну, и так далее, потому что это большой топик.


Что вы думаете насчет отечественных cloud-провайдеров, Yandex, Selectel? Просто ваше мнение и опыт использования, если есть.


Александр: Здесь все просто. У меня есть небольшое участие в разработке одного из околооблачных поставщиков в России, опыта использования нет, потому что я почти сразу после этого переехал из России и ни про Yandex, ни про Selectel не могу рассказывать.


Всеволод: Последний раз, когда я изучал этот рынок, помимо Яндекса и MCS все остальные провайдеры использовали в некотором смысле openstack-решения. И у них были очень классные решения поверх openstack и очень классный менеджмент. В целом если вы держите бизнес в России, наверное, имеет смысл. У Амазона, например, нет региона Россия.


Александр: Да, у GCP, по-моему, тоже. Если вы держите данные ваших пользователей в России, то Yandex и Selectel могут быть для вас хорошим выбором.


После вашего курса смогу ли я запустить свой проект (небольшой) в AWS c пониманием дела? Смогу использовать нужные абстракции и т. д.?


Александр: Да, безусловно, он для этого и разработан. Я прицеплю сюда еще вопрос ниже: У меня уже есть AWS-SAA01, стоит ли покупать курс Слёрм. Насколько он будет мне полезен? Один из ценных моментов курса возможность задать вопрос и быть услышанным. У Амазона с этим сложно, как правило, такой возможности нет. Я готов взаимодействовать и отвечать на вопросы.


Если вы хотите использовать какие-то сложные вещи, про них мы, может быть, в курсе и не говорим. Например, Амазон предоставляет роскошнейшие возможности для machine learning, у них там все автоматизировано, интегрировано, вообще супер. И это в облаке вообще огонь. Но про это мы не рассказываем в базовом курсе, потому что где базовый курс, а где machine learning? Если вы планируете использовать Fargate, про него мы не рассказываем в базовом курсе, но все стандартные вещи: EC2, S3, AutoScaling, базы данных, Serverly, Lambda, API Gateway, инфраструктура как код, которая помогает вам управлять вашим проектом, и т. д. это все есть.


Почему в России большинство компаний все еще косо смотрит на облака (в пользу in-house инфраструктуры) при всех их преимуществах? Когда ожидать сдвига в мышлении?


Всеволод: Здесь причиной является опыт 90-х годов, когда к тебе в любой момент могли прийти за твоими данными. Уже никто в гости не приходит, но привычка осталась. Возможно, учитывая опыт политических блокировок, держать копию где-то при себе имеет смысл. Большинство компаний будет инвестировать в облака, если вы сможете обосновать их стоимость.


Александр: Нужно время на сдвиг парадигмы, наверное.


Сколько требуется времени для получения опыта или равноценного сертификата, который требуют работодатели для Cloud DevOps Engineer?


Александр: Во-первых, я не знаю, каких сертификатов требуют работодатели для Cloud DevOps Engineer. Если говорить про стандартные младшие позиции, если вы не претендуете на Senior Cloud DevOps, то у меня лично подготовка и сертифицирование для GCP заняла ровно месяц. Мне надо было перенести опыт архитектуры и разработки с AWS на GCP. Но это было много работы, я серьезно по много часов в день вкладывался. Что касается младших должностей, мне кажется, в качестве сайд-проекта базовую сертификацию в направлении Сloud DevOps нужно делать тоже за месяц. Если заниматься этим по паре-тройке часов в день, то это возможно. Это дело интересное и очень неплохо оплачивается в очень многих компаниях.


IAAS не всегда решает вопрос рабочих мест. Есть ли альтернативные способы реализации виртуальных рабочих мест кроме RDS (не гибко) и VDS (дорого)?


Всеволод: Я, честно скажу, в основном использовал облака для разработки приложений, которые там будут хоститься. По поводу организации рабочих мест со всеми RDS, VDS и т.д. здесь сложно ответить. Предлагаю связаться в LinkedIn.


Amazon Outpost. Зачем и как применять?


Александр: Это классная возможность, когда вы можете поднять свой собственный ЦОД, и вы можете запустить весь софт AWS на вашей стороне, и вы будете использовать его как полностью интегрированный в инфраструктуру Амазон, но при этом это будет ваше железо, которое стоит у вас и которое охраняется вами, обеспечивается электричеством вами и т. д. Вот что такое Amazon Outpost. Зачем и как применять? Как применять не расскажу, потому что до сих пор не приходилось, это очень специфичный кейс. У меня нет опыта с Outpost никакого, просто никогда не было необходимости. Зачем? В некоторых ситуациях есть супер-строгие требования по аудиту, системам безопасности и т. д. то есть только у вас должны храниться данные и никуда они не должны попадать, с точки зрения аудита.


Какова разница между курсами Слёрма и AWS training?


Александр: Со своей стороны скажу вот что: AWS я больше изучал на практике и отдельно знакомился с некоторыми курсами, которые у них есть. С точки зрения организации обучения, мне очень понравился Google Cloud Platform. Он вперед на милю от AWS с точки зрения организации процесса, материалов для подготовки и т. д. Первая разница между курсами Слёрм и AWS: AWS на английском. Если у вас плохой английский, Слёрм здесь однозначно будет лучшим выбором. У AWS есть тренинги практически на любую тему. Не всегда полные, не всегда хорошие, но они есть. У Слёрм на данный момент есть только один курс по AWS. Это базовый курс, который закрывает все основные юзкейсы и самые наиболее часто используемые сервисы. Но если вам нужен какой-нибудь хитровывернутый кейс, то этого может не оказаться в нашем курсе, опять-таки, курс называется базовый. И последнее Слёрм обеспечивает определенную поддержку: можно написать, можно сказать, что в практике написано вот так, у меня так не получается, что пошло не так? В AWS Training писать будет некому.


На сколько порядков отличается цена за единицу ресурсов облака для Netflix и стартапа?


Александр: Цена за единицу ресурсов будет одинакова. И это очень классно. Может быть, там есть какие-то секретные скидки для Netflix как глобальной корпорации. Но разные совершенно деньги за потребление.


Где границы между разумным использованием Iaas, PaaS, SaaS?


Александр: Все зависит от того, как много у вас специалистов в этой отрасли, насколько у вас хватает мощностей. Первое правило аутсторса: аутсорсить то, что для вас не принципиально, то, на чем вы не зарабатываете деньги, что не является ключом вашей бизнес-модели. Если вы делаете что-то, что не является для вас принципиальным, это склоняет вас ближе к SaaS. Saas и PaaS очень близки. Вы разрабатываете бессерверное приложение: у вас база данных будет SaaSом, а приложение ваше будет запущено на PaaSе. Я про это рассказываю в восьмом модуле курса. Если у вас много крутейших специалистов, вы Apple, и вы хотите иметь полный контроль над всем железом, то вы ближе к IaaSу или к on-premices собственному датацентру.

Подробнее..

Быстрый прототип IIoT-решения на Raspberry PI и Yandex IoT. Часть вторая

15.02.2021 10:17:19 | Автор: admin

Это вторая часть из цикла статей про прототипирование IIoT-решения на Raspberry PI и Yandex IoT.

В первой части мы реализовали основные функции на Raspberry PI:

  • сбор телеметрии с промышленных датчиков по протоколу Modbus;

  • их передачу в облако;

  • локальный мониторинг процесса в реальном времени.

Однако пока наш проект выглядит достаточно странно - данные попадают в облако, но никак там не оседают, а проходят насквозь, или вообще исчезают бесследно, если никто не успел их прочитать.

Настало время это исправить - разберемся с тем, как можно накапливать и обрабатывать переданную телеметрию в Яндекс Облаке.


Требуемый функционал

В рамках нашего решения облако должно решать следующие основные задачи:

  • принимать телеметрию устройства;

  • накапливать телеметрию в хранилище;

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

Посмотрим, какие инструменты для решения этих задач есть в Яндекс Облаке.

Доступные инструменты

Сбор и обработка телеметрии

Yandex IoT Core

В первой части мы уже познакомились с Yandex IoT Core и достаточно подробно разобрали его функционал. Если кратко, это MQTT-брокер от Яндекса, с помощью которого осуществляется обмен сообщениями между реестрами и устройствами.

Его мы и используем, чтобы отправлять телеметрию устройства в облако (как именно? велком в первую часть)

Yandex Cloud Functions

По умолчанию, с полученными по MQTT сообщениями в облаке ничего не происходит и информацию о них можно увидеть только в логах реестра или устройства. Для того, чтобы обработать присланную телеметрию нужно использовать сервис Yandex Cloud Functions.

Этот сервис позволяет разворачивать serverless-функции (на данный момент на Python, Node.js, Bash, Go и PHP), а также обладает механизмом триггеров - запуска развернутых функций по какому-либо условию (таймеру, событию).

Например, можно создать функцию-обработчик сообщения телеметрии и триггер, привязанный к топику устройства или реестра IoT Core, который будет отправлять пришедшие в топик сообщения на обработку этой функции. Таким образом, способы обработки сообщений ограничивается только возможностями выбранного языка программирования, квотами и лимитами сервиса.

Yandex Message Queue

Yandex Message Queue - сервис для обмена сообщениями между приложениями. В рамках этого сервиса можно реализовать механизм очередей, в которые одни приложения отправляют сообщения, а другие - забирают.

Этот механизм будет полезен, если в качестве хранилища использовать ClickHouse или схожие аналитические колоночные СУБД, плохо переносящие единичные вставки - в очереди можно накопить пачку сообщений и отправить их на вставку одним большим пакетом.

Хранение телеметрии

Для хранения данных Яндекс Облако предоставляет большое количество Managed Services для разных СУБД.

Managed Service любой СУБД, позволяет быстро развернуть готовый к работе кластер с необходимым хранилищем. Также в рамках облака можно быстро масштабировать ресурсы кластера в случае увеличения нагрузки.

Доступные на текущий момент СУБД:

  • PostgreSQL

  • ClickHouse

  • MongoDB

  • MySQL

  • Redis

  • SQL Server

По умолчанию, доступ к кластеру возможен только сервисами, развернутыми в рамках той же облачной сети (Yandex Virtual Private Cloud). Но при создании кластера можно включить публичный доступ, и тогда ресурс будет доступен из любой точки интернета.

Использование накопленной телеметрии

Yandex DataLens

Это сервис визуализации данных и анализа данных. Позволяет достаточно быстро создавать дашборды на основе данных из разнообразных источников.

Можно подключаться как к хранилищам, развернутым в облаке, так и сторонним источникам.

Yandex DataSphere

Сервис для ML-разработки, предоставляющий все необходимые инструменты и динамически масштабируемые ресурсы для полного цикла разработки машинного обучения.

Работа ведется в ноутбуках JupyterLab, есть возможность выбора ресурсов, на которых будет выполняться каждая отдельная ячейка (количество ядер, GPU).

Дополнительные инструменты

Yandex Monitoring

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

Настройка сохранения телеметрии

Несмотря на разнообразие инструментов, сейчас мы ограничимся тем, что будем просто сохранять телеметрию, пришедшую в IoT Core, в базу данных.

Для этого нам нужно развернуть и настроить 4 элемента:

  • IoT Core: создать реестр, устройство, наладить передачу сообщений по MQTT (сделано в первой части);

  • Managed Service for PostgreSQL - развернуть кластер, создать таблицу для хранения телеметрии;

  • Cloud Functions - написать функцию-обработчик сообщения с телеметрией: функция должна записывать payload сообщения в БД;

  • Cloud Functions - настроить триггер IoT Core, который будет запускать функцию-обработчик при появлении нового сообщения в топике реестра.

Частично здесь мы будем опираться на пример подобного решения из документации Яндекс Облака.

Настройка PostgreSQL

Для начала подключаем и настраиваем кластер Postgres:

Сервис Managed Service for PostgreSQL в консоли.Сервис Managed Service for PostgreSQL в консоли.

Нам подойдет самая минимальная конфигурация - b2.nano (если впоследствии проект перерастет во что-то большее, ее легко можно будет расширить):

Конфигурация кластера.Конфигурация кластера.

Заводим пользователя и базу данных:

Настройки БД.Настройки БД.

В разделе хосты нужно будет разрешить публичный доступ к ресурсу:

Настройка публичного доступа к БД.Настройка публичного доступа к БД.

Это нужно для того, чтобы база была доступна для обращения из Cloud Functions.

Создадим кластер. Теперь придется подождать некоторое время пока кластер развернется и его статус поменяется с Creating на Alive.

Создание кластера.Создание кластера.

После того, как кластер развернулся, заходим в него и создаем таблицу:

Вход в SQL клиент облакаВход в SQL клиент облака

Пока будем просто складывать весь payload в одну колонку. В последствии его можно будет распарсить на отдельные колонки по каждому значению, или классический timeseries:

CREATE TABLE telemetry_hist( telemetry_timestamp timestamp,  device_nm varchar(200),  payload varchar(2000));

Такой подход удобен ещё и тем, что если в процессе доработки проекта поменяется структура payload-а, сохранение в БД не сломается и телеметрия не будет теряться.

Создание функции-обработчика

Функция будет получать сообщения из MQTT-брокера и записывать данные в таблицу, созданную ранее.

В каталоге в консоли выбираем Cloud Functions:

Сервис Cloud Functions в консоли.Сервис Cloud Functions в консоли.

Создаем функцию с названием iot-core-handler и каким-нибудь говорящим описанием.

В открывшемся редакторе выбираем среду выполнения. Мы будем использовать Python 3.7 (preview).

Выбор среды выполнения при создании YCF.Выбор среды выполнения при создании YCF.

Теперь нам доступен редактор кода. Здесь мы можем написать требуемую функцию, создать ее версию, после чего она сразу развернется и станет доступной для выполнения.

Редактор кода YCF.Редактор кода YCF.

Помимо редактора кода, можно разворачивать код из архивов в Object Storage или загруженных напрямую.

Мы будем использовать код, предоставленный в документации Яндекс Облака (гитхаб), немного поправив его под наши нужды.

Правки касаются формата таблицы и payload сообщений:

  • Функция makeInsertStatement:

    Поменяем формат инсерта согласно формату нашей таблицы, уберем разбор пэйлоада на отдельные поля, а также изменим входную переменную event_id на event_ts.

def makeInsertStatement(event_ts, payload_json, table_name):    msg = json.loads(payload_json)    msg_str = json.dumps(msg)    logger.info(msg_str)    insert=  f"""INSERT INTO {table_name} (telemetry_timestamp , device_nm , payload) VALUES ('{event_ts}','iot_test_device', '{msg_str}')"""    return insert
  • Функция makeCreateTableStatement:

    Изменим выражение в соответсвтии с форматом таблицы.

def makeCreateTableStatement(table_name):    statement = f"""CREATE TABLE {table_name} (    ( telemetry_timestamp timestamp,      device_nm varchar(200),      payload varchar(2000)    );    """    return statement
  • Функция msgHandler:

    • Изменим переменную event_id на event_ts (96 строка) и будем формировать ее следующим образом:

      event_ts = json_msg["event_metadata"]["created_at"]
      
    • Изменим значение переменной table_name на название нашей таблицы (98 строка):

      table_name = telemetry_hist
      
    • В функцию makeInsertStatement в качестве первого аргумента отправляем не event_id, а event_ts (99 строка):

      sql = makeInsertStatement(event_ts, event_payload, table_name)
      

Код с уже внесенными правками можно найти в этом гисте. Вставим его в файл index.py.

Обратите внимание, если вы использовали другое название таблицы для сохранения телеметрии, необходимо указать его в качестве значения переменной table_name на 79 строке.

Теперь, перед созданием версии функции, в форме под редактором необходимо заполнить параметры развертывания:

  • Точка входа: укажем index.msgHandler - это имя функции в файле index.py, которая будет вызываться в качестве обработчика. Указывается в формате <имя файла с функцией>.<имя обработчика>

  • Таймаут, с: 10 секунд -максимальное время выполнения функции. Облачная функция может выполняться не более 10 минут.

  • Память: 128 МБ - объем необходимой для функции памяти

  • Сервисный аккаунт - укажем (или создадим, если его еще нет) сервисный аккаунт с ролями serverless.functions.invoker и editor

  • Переменные окружения - обратите внимание, разработанная функция использует 6 переменных окружения, которые необходимо заполнить в соответствующих полях. Нужно указать следующее:

    • VERBOSE_LOG параметр, отвечающий за вывод подробной информации о выполнении функции. Введем значение True.

    • DB_HOSTNAME имя хоста БД PostgreSQL для подключения.

    • DB_PORT порт для подключения.

    • DB_NAME имя базы данных для подключения.

    • DB_USER имя пользователя для подключения.

    • DB_PASSWORD пароль, который был введен при создании кластера

Все данные для подключения (кроме пароля) можно найти в обзоре развернутого Managed Service for PostgreSQL.

Информация для подключения к БДИнформация для подключения к БД

В итоге мы получаем такое заполнение полей:

Настройки YCF.Настройки YCF.

Создадим версию функции (кнопка Создать версию).

Настройка триггера IoT Core

Вернемся в раздел Cloud Functions и выберем подраздел Триггеры.

Подраздел "Триггеры" YCF.Подраздел "Триггеры" YCF.

Создадим триггер (кнопка Создать триггер).

  • В блоке Базовые параметры:

    • В поле Имя введем имя триггера.

    • В поле Тип выберем Yandex IoT Core. Так мы укажем сервису, что будем работать с обработкой событий IoT Core. Кроме этого источника, для решения других задач можно обрабатывать сообщения Message Queue, события Object Storage, Container Registry, логов Cloud Logs, а также запускать функцию по таймеру.

  • В блоке Настройки сообщений Yandex IoT Core:

    • В поле Реестр введем iot_test-reg - реестр к которому привязано наше устройствою

    • В поле Устройство выберем Любое устройство (т.к. мы отправляем сообщения в топик реестра)

    • В поле Топик укажем топик, в который устройство отправляет данные:

      • $registries/<ID реестра>/events

Теперь триггер будет срабатывать при появлении новых данных в указанном топике.

  • В блоке Настройки функции:

    • Выберем функцию для обработки данных, созданную ранее (iot-core-handler).

    • В поле Тег версии укажем $latest - тогда триггер будет запускать последнюю развернутую .

    • В поле Сервисный аккаунт укажем созданный ранее сервисный аккаунт.

    • Остальные поля оставим пустыми.

Настройки триггера YCF.Настройки триггера YCF.

Создадим триггер с заданными настройками.

Проверка работоспособности

Всё готово!

Теперь (если всё сделано правильно) каждое сообщение, отправляемое устройством, будет через созданный триггер инициировать вызов функции. Которая, в свою очередь, положит отправленный payload в таблицу на Postgres.

Проверим логи выполнения функции (Cloud Functions -> Функции -> iot-core-handler -> Логи).

Логи выполнения функции iot-core-handler.Логи выполнения функции iot-core-handler.

Здесь отображаются сообщения, выводимые функцией в процессе работы, в том числе, сообщения об ошибках. Если сообщений об ошибках нет (а есть информационные сообщения, начинающиеся с [INFO]) - функция работает корректно.

Посмотрим теперь заполнение таблицы telemetry_hist в нашей БД (Managed Services for PostgresSQL -> telemetry_store -> SQL). Вводим имя пользователя и пароль и попадаем в редактор SQL.

Вводим простой запрос для получения выгрузки из таблицы

SELECT * FROM telemetry_hist

И видим всю историю отправленных пэйлоадов:

Заполнение таблицы telemetry_hist.Заполнение таблицы telemetry_hist.

То есть всё работает: теперь телеметрия попадает в облако, накапливается в развернутой БД и доступна для дальнейшего анализа в любое удобное время из любой точки планеты!

PS. Если по каким-то причинам таблица остается пустой, можно проверить следующие моменты:

Отправило ли устройство хотя бы одно сообщение с момента деплоя функции и триггера?

  • Если нет - просто ждем пока это произойдет)

  • Если отправляло - смотрим логи выполнения функции.

    • Если логи пустые - стоит проверить триггер (в частности правильно ли указан топик и функция).

    • Если в логах ошибки - разбираемся с кодом.

    • Если функция отрабатывает и ошибок нет - проверяем настройки подключения к БД и имя таблицы.

Подробнее..

Облачные Gateway API зачем нужны подобные сервисы и чем они отличаются у разных платформ

19.05.2021 16:06:46 | Автор: admin

Добро пожаловать в современный интернет, где большая часть взаимодействия приходится на интерфейсы прикладного программирования API. На API держится цифровой бизнес: с ними стало возможным предоставлять и получать услуги через приложения и подключённые к Сети устройства. Платёжные системы? Работают через API. Интерактивная карта, показывающая, как добраться от метро до офиса? Снова API. Даже бэкенд строится на API.

Похоже, мы окружены значит, придётся разбираться. Что такое API, на Хабре уже рассказывали, а я предлагаю рассмотреть поподробнее реализацию API Gateway на облачных платформах.

Зачем вообще нужны Gateway API

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

Представьте себе: у вас есть интернет-магазин по продаже реплик молота Тора. Для удобства пользователя имеется как сайт под десктоп и мобильные устройства, так и приложения для Android и iPhone, которые взаимодействуют с сервером через REST API.

Чтобы на странице товара отображались верные данные, нам нужно обратиться к нескольким службам: в одной учитывается наличие молота, в другой записаны материал, вес и длина ручки, в третьей сохраняются отзывы клиентов, а цена вообще указана в четвёртой. API Gateway позволяет обойтись одним запросом.

API Gateway выполняет множество задач: принимает, обрабатывает и распределяет запросы, контролирует трафик, осуществляет мониторинг и контроль доступа.

В микросервисной архитектуре паттерн API Gateway появился в качестве службы, обеспечивающей единую точку входа для веб-приложений и API, эдакой серверной части для клиентской части. В чём польза именно для микросервисов?

Например возможность повторного использования компонентов, упрощение бэкенда приложения, обеспечение доступа к статическим веб-страницам и документам, удобная проверка авторизации и подбор оптимального для каждого типа клиента API как это делает Netflix API Gateway.

Что такое облачные API Gateway

Облачные структуры заимствуют многие паттерны микросервисов в том числе API Gateway и необходимость в их применении. API Gateway упрощает интеграцию приложения с сервисами облачной платформы и позволяет в полной мере использовать её возможности.

Классический API Gateway представляет собой шлюз между пользователями и любым количеством сервисов (API), выполняющий функцию обратного прокси, как Nginx и HAProxy. В то же время облачная версия API Gateway уже полноценный сервис для разработчиков, который простым в исполнении не назовёшь.

Основная задача та же самая приём и обработка запросов от клиентов к службам, а также управление доступом приложения к данным, бизнеслогике или функциональным возможностям сервисов.

Только облачные API Gateway на этом не останавливаются и предлагают множество дополнительных услуг: быстрое масштабирование, интеграцию с облачными сервисами, контроль доступа и настройку безопасности, создание и публикацию API, мониторинг API и тому подобное. Гораздо проще, чем создавать API Gateway с нуля, да и знаний требуется гораздо меньше.

Как облачные API Gateway облегчают жизнь

Итак, в разработке всё чаще применяются облачные технологии и закономерно возникает вопрос об облачных шлюзах API, их особенностях и преимуществах. Стоит ли их применять или лучше как-нибудь по старинке?

Для чего разработчики вообще выбирают облачные API Gateway?

  • Чтобы сократить время разработки API Gateway создаётся в несколько кликов, а интеграция с облачными сервисами выбранной платформы занимает пару минут.

  • Чтобы обеспечить минимальную задержку ответа на запрос об этом позаботится система автоматического масштабирования.

  • Чтобы лучше контролировать трафик к примеру, с помощью ограничения нагрузки на количество запросов в секунду для каждого HTTPметода. А при необходимости можно сформировать кеш с настраиваемыми ключами и указанием жизненного срока в секундах.

  • Чтобы отлаживать API встроенными средствами меньше головной боли.

  • Чтобы генерировать клиентские SDK.

  • Чтобы одновременно использовать нескольких версий одного API, а также управлять стадиями выпуска от альфы до релиза.

  • Чтобы контролировать доступ к API и управлять его жизненным циклом от создания до публикации.

  • Чтобы уведомление приходило от сервиса, а не от разозлённого клиента, если что-то идёт не так.

  • Чтобы настраивать авторизацию удобным методом с помощью средств Lambda или токенов OAuth.

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

  • Чтобы платить только за количество запросов в месяц или пользоваться сервисами бесплатно, если не выходить за рамки определённой цифры.

Как используют облачные API Gateway

Виртуальная доска

Простое приложение, состоящее из двух конечных точек POST для записи сообщений и GET для извлечения трёх последних сообщений. Реализовано с помощью AWS Gateway, AWS DynamoDB, AWS Serverless Application Model и Lambda.

Голосовой сервиc

Рецепт сервиса записи к врачу и регистрации в поликлинике, разработанный коммуникационной платформой Voximplant и Yandex.Cloud.

Бот для телеграма

Запуск бота на Python внутри одного из облачных сервисов, а именно Yandex.Cloud.

Трекер пульсометрии

Один из вариантов решения для сбора данных пульсовой оксиметрии для нескольких пользователей, отслеживания этих данных и обмена ими. Фронт написан на VueJS, бэкенд реализован с применением Amazon API Gateway.

Статический сайт в облаке

Пошаговая инструкция по деплою статического сайта в облако, прикрутке к нему сертификата Lets Encrypt, домена второго уровня и настройке API-шлюза в системе Yandex.Cloud.

Блог

И снова приложение на микросервисах реализация клиентской части на VueJS, взаимодействие настроено через REST API и gRPC, а в качестве базы данных используется MongoDB.

Реализация на разных облачных платформах

Сервис API Gateway предлагают несколько облачных платформ и все они предоставляют более-менее схожий пакет услуг. Так в чём же разница?

Azure API Management

Платформа гибридного кросс-облачного управления через API Позволяет в том числе самостоятельное размещение шлюза в своей среде и управление им через API Azure. Мультиклауд для отважных.

Amazon API Gateway

Amazon API Gateway пожалуй, самый известный сервис, предназначенный для создания, публикации, обслуживания, мониторинга и обеспечения безопасности API в любых масштабах.

Документация включает подробные инструкции от развёртывания RESTful API при создании бессерверного веб-приложения до работы с HTTP API, поэтому не придётся искать примеры по всей Сети, чтобы разобраться.

Особенности:

  • Создание API RESTful при помощи API HTTP или API REST.

  • Интерфейсы API WebSocket для разработки приложений, которым требуется двусторонняя связь в режиме реального времени.

  • Частная интеграция с AWS ELB и AWS Cloud Map.

  • Ключи API для сторонних разработчиков.

  • Генерирование клиентских SDK на многих языках, включая JavaScript, iOS и Android.

  • Внедрение подписи четвёртой версии для API REST и API WebSocket при авторизации и проверке запросов API к другим сервисам AWS API Gateway.

  • Авторизация с помощью AWS Lambda.

  • Amazon API Gateway можно пользоваться бесплатно целый год пока ваши потребности не превышают один миллион вызовов API, полученных для API REST, один миллион вызовов API, полученных для API HTTP, и один миллион сообщений и 750 000 минут подключения для API WebSocket в месяц.

  • Обучение с помощью пошаговых учебных пособий, а также доступ к более чем 500 бесплатным онлайн-курсам.

Oracle API Gateway

Сервис Oracle API Gateway стал доступен любому пользователю в конце 2019 года и уже пытается активно конкурировать с Amazon API Gateway. Получится ли у него отвоевать хотя бы часть аудитории у AWS, нам только предстоит увидеть а сравнивать всегда интереснее на собственном опыте. Почитать про создание своего Gateway API можно вот в этой статье.

Особенности платформы:

  • RESTful API в комбинации с Oracle Functions, а также возможностями Kubernetes и Compute.

  • Каждая служба в облачной инфраструктуре Oracle интегрируется с IAM для аутентификации и авторизации (консоль, SDK или CLI и REST API).

  • Интеграция с системой управления доступом Oracle Cloud Infrastructure.

  • Бесплатный период длительностью в тридцать дней, чтобы опробовать возможности широкого спектра сервисов Oracle Cloud, в том числе к Databases, Analytics, Compute, Container Engine for Kubernetes и т. д.

  • Платформа Oracle Cloud позиционирует себя как более экономичное решение, чем AWS, и в качестве примера упоминает, что соотношение цены и производительности в 2 раза выше, а стоимость исходящей пропускной способности составляет только 1/4 от стоимости у AWS.

Google API Gateway

Сервис перешёл на стадию публичного бета-тестирования 18 сентября 2020 года, так что пока о нём известно довольно мало и тем интереснее пронаблюдать за его развитием.Сейчас Google API Gateway позволяет управлять API других сервисов облачной платформы Cloud Functions, Cloud Run, App Enginе, Compute Engine и Google Kubernetes Engine. Настроить работу с Cloud Run, к примеру, можно всего за несколько минут.

Особенности:

  • Оплачиваются только вызовы к инфраструктурным службам. Стоимость зависит от количества вызовов, а входящий трафик всегда бесплатен.

  • До 2 миллионов запросов в месяц бесплатно.

  • Наличие пробной версии. Google Cloud предоставляет виртуальный кредит в размере 300 долларов, который необходимо потратить в течение последующих трёх месяцев. После окончания бесплатного периода оплата не начинает взиматься автоматически на платный тариф необходимо перейти вручную.

SberCloud API Gateway

SberCloud API Gateway использует наработки Huawei, а информации об особенностях применении в Сети можно найти немного, но здесь вам поможет Хабр: после недавнего хакатона один из участников рассказал о впечатлениях от SberCloud и сравнил функциональность с более известным AWS.

Особенности:

  • Доступ к облачным продуктам для физических лиц возможен только с помощью входа/регистрации через Сбер ID.

  • Управление квотами и регулирование запросов пользователей.

  • Встроенный инструмент отладки.

  • Визуализированная панель мониторинга API.

  • Создание каналов VPC для доступа к бэкенд-сервисам в сети VPC и управления нагрузкой путём отправки API-запросов на различные серверы.

  • Цифровая подпись, которая вступает в силу только после привязки к API.

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

  • Возможность монетизации API.

Yandex API Gateway

23 сентября 2020 года к четырём сервисам платформы Yandex.Cloud прибавились ещё два Yandex API Gateway и база данных Yandex Database в режиме Serverless.

Yandex API Gateway интегрирован с другими сервисами платформы, благодаря чему возможна отправка HTTP-запросов с помощью функций Yandex Cloud Functions, доступ к статическим данным осуществляется Yandex Object Storage напрямую из хранилища, а запуск произвольных HTTP-сервисов в облаке возможен с помощью Yandex Managed Service for Kubernetes. Так что спектр применения широк к примеру, внутри облака можно запустить приложение на Express.js.

К слову, до октября 2021 года на бессерверные решения действуют специальные тарифы, которые позволяют создавать и размещать небольшие сайты и сервисы бесплатно.

Особенности:

  • Наличие расширений для спецификации, которые можно использовать для интеграции с другими облачными платформами.

  • Поддержка OpenAPI 3.0.

  • Обработка запросов только по протоколу HTTPS. Сервис автоматически перенаправляет все запросы к API-шлюзам по протоколу HTTP на их HTTPS-версии.

  • Интеграция с системой управления доменами сервиса Certificate Manager. Для обеспечения TLS-соединения используется привязанный к домену сертификат.

  • Система квот и лимитов. Максимальный размер спецификации 3,5 МБ. Количество API-шлюзов в одном облаке 10, но, в отличие от максимального размера спецификации, меняется по запросу в техническую поддержку.

Тарификация по количеству запросов к созданным API-шлюзам и исходящему трафику. При этом запросы к API-шлюзам до 100 000 запросов в месяц не тарифицируются. Как, кстати, и входящий трафик, а также передача данных между сервисами Yandex.Cloud. Больше подробностей можно узнать в сообществе Serverless в Telegram:Yandex Serverless Ecosystem. Мы регулярно встречаемся в виртуальном пространстве и похоже созревает потребность в очной встрече.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru