** * 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) **
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.
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.
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é.
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.
Même s'il s'agit d'une architecture sans serveur, les fonctions requises cette fois sont
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.
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.
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.
Serverless Framework C'est probablement l'outil le plus utilisé pour l'architecture sans serveur, et il existe de nombreux documents et articles japonais. Avant de rejoindre LiB, j'étais souvent pris en charge par l'entreprise. Personnellement, je me demande si ce sera Serverless Framework + Node pour la stabilité.
AWS SAM Framework officiel AWS pour la création d'applications sans serveur. Il y avait SAM Local (maintenant appelé SAM CLI) qui pouvait configurer un pseudo serveur API Gateway dans l'environnement local et c'était très facile à déboguer, mais quand je l'utilisais, c'était douloureux car il y avait de nombreux bogues. est,, (Je pense que cela a été corrigé maintenant!)
Ruby on Jets Cette fois, j'ai adopté ce Ruby on Jets. Je suis surpris quand je l'utilise réellement. Loin de ressembler à des Rails, c'était presque des Rails. Pour plus de détails, il est organisé en Qiita here d'une manière facile à comprendre, mais les routes écrites dans les routes sont reflétées dans API Gateway telles quelles, et je les ai écrites dans Controller. Le traitement est reflété dans Lambda.
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.)
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?
À 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.
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.
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.
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.
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.
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/
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
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.