L'histoire de l'introduction d'un framework sans serveur très semblable à Rails "Ruby on Jets" dans l'environnement de production

** * Cet article a été créé le 12 juillet 2019 [L'histoire de l'introduction du framework sans serveur très semblable à Rails "Ruby on Jets" dans l'environnement de production --LiBz Tech Blog](https: //tech.libinc. Il s'agit du même contenu que co.jp/entry/2019/07/12/113215) **

introduction

salut! Watanabe, qui a eu 26 ans l'autre jour, n'a cessé d'augmenter sa peur de 30 ans.

Ceci est mon troisième article de blog. Merci pour vos nombreux signets dans le précédent Premiers pas avec Kubernetes (GKE) à moindre coût.

Cette fois, j'écrirai sur le ** framework Ruby sans serveur ** de type Rails ** "Ruby on Jets" ** que j'ai effectivement commencé à utiliser en entreprise.

20190710145705.jpg

Contexte

Le produit que je suis en charge de développer a une fonction qui permet aux demandeurs d'emploi et à nos conseillers d'orientation d'échanger des messages via LINE.

Cette fonctionnalité est implémentée à l'aide de l'API de messagerie de LINE, mais elle reçoit le message envoyé par le demandeur d'emploi. Le seul moyen est de "recevoir des données avec un webhook" Lorsqu'un webhook est demandé à notre serveur, il y a un gros problème: ** le message envoyé par le chercheur d'emploi disparaît si le serveur a des problèmes ou est en état de maintenance **. était.

20190711145732.png

Par conséquent, nous avons décidé de construire un système sans serveur qui ne serait pas affecté par la vie ou la mort de notre ** serveur exploité par ECS **, et de réparer le processus de réception des messages LINE afin qu'il y soit traité.

Constitution

Tout d'abord, je vais vous présenter de quel type de configuration il s'agissait, mais à la fin, l'environnement de production actuel est le suivant.

20190710195302.png

Même s'il s'agit d'une architecture sans serveur, les fonctions requises cette fois sont

  1. Recevoir un webhook du serveur LINE
  2. Vérifiez si la demande provient vraiment du serveur LINE
  3. Enregistrez les données reçues par le webhook

Il n'y avait que les trois ci-dessus.

Il était question d'utiliser DynamoDB pour stocker des données, mais à la fin, il a été décidé d'utiliser la file d'attente FIFO SQS.

