如何 运行 Google App Engine 应用无限期
How to run Google App Engine app indefinitely
我在 Google App Engine 上成功部署了一个 Twitter 截图机器人。
这是我第一次部署。
我注意到的第一件事是,在我单击 link 之前,应用程序没有启动 运行。
当我这样做时,只要选项卡正在加载和打开,该应用程序就会成功运行(回复带有屏幕截图的推文)。
当我关闭标签时,机器人停止工作。
另外,在云端shell日志中,我看到:
Handling signal: term
[INFO] Worker exiting (pid 18)
这种行为让我感到惊讶,因为我预计它会无限期地在 google 服务器上保留 运行。
我的机器人通过使用 Twitter api 进行流式传输来工作。上面的“工人退出”行也让我感到惊讶。
相关代码如下:
def get_stream(set):
global servecount
with requests.get(f"https://api.twitter.com/2/tweets/search/stream?tweet.fields=id,author_id&user.fields=id,username&expansions=author_id,referenced_tweets.id", auth=bearer_oauth, stream=True) as response:
print(response.status_code)
if response.status_code == 429:
print(f"returned code 429, waiting for 60 seconds to try again")
print(response.text)
time.sleep(60)
return
if response.status_code != 200:
raise Exception(
f"Cannot get stream (HTTP {response.status_code}): {response.text}"
)
for response_line in response.iter_lines():
if response_line:
json_response = json.loads(response_line)
print(json.dumps(json_response, indent=4))
if json_response['data']['referenced_tweets'][0]['type'] != "replied_to":
print(f"that was a {json_response['data']['referenced_tweets'][0]['type']} tweet not a reply. Moving on.")
continue
uname = json_response['includes']['users'][0]['username']
tid = json_response['data']['id']
reply_tid = json_response['includes']['tweets'][0]['id']
or_uid = json_response['includes']['tweets'][0]['author_id']
print(uname, tid, reply_tid, or_uid)
followers = api.get_follower_ids(user_id='1509540822815055881')
uid = int(json_response['data']['author_id'])
if uid not in followers:
try:
client.create_tweet(text=f"{uname}, you need to follow me first :)\nPlease follow and retry. \n\n\nIf there is a problem, please speak with my creator, @JoIyke_", in_reply_to_tweet_id=tid, media_ids=[mid])
except:
print("tweet failed")
continue
mid = getmedia(uname, reply_tid)
#try:
client.create_tweet(text=f"{uname}, here is your screenshot: \n\n\nIf there is a problem, please speak with my creator, @JoIyke_", in_reply_to_tweet_id=tid, media_ids=[mid])
#print(f"served {servecount} users with screenshot")
#servecount += 1
#except:
# print("tweet failed")
editlogger()
def main():
servecount, tries = 1, 1
rules = get_rules()
delete = delete_all_rules(rules)
set = set_rules(delete)
while True:
print(f"starting try: {tries}")
get_stream(set)
tries += 1
如果这很重要,我的 app.yaml
文件只有一行:
runtime: python38
并且我使用 gcloud app deploy app.yaml
从云 shell 部署了应用程序
我能做什么?
我已经搜索过,但似乎找不到解决方案。此外,这是我第一次成功部署应用程序。
谢谢。
App Engine 按需工作,即只有在对应用程序发出请求时才会启动(这就是为什么当您单击 URL 应用程序工作时)。您也可以将 1 个实例设置为“运行一直都在”(min_instances) it will be an anti-pattern for what you want to accomplish and App Engine. Please read How Instances are Managed
查看您的代码,您每分钟都在从 Twitter 中提取数据,因此对您来说最好的选择是使用 Cloud Scheduler + Cloud Functions.
Cloud Scheduler 将调用您的函数,它会检查是否有数据要处理,如果没有则进程终止。这将帮助您节省成本,因为该功能不会一直 运行ning,而是只在需要的时间工作。
另一方面,我不是 Twitter API 的专家,但如果有一种方法可以代替从 [=23= 中提取数据]Twitter 和 Twitter 直接调用你的函数它会更好,因为你可以优化你的成本并且函数只会 运行 当有数据要处理时每 n
分钟检查一次。
作为建议,首先查看您在 GCP 中拥有的所有选项或您将使用的提供商,然后选择最适合您的用例的选项。在这种情况下,仅选择适合您的编程语言的编程语言不一定会像您期望的那样工作。
Google App Engine 按需工作,即当它收到 HTTP(s) 请求时。
Warmup 请求和 min_instances > 0 都不能满足您的需求。在您的请求进入之前,预热会尝试 'start up' 一个实例。 A min_instance > 0 只是说不要杀死该实例,但您仍然需要一个 http 请求来调用该服务(这是您所做的打开浏览器选项卡并输入您的应用 url)。
您可能会问 - 既然您通过打开浏览器选项卡获得了 'started up' 实例,为什么之后它不保留 运行?答案是,对 Google App Engine(标准)应用程序的每个请求都必须在您的应用程序使用的 1 - 10 分钟内完成(取决于缩放类型)(参见 documentation)。对于 Google App Engine Flexible,超时时间最长为 60 分钟。这告诉您您的服务将在 GAE 标准最多 10 分钟或 GAE 灵活 60 分钟后超时。
我认为在 GCP 上最适合您的解决方案是使用 Google Compute Engine (GCE)。启动虚拟服务器(选择最低配置,这样您就可以留在免费层内)。如果您使用 GCE,则意味着您启动了一个虚拟机 (VM),将您的代码部署到其中并启动您的代码。然后您的代码会连续运行。
我在 Google App Engine 上成功部署了一个 Twitter 截图机器人。 这是我第一次部署。
我注意到的第一件事是,在我单击 link 之前,应用程序没有启动 运行。 当我这样做时,只要选项卡正在加载和打开,该应用程序就会成功运行(回复带有屏幕截图的推文)。 当我关闭标签时,机器人停止工作。
另外,在云端shell日志中,我看到:
Handling signal: term
[INFO] Worker exiting (pid 18)
这种行为让我感到惊讶,因为我预计它会无限期地在 google 服务器上保留 运行。 我的机器人通过使用 Twitter api 进行流式传输来工作。上面的“工人退出”行也让我感到惊讶。
相关代码如下:
def get_stream(set):
global servecount
with requests.get(f"https://api.twitter.com/2/tweets/search/stream?tweet.fields=id,author_id&user.fields=id,username&expansions=author_id,referenced_tweets.id", auth=bearer_oauth, stream=True) as response:
print(response.status_code)
if response.status_code == 429:
print(f"returned code 429, waiting for 60 seconds to try again")
print(response.text)
time.sleep(60)
return
if response.status_code != 200:
raise Exception(
f"Cannot get stream (HTTP {response.status_code}): {response.text}"
)
for response_line in response.iter_lines():
if response_line:
json_response = json.loads(response_line)
print(json.dumps(json_response, indent=4))
if json_response['data']['referenced_tweets'][0]['type'] != "replied_to":
print(f"that was a {json_response['data']['referenced_tweets'][0]['type']} tweet not a reply. Moving on.")
continue
uname = json_response['includes']['users'][0]['username']
tid = json_response['data']['id']
reply_tid = json_response['includes']['tweets'][0]['id']
or_uid = json_response['includes']['tweets'][0]['author_id']
print(uname, tid, reply_tid, or_uid)
followers = api.get_follower_ids(user_id='1509540822815055881')
uid = int(json_response['data']['author_id'])
if uid not in followers:
try:
client.create_tweet(text=f"{uname}, you need to follow me first :)\nPlease follow and retry. \n\n\nIf there is a problem, please speak with my creator, @JoIyke_", in_reply_to_tweet_id=tid, media_ids=[mid])
except:
print("tweet failed")
continue
mid = getmedia(uname, reply_tid)
#try:
client.create_tweet(text=f"{uname}, here is your screenshot: \n\n\nIf there is a problem, please speak with my creator, @JoIyke_", in_reply_to_tweet_id=tid, media_ids=[mid])
#print(f"served {servecount} users with screenshot")
#servecount += 1
#except:
# print("tweet failed")
editlogger()
def main():
servecount, tries = 1, 1
rules = get_rules()
delete = delete_all_rules(rules)
set = set_rules(delete)
while True:
print(f"starting try: {tries}")
get_stream(set)
tries += 1
如果这很重要,我的 app.yaml
文件只有一行:
runtime: python38
并且我使用 gcloud app deploy app.yaml
我能做什么? 我已经搜索过,但似乎找不到解决方案。此外,这是我第一次成功部署应用程序。 谢谢。
App Engine 按需工作,即只有在对应用程序发出请求时才会启动(这就是为什么当您单击 URL 应用程序工作时)。您也可以将 1 个实例设置为“运行一直都在”(min_instances) it will be an anti-pattern for what you want to accomplish and App Engine. Please read How Instances are Managed
查看您的代码,您每分钟都在从 Twitter 中提取数据,因此对您来说最好的选择是使用 Cloud Scheduler + Cloud Functions.
Cloud Scheduler 将调用您的函数,它会检查是否有数据要处理,如果没有则进程终止。这将帮助您节省成本,因为该功能不会一直 运行ning,而是只在需要的时间工作。
另一方面,我不是 Twitter API 的专家,但如果有一种方法可以代替从 [=23= 中提取数据]Twitter 和 Twitter 直接调用你的函数它会更好,因为你可以优化你的成本并且函数只会 运行 当有数据要处理时每 n
分钟检查一次。
作为建议,首先查看您在 GCP 中拥有的所有选项或您将使用的提供商,然后选择最适合您的用例的选项。在这种情况下,仅选择适合您的编程语言的编程语言不一定会像您期望的那样工作。
Google App Engine 按需工作,即当它收到 HTTP(s) 请求时。
Warmup 请求和 min_instances > 0 都不能满足您的需求。在您的请求进入之前,预热会尝试 'start up' 一个实例。 A min_instance > 0 只是说不要杀死该实例,但您仍然需要一个 http 请求来调用该服务(这是您所做的打开浏览器选项卡并输入您的应用 url)。
您可能会问 - 既然您通过打开浏览器选项卡获得了 'started up' 实例,为什么之后它不保留 运行?答案是,对 Google App Engine(标准)应用程序的每个请求都必须在您的应用程序使用的 1 - 10 分钟内完成(取决于缩放类型)(参见 documentation)。对于 Google App Engine Flexible,超时时间最长为 60 分钟。这告诉您您的服务将在 GAE 标准最多 10 分钟或 GAE 灵活 60 分钟后超时。
我认为在 GCP 上最适合您的解决方案是使用 Google Compute Engine (GCE)。启动虚拟服务器(选择最低配置,这样您就可以留在免费层内)。如果您使用 GCE,则意味着您启动了一个虚拟机 (VM),将您的代码部署到其中并启动您的代码。然后您的代码会连续运行。