一直想项目,没怎么写过后端服务,但很多时候,有些服务又是公用的,平时一般都用redis来当做通信的中间件,但这个标准的通用型与扩展信太差了.

与一些群友交流,建议还是起http服务比较好,自己也偏向与写一个后端服务,一来可以练手,二来分分钟可以部署到外网。

首先定型的是后端的框架为flask,没啥原因。但flask有一个问题就是通过自身内置的WSGI启动服务,会弹出警告,说该WSGI应用只能用于测试环境,不能用于工作环境,虽然以前部署了一个工作环境,也不知道具体效果,但出于完美的要求,网上随便专业的WSGI工作。

首先,不推荐uWSGI,因为我捣鼓了老半天,给我弹出编译安装的时候,gcc版本过高。我后面用了gunicorn, 这个pip安装方便多了。

这里写一写我自己的感悟,我的mac打字实在太卡了。明天到单位再码字吧

继续,继续。先来说一下我对于WSGI的理解,这个其实就是一个开启端口监控,并按照规定的协议,解析http协议内容,并调用框架写的试图函数。

(environ, start_response)

这是调用函数的参数,第一个environ是http请求过来的参数,第二个是后面响应需要的头部信息,函数的return是需要响应的response的响应体内容

有了这一层理解,所有的框架只不过是WSGI的调用函数内部的扩展,也就是通过读取environ的内容,然后内部定义具体逻辑,将start_response写入头部参数,

再更具实际需要是否提供响应体

有了这一层理解,就很好理解了。WSGI还负责接收解析http请求,如果没有nginx的前置,那所有请求的IO多路复用的任务就算交到他手上了,这里面就又涉及到IO多路复用的

SELECT,POLL,EPOLL,虽然我不能很好的理解相关具体内容,但大概的逻辑还是有的,都是通过操作系统提供的该方便,能够在一个进程的情况下,方便的监控维护多个IO连接。

因为如果一个IO开一条线程或者进程实在太浪费了,而且大多数时候一个连接并没有数据传输。就我自己的有限知识理解,因为IO传输涉及到中断,通过操作系统的中断信号,能够知道网卡是否有信号传输,然后IO的中断信号传输给EPOLL函数。通过一些标记就可以选出有数据需要读写的连接。前面的那套想法应该在EPOLL的时候应该是有的,我网上有查到一些资料,但SELECT与POLL未知,我就知道,说是每次轮询所有的连接,这样的话,传那个中断信号哦给它确实也没什么意思。

当取到一个需要读取信息的连接socket时,应用层已经及时取出在系统缓存区中的信息,第一不及时取出,浪费内存,第二,该连接的用户那边将无法及时获得响应。当一个应用层取出数据,然后逻辑处理,其中的逻辑处理,就是那些后端框架需要做的事情。

这里我记录一下,自己的感觉,当应用层收到需要操作的socket连接时,处理的两种方式,一种是开线程,还有一种就是所谓的异步操作协程。

就我个人理解,除非你的后端逻辑也都是异步协程操作,要不然还是老老实实的用开进程或者线程的逻辑,因为协程的操作是阻塞操作的地方都需要用到协程,对于一些数据库的操作,你必须都用到协程操作。我网上查tornado那个异步框架,据说连接处理用了EPOOL,然后内部的逻辑处理用了协程,但相关的联想出来的收缩就是阻塞了杂办,后面还是老老实实的开条线程去处理阻塞业务,要不然整个线程都卡住了。EPOOL的好处是能够快速的维护大量的连接socket,我怀疑tornado的快可能是在大量连接的时候,因为EPOOL的原因,能够快速找到处理的连接。

所以我个人认为,在数据库压力的范围内,没必要上协程或者EPOOL,就算EPOOL以及协程包括数据库的处理都是协程处理,但你的数据库顶的住吗?所以,一般的条件下,我自己还是选出简单的多线程就够了,关于多路复用更加无所谓了,普通网站没有那么高的并发,无论哪一种都够了。

上述的记录是自己的一些简单理解,如有不对还请指出

