In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/01 Report--
This article will explain in detail how to develop Blog with the combination of Serverless and Flask framework. The content of the article is of high quality, so the editor shares it for you as a reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.
With the development of time, the Serverless architecture is becoming more and more popular. Its pay-per-view, flexible scaling and many other high-quality features make people shine in front of our eyes, and we have to marvel at the convenience that cloud computing brings to us.
This practice through the development of a blog system, and you simply experience what the blog system based on Serverless architecture is like.
Thinking before development
What functions does the blog system need? This article is only demo in nature, so it has less functionality, only two pages. It has the functions of article management, classification management, label management and message management. At the same time, in order to facilitate user management, there should be two parts: the foreground and the background.
What does the receptionist do? The foreground may have a large amount of user traffic (relative to the background), so this part uses a separate function. One function for each function, preliminary judgment of the foreground may require: get article classification, get article list, get comment list, add comments, get tag list and other interfaces.
How do you do it backstage? In theory, the background is the exclusive domain of the administrator, so this part of the traffic is relatively small, which can be solved by putting it into a function through flask-admin.
Why do you need so many functions in the foreground and a framework in the background? Isn't it good to use one framework for the whole project? First of all, it is OK to use one framework for the whole project, but it is not good. For example, the background of this project uses the Flask framework and flask-admin for background management. The development process is very simple. It may take about 100 lines of code to complete the whole background, but this involves:
To return a web page, APIGW is required to enable response integration. The performance of response integration is actually very poor, so relatively speaking, it is not suitable to be placed in the front end.
A complete project is relatively large and may require more resources, so we need to give this function more resource memory, which may lead to an increase in fees. For example, the resource given by my backend is 1024, and the memory resource given by each function in my frontend is 128ram 256. In the same time of execution, the cost of the latter is obviously reduced by 480 times. Similarly, the function may involve a large cold start, a cold start function and a complete framework / project in the cold start function, and the speed and performance of the former may be better
Functions have a concurrency limit. If all resources are requested to one function, it is likely that when the actual user concurrently has several functions, the concurrency of the functions used may be several hundred. This is likely to touch the upper limit of user instances when there are a little more users. The background function is infrequent, and the foreground is relatively more frequent, so it is more reasonable for the foreground to use a separate interface.
How to do the login function? Sorry, the function cannot cache some of the customer's login information to the machine like the traditional development, but the client can still use cookie, so using this method, you can do the following process:
At the login entrance at the background, pull the APIGW Event passed by APIGW to see if headers/cookie exists. If it does not exist, you will return to the login page.
If headers/cookie exists, take the token field in cookie to determine whether the token field matches the token field on the server, enters the system background, and returns to the login page if it does not match.
The user logs in and requests the login function of the backend. If the account password is correct, a token is returned to the user, and the client records the token in the cookie.
Here's the problem:
What is token? Token can be considered as a login credential, and the generation method can be upgraded according to your own design. This practice is relatively simple, just use the account password combination directly, and then md5.
Where is the token stored? How to get it next time? Token can be stored in Mysql database, Redis, or even COS, such as Redis and COS, which can make use of some of its own features to do some additional operations, such as data expiration (used for login expiration, etc.). Of course, this article doesn't want to be that troublesome, so every time a user requests to come over, it calculates the token separately and then makes a comparison.
Can this token login method be used for other projects? It is still only applicable to this kind of blog system. It can be applied to other projects, and many projects can be done in this way. For example, my own Anycodes is also authenticated through Token. However, under the Serverless architecture, how to store Token is a problem. But I personally recommend that you use redis if you have money, and cos if you have no money. Just like me, I use a separate comparison each time.
The existence of redis in token is understandable, but why is there cos? Cos itself is object storage, which is used to store files. In fact, it can be used to store token. For example, every time we generate a new token, we set the token to a file, and the content of the file is the corresponding user information of the token, or permission information, or other information, and then the bucket policy is set to the expiration time of the file. For example, if the file is stored for 1 day, it will be deleted automatically after 1 day. The token file you saved will be deleted. When the user comes over with token, directly request cos (no flow fee) to get the specified file name through the private network. If you get the file, download it back (the file is usually 1K or less), and then do other operations. If it does not exist, it will prove that the user has expired, or token error. Just let him log in again. Of course, this approach may not be the optimal solution, but it is an interesting approach under Serverless conditions. You can try it in small projects.
How to debug the local development of the project? It is well known that local debugging of Serverless schemas is difficult. Indeed, although it is difficult to debug locally, it is not impossible to get over it. You can do some debugging strategies according to the needs of the project.
Project development
The project development process is mainly the addition, deletion, modification and query of the database. In order to better adapt to the project development under the Serverless architecture, but also to improve the development efficiency of the project, this paper summarizes the relevant development skills and experience.
Database design
Because it is a simple blog, the design of the database is relatively simple, with only article table, classification table, tag table, comment table and so on. The overall ER diagram is as follows:
Local development and debugging
For development and debugging, I added a debugging scheme for corresponding triggers after each function, such as APIGW triggers, and I added the following code:
Def test (): event = {"requestContext": {"serviceId": "service-f94sy04v", "path": "/ test/ {path}", "httpMethod": "POST", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "identity": {"secretId": "abdcdxxxxxxxsdfs"} "sourceIp": "14.17.22.34", "stage": "release"}, "headers": {"Accept-Language": "en-US,en,cn", "Accept": "text/html,application/xml,application/json", "Host": "service-3ei3tii4-251000691.ap-guangzhou.apigateway.myqloud.com" User-Agent: "User Agent String"}, "body": json.dumps ({"id": 1}),.... .... } print (main_handler (event, None)) if _ _ name__ = = "_ _ main__": test ()
In fact, every time I want to see how it works, I execute this file:
{'id': 1,' title':', 'watched': 1,' category': 'Hot News', 'publish':' 2020-02-13 00 watched': 4515 52, 'tags': [],' next': {}, 'pre': {} {' uuid': '749ca9f6-4dfbmur11eamurc 9c5b acde48001122,' error': False, 'message':'}
It can be thought that some online environments are being simulated locally. Of course, if there are some functions that require intranet resources, such as redis, it will be more troublesome, but I can use it for most functions. Including the Flaks framework in the background:
Def test (): event = {'body':' name=sdsadasdsadasd&remark=', 'headerParameters': {},' headers': {'accept':' text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'accept-encoding':' gzip, deflate', 'accept-language':' zh-CN,zh QQ 0.9, 'cache-control':' no-cache', 'connection':' keep-alive', 'content-length':' 27, 'content-type':' application/x-www-form-urlencoded', 'cookie':' Hm_lvt_a0c900918361b31d762d9cf4dc81ee5b=1574491278,1575257377', 'endpoint-timeout':' 15, 'host':' blog.0duzhan.com', 'origin':' http://blog.0duzhan.com', 'pragma': 'no-cache',' proxy-connection': 'keep-alive',' referer': 'http://blog.0duzhan.com/admin/tag/new/?url=%2Fadmin%2Ftag%2F',' upgrade-insecure-requests': '1century,' user-agent': 'Mozilla/5.0 (Macintosh Intel Mac OS X 10x144a0d406a376809b03b008a0d406a376809b03b008a0d406a376809b008a0d406a3766622f3b008a0d406a376809b03b52csubscription, 'xmurf qualifier:' $LATEST'}, 'httpMethod':' POST', 'path':' / admin/tag/new/' 'pathParameters': {}, 'queryString': {' url':'/ admin/tag/'}, 'queryStringParameters': {},' requestContext': {'httpMethod':' ANY', 'identity': {},' path':'/ admin', 'serviceId':' service-23ybmuq7', 'sourceIp':' 119.123.224.87' 'stage':' release'}} print (main_handler (event, None)) if _ _ name__ = "_ _ main__": test ()
Index execution result:
{'body':' name=sdsadasdsadasd&remark=', 'headerParameters': {},' headers': {'accept':' text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'accept-encoding':' gzip, deflate', 'accept-language':' zh-CN,zh QQ 0.9, 'cache-control':' no-cache', 'connection':' keep-alive', 'content-length':' 27, 'content-type':' application/x-www-form-urlencoded', 'cookie':' Hm_lvt_a0c900918361b31d762d9cf4dc81ee5b=1574491278,1575257377', 'endpoint-timeout':' 15, 'host':' blog.0duzhan.com', 'origin':' http://blog.0duzhan.com', 'pragma': 'no-cache',' proxy-connection': 'keep-alive',' referer': 'http://blog.0duzhan.com/admin/tag/new/?url=%2Fadmin%2Ftag%2F',' upgrade-insecure-requests': '1century,' user-agent': 'Mozilla/5.0 (Macintosh Intel Mac OS X 10x144a0d406a376809b03b008a0d406a376809b03b008a0d406a376809b008a0d406a3766622f3b008a0d406a376809b03b52csubscription, 'true',' qualifier:'$LATEST'}, 'httpMethod':' POST', 'path':' / admin/tag/new/', 'pathParameters': {} 'queryString': {' url':'/ admin/tag/'}, 'queryStringParameters': {},' requestContext': {'httpMethod':' ANY', 'identity': {},' path':'/ admin', 'serviceId':' service-23ybmuq7', 'sourceIp':' 119.123.224.87, 'stage':' release'} {'isBase64Encoded': False,' statusCode': 200 'headers': {' Content-Type': 'text/html'},' body': 'nnn n Titlen n var url = _ window.location.hrefn url = url.split ("admin") [0] + "admin" n String.prototype.endWith = function (s) {n var d = this.length-s.length N return (d > = 0 & & this.lastIndexOf (s) = = d) n} n if _ (window.location.href! = url) {n if (! _ window.location.href.endsWith ("admin") | |! _ window.location.href.endsWith ("admin/") n _ window.location = urln} nn function doLogin () {n var xmlhttp = window.XMLHttpRequest? (new XMLHttpRequest (): (new ActiveXObject ("Microsoft.XMLHTTP")) n xmlhttp.onreadystatechange = function () {n if (xmlhttp.readyState = = 4 & & xmlhttp.status = = 200) {n if (JSON.parse (xmlhttp.responseText) ["token"]) {n [xss_clean] = "token=" + JSON.parse (xmlhttp.responseText) ["token"] N _ window.location = `http://${_window.location.host}/admin`n} else {n alert (JSON.parse (xmlhttp.responseText) ["message"]) n} n xmlhttp.open ("POST", _ window.location.pathname, true) N xmlhttp.setRequestHeader ("Content-type", "application/json"); n xmlhttp.send ({n "username": document.getElementById ("username"). Value,n "password": document.getElementById ("password") .value, n} n nnnnServerless Blog backend management n management account:
N Administrative password:
N% s) ") if articleType = =" next "else (" SELECT * FROM `roomle`WHERE aid= (select max (aid) from `roomle` where aid) "
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.