一直想项目,没怎么写过后端服务,但很多时候,有些服务又是公用的,平时一般都用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. 遇到bug怎么分析,这篇文章值得一看

    博主总结的非常到位:https://mp.weixin.qq.com/s/UpaLWjix2tnfTqybx9dmoQ 为什么定位问题如此重要? 可以明确一个问题是不是真的"bug" ...

  2. 使用 EMQX Cloud 桥接数据到 GCP Pub/Sub

    前不久,Google 宣布其旗下的 GCP IoT Core 即将在 2023 年 8 月 16 日停止提供服务.这意味着大量使用 GCP IoT Core 的用户可能需要将他们的 IoT 应用迁移到 ...

  3. BIP去掉弹框中的参照的新增按钮

    viewModel.get("material_class_name").on("afterInitVm", function (arg) {         ...

  4. Redis缓存中的数据和数据库不一致

    首先关于两者数据的一致性包含有两种情况: (1)缓存中有数据时,那数据库中的数据要和缓存中的数据相同: (2)缓存中没有数据时,数据库中的数据必须是最新的. 如果不符合以上两种情况,就属于缓存和数据库 ...

  5. Pods与Nodes

    Pod是Kubernetes抽象出来表示一组应用容器(比如Docker.rkt),还有这些容器共享的资源.这些资源包括: 共享存储,比如Volumes 网络,比如独立的集群IP地址 如何去运行每个容器 ...

  6. linux清除恶意程序流程-kdevtmpfsi清除

    TOP命令查看发现kdevtmpfsi进程跑满CPU, 处理如下: 解决过程 1.清除被新增的用户名和密码# 找到账户ID和权限组都是0跟root同级别的和不认识的, 删掉保存.   more /va ...

  7. WRF rsl.out文件研究

    本文翻译自https://www2.mmm.ucar.edu/wrf/users/FAQ_files/FAQ_wrf_runtime.html Q1 我应该使用几个处理器来运行wrf.exe? A1 ...

  8. 【Windows】Microsoft Store 应用列表

    更新优质微软商店应用: 『购买 WSA工具箱 - Microsoft Store zh-CN』 『购买 Apk安卓安装器 - Microsoft Store zh-CN』 『购买 KMS激活: Win ...

  9. SICP 笔记:环境配置

    SICP 笔记:环境配置 记录学习<算机的程序的构造和解释>的笔记. 环境配置 SICP 里面使用的语言是一种 Lisp 的变体 Scheme. 使用 DrRacket 作为 IDE 来进 ...

  10. 本地JAR包如何上传私有仓库

    需求背景 有些第三方的jar包需要手动上传到maven私有仓库,以便通过maven来管理依赖. 为简化手动上传的jar包的操作步骤,所以整了个脚本,在使用时只需修改相应变量即可. 脚本示例 #!/bi ...