Die Geschichte der Einführung eines sehr Rails-ähnlichen serverlosen Frameworks "Ruby on Jets" in die Produktionsumgebung

** * Dieser Artikel wurde am 12. Juli 2019 erstellt [Die Geschichte der Einführung des sehr Rails-ähnlichen serverlosen Frameworks "Ruby on Jets" in die Produktionsumgebung - LiBz Tech Blog](https: //tech.libinc. Es ist der gleiche Inhalt wie co.jp/entry/2019/07/12/113215) **

Einführung

Hallo! Watanabe, der neulich 26 Jahre alt geworden ist, hat seine Angst vor 30 Jahren stetig erhöht.

Dies ist mein dritter Blogbeitrag. Vielen Dank für Ihre vielen Lesezeichen im vorherigen Günstig Erste Schritte mit Kubernetes (GKE).

Dieses Mal werde ich über ** Rails-ähnliches ** Ruby Serverless Framework ** "Ruby on Jets" ** schreiben, das ich tatsächlich im Geschäft verwendet habe.

20190710145705.jpg

Hintergrund

Das Produkt, für dessen Entwicklung ich verantwortlich bin, hat eine Funktion, mit der Arbeitssuchende und unsere Karriereberater Nachrichten über LINE austauschen können.

Diese Funktion wird mithilfe der LINE-Messaging-API implementiert, erhält jedoch die vom Arbeitssuchenden gesendete Nachricht. Die einzige Möglichkeit besteht darin, "Daten mit einem Webhook zu empfangen". Wenn ein Webhook an unseren Server angefordert wird, besteht das große Problem, dass ** die vom Jobsuchenden gesendete Nachricht verschwindet, wenn mit dem Server etwas nicht stimmt oder wenn er sich im Wartungsstatus befindet **. war.

20190711145732.png

Aus diesem Grund haben wir uns entschlossen, ein serverloses System zu erstellen, das nicht von Leben oder Tod unseres von ECS ** betriebenen ** Servers betroffen ist, und den Prozess des Empfangs von LINE-Nachrichten so zu reparieren, dass er dort verarbeitet wird.

Verfassung

Zuerst werde ich vorstellen, um welche Art von Konfiguration es sich handelt, aber am Ende sieht die aktuelle Produktionsumgebung wie folgt aus.

20190710195302.png

Obwohl es sich um eine Architektur ohne Server handelt, sind diesmal die erforderlichen Funktionen erforderlich

  1. Empfangen Sie einen Webhook vom LINE-Server
  2. Überprüfen Sie, ob die Anforderung wirklich vom LINE-Server stammt
  3. Speichern Sie die vom Webhook empfangenen Daten

Es gab nur die oben genannten drei.

Es war die Rede davon, DynamoDB zum Speichern von Daten zu verwenden, aber am Ende wurde beschlossen, die SQS-FIFO-Warteschlange zu verwenden.

** LINE-Server → API-Gateway → Lambda → SQS (FIFO-Warteschlange) ← Vorhandene Anwendung **

Es wurde eine sehr einfache Struktur.

Technologieauswahl

Was ist die Implementierung von Lambdas Laufzeit (Sprache)?

Die Verarbeitung, für die Lambda verantwortlich sein wird, ist

Es gibt zwei.

In Bezug auf "den Prozess der Überprüfung, ob es sich um eine Anforderung (Webhook) vom LINE-Server handelt", da Ruby bereits in Rails implementiert ist, dachte ich, dass Ruby, das den Code wiederverwenden kann, am einfachsten ist, aber Lambda ist Ruby. Es war Dezember 2018, der relativ neu war, also machte ich mir Sorgen.

20190711144928.png

Was ist für das Konfigurationsmanagement der Architektur ohne Server zu verwenden?

Das Konfigurationsmanagement ist ein Engpass in der Architektur ohne Server. Lambda allein kann die Codeversion verwalten, daher gibt es möglicherweise kein Problem. Wenn Sie jedoch die Einstellungen wie API Gateway zusammen mit dem Code verwalten möchten, ist es besser, ein Tool zu verwenden.

Obwohl ich mich für Jets entschieden habe, gibt es viele instabile Teile, wie zum Beispiel nur einen Haupt-Committer, und dieser wird alle 3 Tage aktualisiert. Wenn also etwas schief geht, kann ich zu Serverless Framework wechseln. Es wurde mit Aussicht angenommen. (Ich entschied, dass die Übertragungskosten nicht zu hoch sein würden, da die Implementierung nicht so kompliziert ist.)

Eine kleine Erklärung von Jets

Ein Projekt erstellen

Rails New Grüße, Sie können ein Projekt mit dem Befehl Jets New erstellen. Geben Sie die API als Modus an. Wir haben auch die Option "--no-database" angegeben, da wir diesmal die Datenbank nicht verwenden.

$Jets neuer Projektname--mode api --no-database

Jets unterstützt RDB und DynamoDB wie MySQL und PostgreSQL, aber RDB und Lambda gelten aufgrund der Verbindungsbeziehung als sehr inkompatibel. Wenn Sie sie also verwenden, handelt es sich dann um DynamoDB?

Referenz: Eine kurze Erklärung, warum AWS Lambda und RDBMS nicht kompatibel sind - Sweet Escape

Übrigens ist der Entwickler von "Gem Dynomite", der die Migration von DynamoDB wie ActiveRecord verwaltet und CRUD-Operationen vereinfacht, auch der Entwickler dieser Jets.

Routing-Einstellungen

config/routes.rb


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

Genau das gleiche wie Rails. Mit den obigen Einstellungen wird "def huga" von "HogeController" ausgeführt, wenn eine Get-Anfrage an "/ hoge" gestellt wird.

Tatsächlich ist die Lambda-Funktion verknüpft, die den Code der "huga" -Methode ausführt, wenn auf das API-Gateway über "GET / hoge" zugegriffen wird.

Regler

In Rails ist es meiner Meinung nach grundlegend, verschiedene Controller zu erstellen, die "ActionController :: Base" erben, in Jets jedoch Controller, die "Jets :: Controller :: Base" erben.

app/controllers/hoge_controller.rb


# Jets::Controller::Es erbt den Anwendungscontroller, der Base erbt
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

Die Ereignisvariable ändert sich auch abhängig davon, was Lambda zum Starten ausgelöst hat. Im Fall von API Gateway können Sie die Anforderungsparameter jedoch wie oben beschrieben problemlos abrufen.

Erforderliche IAM-Richtlinie

Sie benötigen die hier aufgeführten Berechtigungen [https://rubyonjets.com/docs/extras/minimal-deploy-iam/]. Ich habe DynamoDB und Route53 in dieser Produktionsbereitstellung nicht verwendet, daher habe ich sie nicht benötigt.

CloudFormation-Berechtigungen sind erforderlich, da die Konfiguration möglicherweise als CloudFormation-Vorlage transformiert / ausgeführt wird. Dies ist nicht auf Jets beschränkt, und die meisten serverlosen Frameworks verwalten die Konfiguration durch Konvertieren von Ressourceneinstellungen wie API Gateway in CloudFormation-Vorlagen.

Umgang mit geheimen Schlüsseln usw.

Es ist config / secret.yml in Rails. Leider gibt es in Jets keine Secrets.yml, aber ich konnte dasselbe mithilfe der env-Datei tun.

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

Wenn Sie wie oben schreiben, wird es in die Umgebungsvariable der Lambda-Funktion gesetzt und kann mit "ENV ['key_name']" abgerufen werden.

Es unterstützt auch AWS SSM-Parameter und kann wie folgt beschrieben werden.

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

Natürlich benötigen Sie auch Berechtigungen für den SSM, aber Sie können die harte Codierung von secret_key vermeiden, indem Sie die Parameter im SSM im Voraus festlegen. Wenn dies der Fall ist, können Sie auch auf Github drücken.

20190711145146.png

Bereitstellen

Bereitstellung mit dem Befehl jets deploy.

#Bereitstellen
$ AWS_PROFILE=[Profilname] bundle exec jets deploy [Umgebungsname]

#Bereitgestellte Ressourcen löschen
$ AWS_PROFILE=[Profilname] bundle exec jets remove [Umgebungsname]

Jets bietet auch Befehle für die Blaugrün-Bereitstellung.

# Blue-Grüner Einsatz
$ AWS_PROFILE=[Profilname] JETS_ENV_EXTRA=[1~Nummer 9] bundle exec jets deploy [Umgebungsname]

Durch die Bereitstellung durch Angabe der Nummer mit "JETS_ENV_EXTRA" werden Ressourcen wie "hoge-resources- [Umgebungsname] - [Nummern 1 bis 9]" erstellt. Sie können Vorgänge wie das Wechseln von Ressourcenendpunkten nach ausreichender Überprüfung ausführen.

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

Schließlich

Diesmal war die Anforderung gering, daher habe ich mich für Jets entschieden, aber ich habe den Eindruck, dass sie noch nicht ausgereift genug ist, um für umfangreiche Dienste verwendet zu werden.

Ich war jedoch überrascht, wie groß der Unterschied zwischen vorhandenen und serverlosen Anwendungen wird. Werden Anwendungsingenieure in der Lage sein, ohne sich um den Server (die Infrastruktur) zu kümmern? Lol

Heutzutage denke ich, dass ich beim Lesen des Dokuments noch nicht die Hälfte der Funktionalität von Jets beherrsche. Ich möchte, dass Sie zu einem der größten Produkte werden, die Ruby repräsentieren! (Personen, die ab sofort Jets verwenden, müssen darauf vorbereitet sein, auf Aktualisierungen zu reagieren, die alle drei Tage erfolgen. Lol)

https://rubyonjets.com

Bonus

Bei der diesmaligen Entwicklung mit SQS möchte ich ** Elastic MQ ** einführen, mit dem ein Pseudo-SQS in der lokalen Umgebung erstellt werden kann, da dies sehr praktisch war.

Ich habe softwaremill / elasticmq für das Docker-Image verwendet.

docker-compose.yml


version: '3.2'
services:
  jets: 
    ..Kürzung..

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

Sie können die Warteschlange anpassen, indem Sie local_sqs.conf on / opt / elasticmq.conf von ElasticMQ mounten. Dieses Mal wollte ich die FIFO-Warteschlange verwenden, also habe ich sie wie folgt eingestellt.

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 {
    "Name der Warteschlange.fifo" {
        fifo = true
    }
}

Der Grund, warum dem Namen der Warteschlange ".fifo" hinzugefügt wird, besteht darin, dass die von SQS erstellte FIFO-Warteschlange am Ende automatisch mit ".fifo" hinzugefügt wird.

In letzter Zeit sind Tools für die lokale Entwicklung von Anwendungen verfügbar geworden, die unter AWS ausgeführt werden, was von Entwicklern sehr geschätzt wird.

Recommended Posts

Die Geschichte der Einführung eines sehr Rails-ähnlichen serverlosen Frameworks "Ruby on Jets" in die Produktionsumgebung
Eine Geschichte über die Einführung von Evolutions in das Play Framework
Einführung in Rspec, ein Testframework für Ruby on Rails
Ein Hinweis zum Seed-Feature von Ruby on Rails
So lösen Sie die lokale Umgebungskonstruktion von Ruby on Rails (MAC)!
[Ruby] Erstellen einer Ruby-Entwicklungsumgebung unter Ubuntu
Erstellen Sie eine Entwicklungsumgebung, um Ruby on Jets + React-Apps mit Docker zu erstellen
[Ruby on Rails] Implementieren Sie ein Kreisdiagramm, das den Prozentsatz der Farben angibt
[Ruby on Rails] Bis zur Einführung von RSpec
Eine sehr nützliche Geschichte über Rubys Struct-Klasse
[Ruby on Rails] Ein Memorandum mit Layoutvorlagen
Schreiben Sie einen Test, indem Sie die Geschichte von Mr. Nabeats in der Welt mit Rubin umsetzen
Erfahren Sie, was es bedeutet, den Pfad zu übergeben, indem Sie eine Java-Entwicklungsumgebung auf einem Mac erstellen