后面就是光遇requests的一些感悟吧,工作中,一次两个线程操作同一个requests.Sessioon。项目跑了很久了,两个线程也没有加锁,还想着两个线程操作着同一个socket连接,会出问题吗?其实我是多了吧了吗,当我用两个线程操作同一个线程的时候,其实框架的底部,已经给你做了连接池,两个线程默认情况下应该操作的是两个不同的socket连接。

这里有ression的介绍:https://requests.readthedocs.io/en/latest/user/advanced/

Session Objects

The Session object allows you to persist certain parameters across requests. It also persists cookies across all requests made from the Session instance, and will use urllib3’s connection pooling. So if you’re making several requests to the same host, the underlying TCP connection will be reused, which can result in a significant performance increase (see HTTP persistent connection).

然后我又去了urllib3网站,查看了具体的信息

网址: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#customizing-pool-behavior

最后在这个网站,作者进行了试验

网址: https://www.kawabangga.com/posts/2740

这里要感觉早一些时间大概的学习了一些计算机网络,当我们对一个计算机进行请求的时候,http首先要求的是tcp连接,所以在请求之前,必须要建立tcp连接,然后再发送具体的数据报文

这里就用到了连接池的作用,如果你发送完了数据,连接池可以帮助你维护着你的主机到请求目标服务器的连接,这样当你下次要发送内容的时候,无需从建立连接开发。直接拿一个连接好的socket发送数据既可。那为什么维护这些socket这么简单,不需要通过EPOOL,SELECT,POLL的方式,因为一般情况下,你请求服务器,服务器返回信息,处理完毕,后续服务器不会再主动给你发送信息, 就算给你发了信息,你也不需要了,缓存区满了以后,服务器那边想发通过这个连接也发不过来了。

这里我给自己再记录一下,我请求服务器,是一个主动行为,我可以把控所有的局面,但作为服务器来说就不一样,维护着一堆连接socket,你不知道下一秒哪一个会亮,所以必须一直监控着这些王八蛋

    def __init__(self, pool_connections=DEFAULT_POOLSIZE,
pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES,
pool_block=DEFAULT_POOLBLOCK):
if max_retries == DEFAULT_RETRIES:
self.max_retries = Retry(0, read=False)

上面是requests.Session的连接池默认的初始化,那个DEFAULT_POOLSIZE的值为10,也就是默认有10个连接池,一个池子10个连接。

一个池子对应着一个目标地址,也就是可以维护10个目标地址,每个目标地址10个连接。但如果你用了11个线程操作同一个目标地址,也没关系

多的一个,还会新开一个socket连接,只不过这个连接用完就丢了。

所以,简单的总结,就是爬虫的时候,如果多个线程使用同一个requests.Session,可以放心大胆的用,不用考虑线程安全问题。

两天的自学下来,乱七八糟写了一堆,写的不对请指出。收笔

