1. Visão geral
A série de codelabs da estação de migração sem servidor (tutoriais práticos e individualizados) e os vídeos relacionados têm como objetivo ajudar desenvolvedores sem servidor do Google Cloud a modernizar apps, orientando-os em uma ou mais migrações, principalmente para evitar serviços legados. Isso torna seus apps mais portáteis e oferece mais opções e flexibilidade, o que permite a integração e o acesso a uma variedade maior de produtos do Cloud e o upgrade para versões de idiomas mais recentes com mais facilidade. Embora inicialmente voltada para os primeiros usuários do Cloud, principalmente desenvolvedores do App Engine (ambiente padrão), esta série é ampla o suficiente para incluir outras plataformas sem servidor, como o Cloud Functions e o Cloud Run, ou outros lugares, se aplicável.
O objetivo deste codelab é mostrar aos desenvolvedores do App Engine em Python 2 como migrar do Memcache do App Engine para o Cloud Memorystore (para Redis). Há também uma migração implícita do App Engine ndb
para o Cloud Node, mas ela é abordada principalmente no codelab do módulo 2. confira mais informações passo a passo.
Você vai aprender a
- Configurar uma instância do Cloud Memorystore (no Console do Cloud ou na ferramenta
gcloud
) - Configurar um conector de acesso VPC sem servidor do Cloud (no Console do Cloud ou na ferramenta
gcloud
) - Migrar do Memcache do App Engine para o Cloud Memorystore
- Implementar o armazenamento em cache com o Cloud Memorystore em um aplicativo de amostra
- Migrar do App Engine
ndb
para o Cloud NDB
O que é necessário
- Um projeto do Google Cloud com uma conta de faturamento ativa (este não é um codelab sem custo financeiro).
- Habilidades básicas em Python
- Conhecimento prático de comandos comuns do Linux
- Conhecimento básico sobre desenvolvimento e implantação de apps no App Engine
- Um app do App Engine do Módulo 12 em funcionamento (conclua o codelab do módulo 12 [recomendado] ou copie o app do módulo 12 do repositório)
Pesquisa
Como você usará este tutorial?
Como você classificaria sua experiência com Python?
Como você classificaria sua experiência de uso dos serviços do Google Cloud?
2. Contexto
Este codelab demonstra como migrar um aplicativo de amostra do App Engine Memcache (e do MapReduce) para o Cloud Memorystore (e o Cloud serviço). Esse processo envolve a substituição de dependências nos serviços agrupados no App Engine, o que aumenta a portabilidade dos aplicativos. Você pode optar por permanecer no App Engine ou considerar mudar para qualquer uma das alternativas descritas anteriormente.
Essa migração requer mais esforço em comparação com as outras desta série. A substituição recomendada para o Memcache do App Engine é o Cloud Memorystore, um serviço de armazenamento em cache totalmente gerenciado e baseado em nuvem. O Memorystore oferece suporte a um par de mecanismos conhecidos de armazenamento em cache de código aberto, o Redis e o Memcached. Este módulo de migração usa o Cloud Memorystore para Redis. Saiba mais na Visão geral do Memorystore e do Redis.
Como o Memorystore exige um servidor em execução, o Cloud VPC também é necessário. Especificamente, é necessário criar um conector de acesso VPC sem servidor para que o aplicativo do App Engine possa se conectar à instância do Memorystore pelo endereço IP particular. Ao concluir este exercício, você terá atualizado o aplicativo para que, embora ele se comporte como antes, o Cloud Memorystore será o serviço de armazenamento em cache, substituindo o serviço de Memcache do App Engine.
Este tutorial começa com o aplicativo de exemplo do Módulo 12 em Python 2, seguido por um upgrade secundário adicional e opcional para o Python 3. Se você já sabe como acessar os serviços incluídos no App Engine no Python 3 usando o SDK do App Engine para Python 3, comece com a versão para Python 3 do app de exemplo do Módulo 12. Isso implica a remoção do uso do SDK, já que o Memorystore não é um serviço incluído no App Engine. Aprender a usar o SDK do App Engine para Python 3 está fora do escopo deste tutorial.
Este tutorial apresenta as seguintes etapas principais:
- Configuração/pré-trabalho
- Configurar serviços de armazenamento em cache
- Atualizar os arquivos de configuração
- Atualizar aplicativo principal
3. Configuração/pré-trabalho
Preparar projeto do Cloud
Recomendamos reutilizar o mesmo projeto usado para concluir o codelab do módulo 12. Outra opção é criar um novo projeto ou reutilizar um projeto existente. Cada codelab desta série tem um "INÍCIO" (o código de referência para começar) e um "FINISH" (o app migrado). O código FINISH é fornecido para que você possa comparar suas soluções com as nossas caso tenha problemas. Você pode reverter para START de novo se algo der errado. Esses pontos de verificação são projetados para garantir que você tenha sucesso ao aprender como realizar as migrações.
Seja qual for o projeto do Cloud usado, verifique se ele tem uma conta de faturamento ativa. Verifique também se o App Engine está ativado. Leia estes tutoriais para entender as implicações gerais de custo. No entanto, ao contrário de outros itens desta série, este codelab usa recursos do Cloud que não têm um nível sem custo financeiro. Portanto, alguns custos serão gerados para a conclusão do exercício. Informações de custo mais específicas serão fornecidas juntamente com recomendações para redução de uso, incluindo instruções no final sobre como liberar recursos para minimizar cobranças de cobrança.
Receber app de amostra do valor de referência
A partir do código de referência do Módulo 12 que estamos começando, este codelab orienta você na migração em detalhes. Ao concluir, você terá um app funcional do Módulo 13 que se assemelha ao código de uma das pastas FINISH. Confira esses recursos:
- INICIAR: módulo 12 Python 2 (
mod12
) ou app Python 3 (mod12b
) - FINISH: módulo 13 em Python 2 (
mod13a
) ou app Python 3 (mod13b
) - Todo o repositório de migração (clonar ou fazer o download do ZIP)
A pasta START deve conter os seguintes arquivos:
$ ls README.md app.yaml main.py requirements.txt templates
Se você estiver começando pela versão do Python 2, também vai haver um arquivo appengine_config.py
e possivelmente uma pasta lib
se tiver concluído o codelab do Módulo 12.
(Re)implantar o app Módulo 12
Suas etapas de pré-trabalho restantes:
- Familiarize-se com a ferramenta de linha de comando
gcloud
(se necessário). - (Re)implantar o código do Módulo 12 no App Engine (se necessário)
Os usuários do Python 2 precisam excluir e reinstalar a pasta lib
com estes comandos:
rm -rf ./lib; pip install -t lib -r requirements.txt
Agora todos (usuários de Python 2 e 3) devem fazer upload do código para o App Engine com este comando:
gcloud app deploy
Após a implantação, confirme se o app tem a aparência e o funcionamento do app no Módulo 12, um app da Web que rastreia visitas, armazenando-as em cache para o mesmo usuário por uma hora:
Como as visitas mais recentes são armazenadas em cache, as atualizações da página devem carregar rapidamente.
4. Configurar serviços de armazenamento em cache
O Cloud Memorystore não funciona sem servidor. Uma instância é obrigatória. nesse caso, um executando o Redis. Ao contrário do Memcache, o Memorystore é um produto independente do Cloud e não tem um nível sem custo financeiro. Por isso, verifique as informações de preços do Memorystore para Redis antes de continuar. Para minimizar os custos desse exercício, recomendamos a menor quantidade de recursos para operar: um nível de serviço básico e uma capacidade de 1 GB.
A instância do Memorystore está em uma rede diferente do aplicativo do App Engine (instâncias). É por isso que é preciso criar um conector de acesso VPC sem servidor para que o App Engine possa acessar os recursos do Memorystore. Para minimizar os custos da VPC, opte pelo tipo de instância (f1-micro
) e pelo menor número de instâncias a serem solicitadas (sugerimos no mínimo 2, máximo de 3). Confira também a página de informações sobre preços da VPC.
Repetimos essas recomendações para reduzir custos à medida que orientamos você na criação de cada recurso necessário. Além disso, ao criar recursos do Memorystore e da VPC no console do Cloud, você verá a calculadora de preços de cada produto no canto superior direito, que fornece uma estimativa de custo mensal (consulte a ilustração abaixo). Esses valores serão ajustados automaticamente se você alterar as opções. Aproximadamente, isto é o que você deve ver:
Os dois recursos são necessários, e não importa qual deles você cria primeiro. Se você criar a instância do Memorystore primeiro, o aplicativo do App Engine não poderá acessá-la sem o conector de VPC. Da mesma forma, se você criar o conector VPC primeiro, não haverá nada nessa rede para o aplicativo do App Engine se comunicar. Neste tutorial, ensinamos como criar a instância do Memorystore primeiro e depois o conector de VPC.
Quando os dois recursos estiverem on-line, você vai adicionar as informações relevantes ao app.yaml
para que o app possa acessar o cache. Também é possível consultar os guias do Python 2 ou Python 3 na documentação oficial. Também vale a pena consultar o guia de armazenamento em cache de dados na página de migração do Cloud NBS ( Python 2 ou Python 3).
Criar uma instância do Cloud Memorystore
Como o Cloud Memorystore não tem um nível sem custo financeiro, recomendamos alocar a menor quantidade de recursos para concluir o codelab. Use estas configurações para manter os custos em um nível mínimo:
- Selecione o nível de serviço mais baixo: Básico (padrão do console: "Padrão",
gcloud
como padrão: "Básico"). - Escolha a menor quantidade de armazenamento: 1 GB (padrão do console: 16 GB,
gcloud
padrão: 1 GB). - Normalmente, as versões mais recentes de qualquer software exigem a maior quantidade de recursos, mas selecionar a versão mais antiga também não é recomendado. A segunda versão mais recente atualmente é a versão do Redis 5.0 (padrão do console: 6.x).
Com essas configurações em mente, a próxima seção mostra como criar a instância no console do Cloud. Se preferir fazer isso na linha de comando, pule para a próxima.
No Console do Cloud
Acesse a página do Cloud Memorystore no console do Cloud. Talvez você precise fornecer informações de faturamento. Se você ainda não ativou o Memorystore, será necessário fazer isso:
Depois de ativá-lo (e possivelmente junto com o faturamento), você chegará ao painel do Memorystore. É aqui que você pode ver todas as instâncias criadas no seu projeto. O projeto mostrado abaixo não tem nenhuma. É por isso que a mensagem "No rows to display" é exibida. Para criar uma instância do Memorystore, clique em Criar instância na parte de cima:
Esta página apresenta um formulário a ser preenchido com as configurações desejadas para criar a instância do Memorystore:
Para manter os custos baixos para este tutorial e o app de exemplo dele, siga as recomendações abordadas anteriormente. Depois de escolher as opções, clique em Criar. O processo de criação leva vários minutos. Quando terminar, copie o endereço IP da instância e o número da porta para adicionar a app.yaml
.
Na linha de comando,
Embora seja visualmente informativo criar instâncias do Memorystore no console do Cloud, alguns preferem a linha de comando. Confira se o gcloud
está instalado e inicializado antes de continuar.
Assim como no console do Cloud, é necessário ativar o Cloud Memorystore para Redis. Emita o comando gcloud services enable redis.googleapis.com
e aguarde a conclusão, como neste exemplo:
$ gcloud services enable redis.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Se o serviço já estiver ativado, executar o comando (novamente) não terá efeitos colaterais (negativos). Com o serviço ativado, vamos criar uma instância do Memorystore. O comando vai ficar assim:
gcloud redis instances create NAME --redis-version VERSION \ --region REGION --project PROJECT_ID
Escolha um nome para sua instância do Memorystore. este laboratório usa "demo-ms
" como o nome junto com um ID de projeto de "my-project
". A região deste app de exemplo é us-central1
(igual a us-central
), mas é possível usar uma região mais próxima de você se a latência for uma preocupação. Selecione a mesma região do seu aplicativo do App Engine. É possível selecionar a versão do Redis que você preferir, mas estamos usando a versão 5, conforme recomendado anteriormente. Com base nessas configurações, este é o comando que você emitiria (junto da saída associada):
$ gcloud redis instances create demo-ms --region us-central1 \ --redis-version redis_5_0 --project my-project Create request issued for: [demo-ms] Waiting for operation [projects/my-project/locations/us-central1/operations/operation-xxxx] to complete...done. Created instance [demo-ms].
Ao contrário dos padrões do Console do Cloud, o padrão de gcloud
é ter recursos mínimos. O resultado é que o nível de serviço e a quantidade de armazenamento não eram necessários naquele comando. A criação de uma instância do Memorystore leva vários minutos. Após a conclusão, anote o endereço IP e o número da porta da instância, porque eles serão adicionados ao app.yaml
em breve.
Confirmar criação da instância
No console do Cloud ou na linha de comando
Se você criou a instância no console do Cloud ou na linha de comando, confirme se ela está disponível e pronta para uso com este comando: gcloud redis instances list --region REGION
Este é o comando para verificar instâncias na região us-central1
e a saída esperada mostrando a instância que acabamos de criar:
$ gcloud redis instances list --region us-central1 INSTANCE_NAME VERSION REGION TIER SIZE_GB HOST PORT NETWORK RESERVED_IP STATUS CREATE_TIME demo-ms REDIS_5_0 us-central1 BASIC 1 10.aa.bb.cc 6379 default 10.aa.bb.dd/29 READY 2022-01-28T09:24:45
Quando as informações da instância ou a configuração do app forem solicitadas, use HOST
e PORT
(não RESERVED_IP
). O painel do Cloud Memorystore no console do Cloud agora exibirá essa instância:
Da máquina virtual do Compute Engine
Se você tem uma máquina virtual (VM) do Compute Engine, também pode enviar comandos diretos à instância do Memorystore de uma VM para confirmar que ela está funcionando. Esteja ciente de que o uso de uma VM pode ter custos associados independentemente dos recursos que você já usa.
Criar conector de acesso VPC sem servidor
Assim como acontece com o Cloud Memorystore, é possível criar o conector sem servidor do Cloud VPC no Console do Cloud ou na linha de comando. Da mesma forma, a VPC do Cloud não tem nível sem custo financeiro. Portanto, recomendamos alocar a menor quantidade de recursos para concluir o codelab para manter os custos no mínimo, e isso pode ser feito com estas configurações:
- Selecione o menor número máximo de instâncias: 3 (console e
gcloud
padrão: 10) - Escolha o tipo de máquina de menor custo:
f1-micro
(padrão do console:e2-micro
, sem o padrãogcloud
)
Na próxima seção, vamos mostrar como criar o conector no console do Cloud usando as configurações de VPC do Cloud acima. Se preferir fazer isso na linha de comando, pule para a próxima seção.
No console do Cloud
Acesse "Acesso à VPC sem servidor" do Cloud Networking no console do Cloud. Talvez você precise inserir informações de faturamento. Se você ainda não ativou a API, vai receber uma solicitação para fazer isso:
Depois de ativar a API (e possivelmente junto com o faturamento), você vai ver o painel que mostra todos os conectores de VPC criados. O projeto usado na captura de tela abaixo não tem nenhum, por isso diz “Nenhuma linha para exibir”. No console, clique em Criar conector na parte superior:
Preencha o formulário com as configurações desejadas:
Escolha as configurações apropriadas para seus próprios aplicativos. Para este tutorial e o app de exemplo dele com necessidades mínimas, faz sentido minimizar os custos. Portanto, siga as recomendações abordadas anteriormente. Depois de escolher as opções, clique em Criar. A solicitação de um conector de VPC vai levar alguns minutos para ser concluída.
Na linha de comando
Antes de criar um conector VPC, ative a API Serverless VPC Access. Você vai ver uma saída semelhante depois de executar o comando a seguir:
$ gcloud services enable vpcaccess.googleapis.com Operation "operations/acf.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Com a API ativada, um conector de VPC é criado com um comando parecido com este:
gcloud compute networks vpc-access connectors create CONNECTOR_NAME \ --range 10.8.0.0/28 --region REGION --project PROJECT_ID
Escolha um nome para o conector e um endereço IP inicial do bloco CIDR /28
não utilizado. Neste tutorial, pressupomos o seguinte:
- Project ID:
my-project
- Nome do conector de VPC:
demo-vpc
- Instâncias mínimas: 2 (padrão) e instâncias máximas: 3
- Tipo de instância:
f1-micro
- Região:
us-central1
- Bloco CIDR IPv4:
10.8.0.0/28
(conforme recomendado no console do Cloud)
Se você executar o comando a seguir pensando nas suposições acima, espere um resultado semelhante ao mostrado abaixo:
$ gcloud compute networks vpc-access connectors create demo-vpc \ --max-instances 3 --range 10.8.0.0/28 --machine-type f1-micro \ --region us-central1 --project my-project Create request issued for: [demo-vpc] Waiting for operation [projects/my-project/locations/us-central1/operations/xxx] to complete...done. Created connector [demo-vpc].
O comando acima omite a especificação de valores padrão, como o mínimo de instâncias de 2 e uma rede chamada default
. A criação de um conector de VPC leva vários minutos.
Confirmar criação do conector
Quando o processo for concluído, emita o seguinte comando gcloud
, supondo que se trate da região us-central1
, para confirmar que ele foi criado e está pronto para uso:
$ gcloud compute networks vpc-access connectors list --region us-central1 CONNECTOR_ID REGION NETWORK IP_CIDR_RANGE SUBNET SUBNET_PROJECT MIN_THROUGHPUT MAX_THROUGHPUT STATE demo-vpc us-central1 default 10.8.0.0/28 200 300 READY
Da mesma forma, o painel vai exibir o conector que você acabou de criar:
Anote o ID do projeto do Cloud, o nome do conector de VPC e a região.
Agora que você criou os recursos adicionais do Cloud necessários, seja pela linha de comando ou no console, é hora de atualizar a configuração do aplicativo para que eles possam ser usados.
5. Atualizar os arquivos de configuração
A primeira etapa é fazer todas as atualizações necessárias nos arquivos de configuração. O principal objetivo deste codelab é ajudar os usuários do Python 2 a fazer a migração. No entanto, em cada seção abaixo, o conteúdo geralmente é seguido com informações sobre como fazer a migração para o Python 3.
requirements.txt
Nesta seção, adicionaremos pacotes para oferecer suporte ao Cloud Memorystore e ao Cloud Firestore. No caso do Cloud Memorystore para Redis, basta usar o cliente Redis padrão para Python (redis
), já que não há uma biblioteca de cliente do Cloud Memorystore. Anexe redis
e google-cloud-ndb
a requirements.txt
, unindo flask
do Módulo 12:
flask
redis
google-cloud-ndb
Este arquivo requirements.txt
não tem números de versão, o que significa que as versões mais recentes foram selecionadas. Se houver incompatibilidades, especifique os números de versão para bloquear as versões em funcionamento.
app.yaml
Novas seções para adicionar
O ambiente de execução do App Engine para Python 2 exige pacotes de terceiros específicos ao usar as APIs do Cloud, como o Cloud NBS, ou seja, grpcio
e setuptools
. Os usuários do Python 2 precisam listar bibliotecas integradas como essas junto com uma versão disponível em app.yaml
. Se você ainda não tiver uma seção libraries
, crie uma e adicione as duas bibliotecas da seguinte maneira:
libraries:
- name: grpcio
version: latest
- name: setuptools
version: latest
Ao migrar seu app, talvez ele já tenha uma seção libraries
. Em caso afirmativo, e grpcio
e setuptools
estão ausentes, basta adicioná-los à seção libraries
existente.
Em seguida, nosso app de exemplo precisa das informações da instância do Cloud Memorystore e do conector de VPC. Portanto, adicione as duas novas seções a seguir a app.yaml
, independentemente do ambiente de execução do Python que você estiver usando:
env_variables:
REDIS_HOST: 'YOUR_REDIS_HOST'
REDIS_PORT: 'YOUR_REDIS_PORT'
vpc_access_connector:
name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR
Essas são as atualizações necessárias. Seu app.yaml
atualizado ficará assim:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
env_variables:
REDIS_HOST: 'YOUR_REDIS_HOST'
REDIS_PORT: 'YOUR_REDIS_PORT'
vpc_access_connector:
name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR
Confira abaixo um "antes e depois" ilustrando as atualizações que você deve aplicar a app.yaml
:
*Diferenças do Python 3
Esta seção é opcional e somente se você estiver migrando para Python 3. Para isso, é preciso fazer várias alterações na configuração do Python 2. Pule esta seção se você não estiver fazendo upgrade no momento.
threadsafe
e api_version
não são usados no ambiente de execução do Python 3. Portanto, exclua essas duas configurações. O ambiente de execução mais recente do App Engine não oferece suporte a bibliotecas integradas de terceiros nem à cópia de bibliotecas não integradas. O único requisito para pacotes de terceiros é listá-los no requirements.txt
. Como resultado, toda a seção libraries
de app.yaml
pode ser excluída.
Em seguida, o ambiente de execução do Python 3 exige o uso de frameworks da Web que façam roteamentos próprios. Por isso, mostramos aos desenvolvedores como migrar do webp2 para o Flask no módulo 1. Como resultado, todos os gerenciadores de script precisam ser alterados para auto
. Como esse app não veicula arquivos estáticos, ele é "sem sentido" para ter gerenciadores listados (já que todos são auto
), então toda a seção handlers
também pode ser removida. Como resultado, a nova versão abreviada app.yaml
ajustada para Python 3 precisa ser encurtada para ficar assim:
runtime: python39
env_variables:
REDIS_HOST: 'YOUR_REDIS_HOST'
REDIS_PORT: 'YOUR_REDIS_PORT'
vpc_access_connector:
name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR
Resumindo as diferenças em app.yaml
ao fazer a portabilidade para Python 3:
- Excluir as configurações de
threadsafe
eapi_version
- Excluir seção
libraries
- Exclua a seção
handlers
(ou apenas os gerenciadoresscript
, se o app exibir arquivos estáticos)
Substituir os valores
Os valores nas novas seções do Memorystore e do conector de VPC são apenas marcadores de posição. Substitua esses valores em letras maiúsculas (YOUR_REDIS_HOST, YOUR_REDIS_PORT, PROJECT_ID, REGION, CONNECTOR_NAME
) pelos valores salvos de quando você criou esses recursos anteriormente. Com relação à sua instância do Memorystore, use HOST
(não RESERVED_IP
) e PORT
. Esta é uma maneira rápida de linha de comando receber o HOST
e o PORT
, supondo que o nome de uma instância de demo-ms
e REGION
seja us-central1
:
$ gcloud redis instances describe demo-ms --region us-central1 \ --format "value(host,port)" 10.251.161.51 6379
Se o endereço IP da instância do Redis do nosso exemplo era 10.10.10.10
usando a porta 6379
no projeto my-project
, localizado na região us-central1
com o nome de conector de VPC demo-vpc
, essas seções em app.yaml
vão ficar assim:
env_variables:
REDIS_HOST: '10.10.10.10'
REDIS_PORT: '6379'
vpc_access_connector:
name: projects/my-project/locations/us-central1/connectors/demo-vpc
Criar ou atualizar appengine_config.py
Adicionar suporte a bibliotecas integradas de terceiros
Assim como fizemos com o app.yaml
anteriormente, adicione o uso das bibliotecas grpcio
e setuptools
. Modifique appengine_config.py
para oferecer suporte a bibliotecas integradas de terceiros. Isso parece familiar porque também era necessário no Módulo 2 ao migrar do ndb
do App Engine para o Cloud NBS. A mudança exata necessária é adicionar a pasta lib
ao conjunto de trabalho setuptools.pkg_resources
:
*Diferenças do Python 3
Esta seção é opcional e somente se você estiver migrando para Python 3. Uma das mudanças bem-vindas da segunda geração do App Engine é que a cópia (às vezes chamada de "fornecimento") de pacotes (não integrados) de terceiros e a referência a pacotes de terceiros integrados no app.yaml
não são mais necessárias, o que significa que é possível excluir todo o arquivo appengine_config.py
.
6. Atualizar arquivos do aplicativo
Como há apenas um arquivo de aplicativo, main.py
, todas as mudanças feitas na seção afetam apenas esse arquivo. Fornecemos uma representação pictórica das mudanças que serão feitas para migrar esse aplicativo para o Cloud Memorystore. Eles são apenas ilustrativos e não precisam ser analisados com cuidado. Todo o trabalho está nas mudanças que fazemos no código.
Vamos abordar cada seção, começando pelo topo.
Atualizar importações
A seção de importação em main.py
para o Módulo 12 usa o Cloud NBS e o Cloud Tasks. estas são as importações:
ANTES:
from flask import Flask, render_template, request
from google.appengine.api import memcache
from google.appengine.ext import ndb
Mudar para o Memorystore requer a leitura de variáveis de ambiente, o que significa que precisamos do módulo Python os
, bem como do redis
, o cliente Python Redis. Como o Redis não pode armazenar objetos Python em cache, organize a lista de visitas mais recentes usando pickle
. Portanto, importe-a também. Um benefício do Memcache é que a serialização de objetos acontece automaticamente, enquanto o Memorystore é um pouco mais "aprenda a fazer". Por fim, faça upgrade do App Engine ndb
para o Cloud Node. Para isso, substitua google.appengine.ext.ndb
por google.cloud.ndb
. Depois dessas alterações, as importações vão ficar assim:
DEPOIS:
import os
import pickle
from flask import Flask, render_template, request
from google.cloud import ndb
import redis
Atualizar inicialização
A inicialização do Módulo 12 consiste em instanciar o objeto de aplicativo Flask app
e definir uma constante para armazenamento em cache de uma hora:
ANTES:
app = Flask(__name__)
HOUR = 3600
O uso das APIs do Cloud requer um cliente. Portanto, instancie um cliente do Cloud NFS logo após o Flask. Em seguida, acesse o endereço IP e o número da porta da instância do Memorystore das variáveis de ambiente definidas em app.yaml
. Com essas informações, instancie um cliente Redis. Seu código ficará assim depois dessas atualizações:
DEPOIS:
app = Flask(__name__)
ds_client = ndb.Client()
HOUR = 3600
REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
REDIS_PORT = os.environ.get('REDIS_PORT', '6379')
REDIS = redis.Redis(host=REDIS_HOST, port=REDIS_PORT)
*Migração para Python 3
Esta seção é opcional e se você estiver começando pela versão Python 3 do aplicativo Módulo 12. Nesse caso, há várias mudanças necessárias relacionadas às importações e à inicialização.
Primeiro, como o Memcache é um serviço empacotado do App Engine, o uso dele em um aplicativo Python 3 exige o SDK do App Engine, especificamente encapsulando o aplicativo WSGI (bem como outra configuração necessária):
ANTES:
from flask import Flask, render_template, request
from google.appengine.api import memcache, wrap_wsgi_app
from google.appengine.ext import ndb
app = Flask(__name__)
app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
HOUR = 3600
Como estamos migrando para o Cloud Memorystore, e não um serviço incluído no App Engine, como o Memcache, o uso do SDK precisa ser removido. Isso é simples, já que você exclui a linha inteira que importa memcache
e wrap_wsgi_app
. Exclua também a linha que chama wrap_wsgi_app()
. Essas atualizações deixam essa parte do aplicativo (na verdade, o aplicativo inteiro) idêntica à versão do Python 2.
DEPOIS:
import os
import pickle
from flask import Flask, render_template, request
from google.cloud import ndb
import redis
app = Flask(__name__)
ds_client = ndb.Client()
HOUR = 3600
REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
REDIS_PORT = os.environ.get('REDIS_PORT', '6379')
REDIS = redis.Redis(host=REDIS_HOST, port=REDIS_PORT)
Por fim, remova o uso do SDK de app.yaml
(exclua a linha: app_engine_apis: true
) e requirements.txt
(exclua a linha: appengine-python-standard
).
Migrar para o Cloud Memorystore (e Cloud NBS)
O modelo de dados do Cloud NBS precisa ser compatível com os ndb
do App Engine, o que significa que a definição dos objetos Visit
permanece a mesma. Imitando a migração do Módulo 2 para o Cloud NFS, todas as chamadas do Datastore em store_visit()
e fetch_visits()
são aumentadas e incorporadas em um novo bloco with
, já que o uso do gerenciador de contexto do Cloud NBS é necessário. Estas são as chamadas antes dessa mudança:
ANTES:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
Adicione um bloco with ds_client.context()
às duas funções e coloque as chamadas do Datastore dentro delas (e com recuo). Nesse caso, não é necessário fazer mudanças nas chamadas:
DEPOIS:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
A seguir, vamos analisar as alterações do armazenamento em cache. Esta é a função main()
do Módulo 12:
ANTES:
@app.route('/')
def root():
'main application (GET) handler'
# check for (hour-)cached visits
ip_addr, usr_agt = request.remote_addr, request.user_agent
visitor = '{}: {}'.format(ip_addr, usr_agt)
visits = memcache.get('visits')
# register visit & run DB query if cache empty or new visitor
if not visits or visits[0].visitor != visitor:
store_visit(ip_addr, usr_agt)
visits = list(fetch_visits(10))
memcache.set('visits', visits, HOUR) # set() not add()
return render_template('index.html', visits=visits)
O Redis tem o comando "get" e "definir" chamadas, assim como o Memcache. Tudo o que fazemos é trocar as respectivas bibliotecas de clientes, certo? Quase. Como mencionado anteriormente, não é possível armazenar em cache uma lista Python com o Redis, porque ela precisa ser serializada primeiro, algo que o Memcache cuida automaticamente. Portanto, na chamada set()
, "pickle" as visitas em uma string com pickle.dumps()
. Da mesma forma, ao recuperar visitas do cache, você precisa descartá-las com pickle.loads()
logo após get()
. Este é o gerenciador principal depois de implementar essas mudanças:
DEPOIS:
@app.route('/')
def root():
'main application (GET) handler'
# check for (hour-)cached visits
ip_addr, usr_agt = request.remote_addr, request.user_agent
visitor = '{}: {}'.format(ip_addr, usr_agt)
rsp = REDIS.get('visits')
visits = pickle.loads(rsp) if rsp else None
# register visit & run DB query if cache empty or new visitor
if not visits or visits[0].visitor != visitor:
store_visit(ip_addr, usr_agt)
visits = list(fetch_visits(10))
REDIS.set('visits', pickle.dumps(visits), ex=HOUR)
return render_template('index.html', visits=visits)
Isso conclui as alterações necessárias no main.py
, convertendo o uso do Memcache do app de amostra para o Cloud Memorystore. E o modelo HTML e a portabilidade para Python 3?
Atualizar o arquivo do modelo HTML e a porta para o Python 3?
Surpresa! Não há nada a fazer aqui, já que o aplicativo foi projetado para ser executado em Python 2 e 3 sem nenhuma mudança de código nem bibliotecas de compatibilidade. Você vai encontrar main.py
. idêntico em todo o mod13a
(2.x) e mod13b
(3.x) "FINISH" do Google Cloud. O mesmo vale para requirements.txt
, exceto pelas diferenças nos números de versão (se usado). Como a interface do usuário permanece inalterada, não há atualizações para templates/index.html
.
Tudo o que é necessário para executar esse app no App Engine para Python 3 foi concluído anteriormente na configuração: diretivas desnecessárias foram removidas do app.yaml
e as pastas appengine_config.py
e lib
foram excluídas porque não são usadas no Python 3.
7. Resumo/limpeza
Esta seção encerra este codelab implantando o app, verificando se ele funciona conforme o esperado e em qualquer saída refletida. Após a validação do app, faça uma limpeza e considere as próximas etapas.
Implante e verifique o aplicativo
A última verificação é sempre implantar o app de exemplo. Desenvolvedores em Python 2: excluam e reinstalem lib
com os comandos abaixo. Se você tiver o Python 2 e o 3 instalados no sistema, talvez seja necessário executar explicitamente pip2
.
rm -rf ./lib pip install -t lib -r requirements.txt
Os desenvolvedores de Python 2 e 3 agora devem implantar os aplicativos com:
gcloud app deploy
Como você apenas reconfigurou as coisas em segundo plano para um serviço de armazenamento em cache completamente diferente, o aplicativo em si deve operar de forma idêntica ao aplicativo do Módulo 12:
Esta etapa conclui o codelab. Convidamos você a comparar seu app de exemplo atualizado com uma das pastas do Módulo 13, mod13a
(Python 2) ou mod13b
(Python 3).
Limpar
Geral
Se você já tiver terminado por enquanto, recomendamos que desative seu aplicativo do App Engine para evitar cobranças. No entanto, se você quiser fazer mais testes, saiba que a plataforma do App Engine tem uma cota sem custo financeiro e, desde que você não exceda esse nível de uso, não haverá cobranças. Isso é para computação, mas também pode haver cobranças por serviços relevantes do App Engine. Portanto, consulte a página de preços para mais informações. Se essa migração envolver outros serviços do Cloud, eles serão faturados separadamente. Em ambos os casos, se aplicável, consulte a seção "Específico para este codelab". seção abaixo.
Para divulgação completa, a implantação em uma plataforma de computação sem servidor do Google Cloud, como o App Engine, incorre em menores custos de criação e armazenamento. O Cloud Build tem a própria cota sem custo financeiro, assim como o Cloud Storage. O armazenamento da imagem consome parte da cota. No entanto, talvez você more em uma região que não tenha esse nível sem custo financeiro, portanto, esteja ciente do uso do armazenamento para minimizar os possíveis custos. "Pastas" específicas do Cloud Storage que você deve analisar incluem:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
- Os links de armazenamento acima dependem do
PROJECT_ID
e da *LOC
*ação, por exemplo, "us
" caso seu app esteja hospedado nos EUA.
Por outro lado, se você não for continuar com este aplicativo ou outros codelabs de migração relacionados e quiser excluir tudo completamente, encerre seu projeto.
Específicos deste codelab
Os serviços listados abaixo são exclusivos deste codelab. Consulte a documentação de cada produto para mais informações:
- o Cloud Memorystore requer instâncias e não tem um nível sem custo financeiro; Para saber mais sobre os custos de uso, consulte a página de preços.
- Os conectores de acesso VPC sem servidor do Cloud exigem instâncias e não têm um nível sem custo financeiro. Para saber mais sobre os custos de uso, confira a seção relacionada na página de preços do Cloud VPC.
- o Cloud Datastore (Cloud Firestore no modo Datastore) tem um nível sem custo financeiro; consulte a página de preços para mais informações.
Este tutorial envolveu o uso de quatro produtos do Cloud:
- App Engine
- Cloud Datastore
- Cloud Memorystore
- Cloud VPC
Confira abaixo as instruções para liberar esses recursos e evitar/minimizar cobranças de faturamento.
Encerrar a instância do Memorystore e o conector VPC
Esses são os produtos sem um nível sem custo financeiro. Você está recebendo o faturamento agora. Se você não encerrar seu projeto do Cloud (consulte a próxima seção), será necessário excluir a instância do Memorystore e o conector de VPC para interromper o faturamento. Assim como quando você criou esses recursos, também é possível liberá-los no console do Cloud ou na linha de comando.
No console do Cloud
Para excluir a instância do Memorystore, volte ao painel do Memorystore e clique no ID da instância:
Na página de detalhes da instância, clique em "Excluir" e confirme:
Para excluir o conector VPC, acesse o painel dele, marque a caixa de seleção ao lado do conector que você quer excluir e clique em "Excluir". e confirme:
Na linha de comando
O par de comandos gcloud
a seguir exclui a instância do Memorystore e o conector VPC, respectivamente:
gcloud redis instances delete INSTANCE --region REGION
gcloud compute networks vpc-access connectors delete CONNECTOR --region REGION
Se você não tiver definido o ID do projeto com gcloud config set project
, será necessário fornecer --project PROJECT_ID
. Se o nome da instância do Memorystore for demo-ms
e do conector da VPC forem demo-vpc
, e ambos estiverem na região us-central1
, emita os seguintes pares de comandos e confirme:
$ gcloud redis instances delete demo-ms --region us-central1 You are about to delete instance [demo-ms] in [us-central1]. Any associated data will be lost. Do you want to continue (Y/n)? Delete request issued for: [demo-ms] Waiting for operation [projects/PROJECT/locations/REGION/operations/operation-aaaaa-bbbbb-ccccc-ddddd] to complete...done. Deleted instance [demo-ms]. $ $ gcloud compute networks vpc-access connectors delete demo-vpc --region us-central1 You are about to delete connector [demo-vpc] in [us-central1]. Any associated data will be lost. Do you want to continue (Y/n)? Delete request issued for: [demo-vpc] Waiting for operation [projects/PROJECT/locations/REGION/operations/aaaaa-bbbb-cccc-dddd-eeeee] to complete...done. Deleted connector [demo-vpc].
Cada solicitação leva alguns minutos para ser executada. Essas etapas são opcionais se você optar por encerrar todo o seu projeto do Cloud, conforme descrito anteriormente. No entanto, você ainda vai receber cobranças até que o processo de encerramento seja concluído.
Próximas etapas
Além deste tutorial, outros módulos de migração que se concentram em abandonar os serviços em pacote legados a considerar incluem:
- Módulo 2: migrar do App Engine
ndb
para o Cloud NBS - Módulos 7 a 9: migrar de tarefas push da fila de tarefas do App Engine para o Cloud Tasks
- Módulos 12 a 13: migrar do Memcache do App Engine para o Cloud Memorystore
- Módulos 15 a 16: migrar do App Engine Blobstore para o Cloud Storage
- Módulos 18 a 19: migrar da fila de tarefas do App Engine (tarefas pull) para o Cloud Pub/Sub
O App Engine não é mais a única plataforma sem servidor do Google Cloud. Se você tem um aplicativo pequeno do App Engine ou com funcionalidade limitada e quer transformá-lo em um microsserviço independente ou quer dividir um aplicativo monolítico em vários componentes reutilizáveis, estes são bons motivos para migrar para o Cloud Functions. Se a conteinerização se tornou parte do fluxo de trabalho de desenvolvimento de aplicativos, principalmente se consistir em um pipeline de CI/CD (integração/entrega contínua ou implantação), considere migrar para o Cloud Run. Esses cenários são abordados nos seguintes módulos:
- Migrar do App Engine para o Cloud Functions: consulte o Módulo 11
- Migrar do App Engine para o Cloud Run: consulte o Módulo 4 para conteinerizar seu app com o Docker ou o Módulo 5 para fazer isso sem contêineres, conhecimento do Docker ou
Dockerfile
s
A mudança para outra plataforma sem servidor é opcional. Recomendamos considerar as melhores opções para seus apps e casos de uso antes de fazer qualquer mudança.
Seja qual for o módulo de migração que você considerar a seguir, todo o conteúdo da estação de migração sem servidor (codelabs, vídeos, código-fonte [quando disponível]) pode ser acessado no repositório de código aberto. O README
do repositório também fornece orientações sobre quais migrações considerar e qualquer "ordem" relevante. de módulos de migração.
8. Outros recursos
Abaixo estão listados recursos adicionais para desenvolvedores que querem explorar melhor esse Módulo de migração ou o relacionado, assim como produtos relacionados. Isso inclui locais para fornecer feedback sobre esse conteúdo, links para o código e várias documentações que podem ser úteis.
Problemas/feedback sobre codelabs
Se você encontrar problemas com este codelab, pesquise seu problema antes de preenchê-lo. Links para pesquisar e criar novos problemas:
Recursos de migração
Os links para as pastas do repositório do Módulo 12 (INÍCIO) e do Módulo 13 (FINISH) podem ser encontrados na tabela abaixo. Eles também podem ser acessados no repositório de todas as migrações de codelab do App Engine. Você pode clonar ou fazer o download de um arquivo ZIP.
Codelab | Python 2 | Python 3 |
Módulo 13 (este codelab) |
Referências on-line
Veja abaixo recursos on-line que podem ser relevantes para este tutorial:
App Engine
- Documentação do App Engine
- Ambiente de execução do App Engine para Python 2 (ambiente padrão)
- Como usar as bibliotecas integradas do App Engine no App Engine para Python 2
- Ambiente de execução do App Engine para Python 3 (ambiente padrão)
- Diferenças entre o Python 2 e o Três ambientes de execução do App Engine (ambiente padrão)
- Guia de migração do App Engine (ambiente padrão) Python 2 para 3
- Informações de preços e cotas do App Engine
O App Engine App Engine e o Cloud Node
- Visão geral do App Engine App Engine
- Uso do Datastore do App Engine do App Engine
- Documentos do Google Cloud NDB
- Repositório do Google Cloud NDB
- Informações sobre preços do Cloud Datastore
Memcache do App Engine e Cloud Memorystore
- Visão geral do Memcache do App Engine
- Referência
memcache
do App Engine para Python 2 - Referência
memcache
do App Engine para Python 3 - Guia de migração do App Engine
memcache
para o Cloud Memorystore - Documentação do Cloud Memorystore
- Documentação do Cloud Memorystore para Redis
- Informações sobre preços do Cloud Memorystore para Redis
- O Cloud Memorystore era compatível com versões do Redis
- Página inicial do Cloud Memorystore
- Crie uma nova instância do Memorystore no console do Cloud
- Página inicial do cliente Python Redis
- Documentação da biblioteca de cliente para Python Redis
Cloud VPC
- Documentos da VPC do Google Cloud
- Página inicial da VPC do Google Cloud
- Informações sobre preços do Cloud VPC
- Criar um novo conector de acesso VPC sem servidor no console do Cloud
Outras informações sobre a nuvem
- Python no Google Cloud Platform
- Bibliotecas de cliente do Python para Google Cloud
- "Sempre sem custo financeiro" do Google Cloud nível
- SDK Google Cloud (ferramenta de linha de comando
gcloud
) - Toda a documentação do Google Cloud
Licença
Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.