** Serveur LINE → API Gateway → Lambda → SQS (file d'attente FIFO) ← Application existante **

C'est devenu une structure très simple.

Sélection de technologie

Quelle est l'implémentation du runtime (langage) de Lambda?

Le traitement dont Lambda sera en charge est

Il y en a deux.

Concernant "le processus de vérification s'il s'agit d'une requête (webhook) du serveur LINE", puisqu'il est déjà implémenté dans Rails, j'ai pensé que Ruby qui peut réutiliser le code serait le plus simple, mais Lambda est Ruby. C'était en décembre 2018, ce qui était relativement récent, donc j'étais inquiet.

20190711144928.png

Que utiliser pour la gestion de la configuration de l'architecture sans serveur?

La gestion de la configuration est un goulot d'étranglement dans l'architecture sans serveur. Lambda seul peut gérer la version du code, il ne peut donc y avoir aucun problème, mais si vous souhaitez gérer les paramètres tels que API Gateway avec le code, il est préférable d'utiliser une sorte d'outil.

Bien que j'ai choisi Jets, il existe de nombreuses parties instables telles qu'un seul committer principal et il est mis à jour une fois tous les 3 jours, donc si quelque chose ne va pas, je peux passer à Serverless Framework. Il a été adopté avec un avis. (J'ai décidé que le coût de transfert ne serait pas trop élevé car la mise en œuvre n'est pas si compliquée.)

Une petite explication des Jets

Créer un projet

rails new Cordialement, vous pouvez créer un projet avec la commande jets new. Spécifiez l'API comme mode. Nous avons également spécifié l'option --no-database car nous n'utilisons pas la base de données cette fois.

$jets nouveau nom de projet--mode api --no-database

Jets prend en charge RDB et DynamoDB tels que MySQL et PostgreSQL, mais RDB et Lambda seraient très incompatibles en raison de la relation de connexion, donc si vous l'utilisez, sera-ce DynamoDB?

Référence: Une brève explication des raisons pour lesquelles AWS Lambda et RDBMS sont incompatibles --Sweet Escape

À propos, le créateur de «gem dynomite», qui gère la migration de DynamoDB comme ActiveRecord et facilite les opérations CRUD, est également le développeur de ce Jets.

Paramètres de routage

config/routes.rb


Jets.application.routes.draw do
  get  'hoge', to: 'hoge#huga'
  post 'foo',  to: 'foo#bar'
end

Exactement la même chose que les rails. Avec les paramètres ci-dessus, def huga de HogeController sera exécuté lorsqu'une requête get est faite à / hoge.

En fait, la fonction Lambda qui exécute le code de la méthode huga lorsque la passerelle API est accédée par GET / hoge est liée.

manette

Dans Rails, je pense qu'il est basique de créer divers contrôleurs qui héritent de ʻActionController :: Base, mais dans Jets, créez des contrôleurs qui héritent de Jets :: Controller :: Base`.

app/controllers/hoge_controller.rb


# Jets::Controller::Il hérite du contrôleur d'application qui hérite de la base
class HogeController < ApplicationController

  def huga
    response_body = {
      hello: 'world!!',
      request_params: {
        headers: event['headers'],
        body: event['body'],
        query_parameters: event['queryStringParameters'],
        path_parameters: event['pathParameters']
      } 
    }
    render json: response_body
  end

end

La variable d'événement change également en fonction de ce qui a déclenché le démarrage de Lambda, mais dans le cas d'API Gateway, vous pouvez facilement obtenir les paramètres de demande comme décrit ci-dessus.

Stratégie IAM requise

Vous aurez besoin des permissions listées ici [https://rubyonjets.com/docs/extras/minimal-deploy-iam/). Je n'ai pas utilisé DynamoDB et Route53 dans ce déploiement de production, donc je n'en avais pas besoin.

Les autorisations CloudFormation sont requises car la configuration sera éventuellement transformée / exécutée en tant que modèle CloudFormation. Cela ne se limite pas aux Jets, et la plupart des frameworks sans serveur gèrent les configurations en convertissant les paramètres de ressources tels que API Gateway en modèles CloudFormation.

Comment gérer les clés secrètes, etc.

C'est config / secrets.yml dans Rails. Malheureusement, il n'y a pas de secrets.yml dans Jets, mais j'ai pu faire de même en utilisant le fichier env.

# .env.development
SECRET_KEY_BASE=abcdefg
SECRET_ACCESS_KEY=12345
SECRET_ACCESS_TOKEN=7890

En écrivant comme ci-dessus, il sera défini dans la variable d'environnement de la fonction Lambda et peut être obtenu par ʻENV ['key_name'] `.

Il prend également en charge le paramètre AWS SSM et peut être décrit comme suit.

# .env.production
SECRET_KEY_BASE=ssm:/secret_key_base
SECRET_ACCESS_KEY=ssm:/secret_access_key
SECRET_ACCESS_TOKEN=ssm:/secret_access_token

Bien sûr, vous aurez également besoin d'autorisations autour du SSM, mais vous pouvez éviter le codage en dur de secret_key en définissant les paramètres dans le SSM à l'avance. Si tel est le cas, vous pouvez également pousser vers github.

20190711145146.png

Comment déployer

Déployez avec la commande jets deploy.

#Déployer
$ AWS_PROFILE=[nom de profil] bundle exec jets deploy [Nom de l'environnement]

#Supprimer les ressources déployées
$ AWS_PROFILE=[nom de profil] bundle exec jets remove [Nom de l'environnement]

Jets fournit également des commandes pour le déploiement Blue-Green.

# Blue-Déploiement vert
$ AWS_PROFILE=[nom de profil] JETS_ENV_EXTRA=[1~Nombre de 9] bundle exec jets deploy [Nom de l'environnement]

En déployant en spécifiant le numéro avec JETS_ENV_EXTRA, des ressources telles que` hoge-resources- [nom de l'environnement] - [numéros 1 à 9] sont créées. Vous pouvez effectuer des opérations telles que le changement de points de terminaison de ressources après une vérification suffisante.

https://rubyonjets.com/docs/env-extra/

finalement

Cette fois, il m'est arrivé que le besoin était petit, j'ai donc décidé d'utiliser des Jets, mais j'ai l'impression qu'il n'est pas encore assez mature pour être utilisé pour des services à grande échelle.

Cependant, j'ai été surpris de voir à quel point la différence entre les applications existantes et les applications sans serveur est en train de devenir. Les ingénieurs d'application pourront-ils développer sans se soucier du serveur (infrastructure)? Lol

Aujourd'hui, je pense qu'en lisant le document, je pense que je n'ai pas encore maîtrisé la moitié des fonctionnalités de Jets. Je veux que vous deveniez l'un des plus gros produits qui représentent Ruby! (Les personnes qui utilisent désormais des Jets doivent être préparées à répondre aux mises à jour qui arrivent tous les trois jours. Lol)

https://rubyonjets.com

prime

En développant avec SQS cette fois, je voudrais présenter ** Elastic MQ **, qui peut construire un pseudo SQS dans l'environnement local, car c'était très pratique.

J'ai utilisé softwaremill / Elasticmq pour l'image Docker.

docker-compose.yml


version: '3.2'
services:
  jets: 
    ..réduction..

  local_sqs:
    image: softwaremill/elasticmq
    container_name: local_sqs
    ports:
      - "9324:9324"
    volumes:
      - local_sqs.conf:/opt/elasticmq.conf

Vous pouvez personnaliser la file d'attente en montant local_sqs.conf sur / opt / elasticmq.conf d'ElasticMQ. Cette fois, je voulais utiliser la file d'attente FIFO, je l'ai donc définie comme suit.

local_sqs.conf


include classpath("application.conf")

node-address {
    protocol = http
    host = local_sqs
    port = 9324
    context-path = ""
}
rest-sqs {
    enabled = true
    bind-port = 9324
    bind-hostname = "0.0.0.0"
    sqs-limits = strict
}
generate-node-address = false
queues {
    "Nom de la file d'attente.fifo" {
        fifo = true
    }
}

La raison pour laquelle «.fifo» est ajouté au nom de la file d'attente est que «.fifo» est automatiquement ajouté à la fin de la file d'attente FIFO créée par SQS.

Récemment, des outils pour développer localement des applications exécutées sur AWS sont devenus disponibles, ce qui est très apprécié des développeurs.

Recommended Posts

L'histoire de l'introduction d'un framework sans serveur très semblable à Rails "Ruby on Jets" dans l'environnement de production
Une histoire sur l'introduction d'Evolutions dans le cadre de jeu
Présentation de Rspec, un framework de test pour Ruby on Rails
Une note sur la fonction de départ de Ruby on Rails
Comment résoudre la construction de l'environnement local de Ruby on Rails (MAC)!
[Ruby] Création d'un environnement de développement Ruby sur Ubuntu
Créez un environnement de développement pour créer des applications Ruby on Jets + React avec Docker
[Ruby on Rails] Implémentez un graphique circulaire qui spécifie le pourcentage de couleurs
[Ruby on Rails] Jusqu'à l'introduction de RSpec
Une histoire très utile sur la classe Struct de Ruby
[Ruby on Rails] Un mémorandum de modèles de mise en page
Ecrire un test en mettant en œuvre l'histoire de M. Nabeats dans le monde avec du rubis
Apprenez la signification de «transmettre le PATH» en créant un environnement de développement Java sur Mac