WSGI网站部署以及requests请求的一些随想.的更多相关文章

  1. 利用WSGI来部署你的网站

    利用WSGI来部署你的网站 当需要部署你的django项目的时候,可以使用apache+python来部署访问你的网站. 由于网上的有关的都是老版本的.所以这里使用apache2.4和python3. ...

  2. 网站部署 HTTPS 中需要做的事情

    这篇文章首发于我的个人网站:听说 - https://tasaid.com/,建议在我的个人网站阅读,拥有更好的阅读体验. 这篇文章与 博客园 和 Segmentfault 共享. 前端开发QQ群:3 ...

  3. django+nginx+supervisor+gunicorn+gevent 网站部署

    django+nginx+supervisor+gunicorn+gevent 网站部署 django,nginx,supervisor,gunicorn,gevent这几个都是在本领域大名鼎鼎的软件 ...

  4. web爬虫,requests请求

    requests请求,就是用yhthon的requests模块模拟浏览器请求,返回html源码 模拟浏览器请求有两种,一种是不需要用户登录或者验证的请求,一种是需要用户登录或者验证的请求 一.不需要用 ...

  5. python使用requests请求的数据乱码

    1.首先进入目标网站,浏览器查看源码,找到head标签下面的meta标签,一般meta标签不止一个,我们只需找到charset属性里面的值即可 2.requests请求成功时,设置它的编码,代码如下 ...

  6. 第三百二十二节,web爬虫,requests请求

    第三百二十二节,web爬虫,requests请求 requests请求,就是用yhthon的requests模块模拟浏览器请求,返回html源码 模拟浏览器请求有两种,一种是不需要用户登录或者验证的请 ...

  7. Python flask网站部署总结

    先开一贴,有空来总结下前段时间的网站部署情况.此次部署采用Gunicorn + Nginx + supervisor的组合在VPS环境中部署flask网站应用. Ubuntu环境准备 准备python ...

  8. 解决爬虫浏览器中General显示 Status Code:304 NOT MODIFIED,而在requests请求时出现403被拦截的情况。

    在此,非常感谢 “完美风暴4” 的无私共享经验的精神    在Python爬虫爬取网站时,莫名遇到 浏览器中General显示  Status Code: 304 NOT MODIFIED 而在req ...

  9. 一 web爬虫,requests请求

    requests请求,就是用python的requests模块模拟浏览器请求,返回html源码 模拟浏览器请求有两种,一种是不需要用户登录或者验证的请求,一种是需要用户登录或者验证的请求 一.不需要用 ...

  10. requests请求库

    # coding = utf-8 """ 同urllib一样 requests 也是发送http请求的第三方库 兼容Python2和3 实现了http的绝大部分功能. 安 ...

随机推荐

  1. Nginx/1.13.3热升级1.21.6

    背景: 根据其服务器响应标头,安装的 nginx 版本为低于 1.16.1 的 1.9.5,或是低于 1.17.3 的 1.17.x.因此,它受到多种拒绝服务漏洞的影响: - HTTP/2 协议堆栈中 ...

  2. (0501)phase机制

    (1)启动seq: (2) 0312:

  3. NLP学习日记

    数据读取 下载csv文件后使用excel进行转存,然后用pandas读取,再把读取后转为numpy,numpy的tensor里.-1代表数组的最大维度,将原始数据集的标签和特征集分开,便于下一步的处理 ...

  4. 国产电源芯片DP4054 软硬件兼容TP4054 规格书资料

    DP4054 是一款完整的采用恒定电流/恒定电压单 节锂离子电池充电管理芯片.其SOT小封装和较少的外部元件数目使其成为便携式应用的理想器件,DP4054 可以适合USB 电源和适配器电源工作.跟进口 ...

  5. matlab读写文件操作

    文件相对路径 在编码中尽可能使用相对路径: 1.当前路径下,直接:' xxx.bin ' 2.在下一级路径下,使用:' .\下一级路径文件名\xxx.bin ' 3.在上一级路径下,使用:' ..\x ...

  6. wpf DataGrid相关总结

    1.去掉外边蓝框,设置BorderThickness="0"

  7. Optional中的map函数和flatMap函数的区别

    今天在学scala的时候发现Option中有map和flatMap返回的都是Option,然后再java8中的Optional也存在这样两个函数,觉得有点多余.后来分析了一下,还是有存在的必要的. 1 ...

  8. Flink Concept Timely Stream Processing -Flink概念及时流处理

    目录 介绍 时间概念:事件时间和处理时间 事件时间和水印 并行流中的水印 延迟 窗口 翻译来源- Concept Timely Stream Processing 介绍 及时的流处理是有状态流处理的扩 ...

  9. vue3.0使用富文本编辑器VueQuill

    1. npm install @vueup/vue-quill@alpha --save 2. 在main.js中全局引入 import { QuillEditor } from '@vueup/vu ...

  10. Ubuntu16.04系统语言设置为中文以及搜狗输入法的安装

    特别声明:本文是在操作完才做的记录,不是特别详细,见谅哈! 虚拟机安装的Ubuntu16.04结果语言设置只有英文...起初没啥影响,后来发现自己的脚本注释显示全乱码,而且直接影响脚本运行(其实可能是 ...