Django框架介绍
一、Django是基于python语言的后端框架,特点是集成度高,开发效率高。
MVC是众所周知的模式,即:将应用程序分解成三个组成部分:model(模型),view(视图),和 controller(控制器)。其中:
- M——管理应用程序的状态(通常存储到数据库中),并约束改变状态的行为
- V——负责把数据格式化后呈现给用户。
- C——接受外部用户的操作,根据操作访问模型获取数据,并调用“视图”显示这些数据。控制器是将“模型”和“视图”隔离,并成为二者之间的联系纽带。
二、 Django的MTV模式
- Model(模型):管理数据库数据(ORM)
- Template(模版):管理 html 文件
- View(视图):负责业务逻辑,并在适当的时候调用Model和Template
此外,Django还有一个urls分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template。
docker
docker是一个用Go语言实现的开源项目,可以让我们方便的创建和使用容器,docker将程序以及程序所有的依赖都打包到docker container,这样你的程序可以在任何环境都会有一致的表现,这里程序运行的依赖也就是容器就好比集装箱,容器所处的操作系统环境就好比货船或港口,程序的表现只和集装箱有关系(容器),和集装箱放在哪个货船或者哪个港口(操作系统)没有关系。
docker和虚拟机的区别:
- 每一台虚拟机都需要一个完整的操作系统,而且操作系统极大占用内存,因此我们没有办法划分出更过虚拟机从而部署更多的应用程序,可是我们部署的是应用程序,要用的也是应用程序而不是操作系统。
- 还有就是启动时间问题,我们知道操作系统重启是非常慢的,因为操作系统要从头到尾把该检测的都检测了该加载的都加载上,这个过程非常缓慢。
- 与虚拟机通过操作系统实现隔离不同,容器技术只隔离应用程序的运行时环境但容器之间可以共享同一个操作系统,这里的运行时环境指的是程序运行依赖的各种库以及配置。
- 从下图中我们可以看到容器更加的轻量级且占用的资源更少,与操作系统动辄几G的内存占用相比,容器技术只需数M空间,因此我们可以在同样规格的硬件上大量部署容器,这是虚拟机所不能比拟的,而且不同于操作系统数分钟的启动时间容器几乎瞬时启动,容器技术为打包服务栈提供了一种更加高效的方式。
镜像(image): 可以简单地理解为可执行程序
容器(container):相当于运行起来的进程
dockerfile就是image的源代码,docker就是"编译器"。
Nginx
Nginx 是使用C语言开发的一款自由的、开源的、高性能的HTTP服务器和反向代理服务器。 Nginx本身就可以托管网站(类似于Tomcat一样),进行Http服务处理,也可以用来做反向代理 、负载均衡和动静分离。
- Nginx本身是一个静态资源服务器,当只有静态资源的时候,就可以用Nginx来做服务器。所以当静态资源更新时,客户端也会同步更新;但当后台资源更新时,客户端不会同步更新,需要重新启动nginx服务,才能更新。
- Nginx配置文件中,包括全局块(配置指令),events块,http块,其中http块中可以包含多个server块,每个server块就相当于一个虚拟主机;每个server块也会包含一个或多个location块。
- 反向代理原理:通过监听端口号和server_name,以location /static {proxy_pass }的方式,将server_name/static打到代理服务器上。
- Nginx负载均衡:首先配置upstream负载均衡服务器(ip+port),然后用location将不同web页面任务打到负载均衡服务器上。
- 负载均衡方法:
——轮询(默认):每个请求按照时间顺序打到配置的服务器上。
——weight:weight代表权重,默认是1,权重越高被分配到的几率就越高。
——ip_hash:对用户ip进行hash,然后打到固定的服务器上,此ip永远打到相同的服务器。
——fair(第三方): 按照后端服务器的响应时间来分配请求,响应时间短的优先分配。 - 动静分离:所有动态资源的请求交给应用服务器,而静态资源的请求(例如图片、视频、CSS、JavaScript文件等)则直接由Nginx返回到浏览器,这样能大大减轻应用服务器的压力。
反向代理服务器
反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器;并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。反向代理服务器通常有两种模型,它可以作为内容服务器的替身,也可以作为内容服务器集群的负载均衡器。
uwsgi
uWSGI是一个web服务器,实现了WSGI协议、uwsgi协议、http协议等。uWSGI做为一款优秀的python应用服务器,擅长处理动态请求,而uWSGI服务器虽然也能够处理静态请求,但效率远不如nginx,并且从安全性和可扩展性方面来讲,使用nginx+uWsgi是最佳方式。所以,一般python后端开发一般采取nginx+uWSGI+Django/Flask应用的方式部署。
- 一般首先是浏览器发起 http 请求到 nginx 服务器,Nginx 根据接收到请求包,进行 url 分析,判断访问的资源类型:如果是静态资源,直接读取静态资源返回给浏览器。如果请求的是动态资源就转交给uWSGI服务器,uwsgi 服务器根据自身的 uwsgi 和 WSGI 协议,找到对应的 Django 框架/Flask框架,Django 框架/Flask框架下的应用进行逻辑处理后,将返回值发送到 uWSGI服务器,然后uWSGI服务器再返回给 nginx,最后 nginx将返回值返回给浏览器进行渲染显示给用户。其架构如下:
在acapp中nginx+uWsgi的工作原理是:
websocket和http的区别
- Http连接是一种短连接,是一种无状态的连接。Http会通过TCP建立起一个到服务器的连接通道,当本次请求需要的数据完毕后,Http会立即将TCP连接断开,这个过程是很短的。
- 早期用http协议想实现双向通信的方法是轮询和长轮询,浏览器需要不断的向服务器发出请求,然而HTTP请求头较长,其中真正有效的数据可能只是很小的一部分,显然这样会浪费大量带宽资源。
- websocket连接是一种长连接,一旦客户端和服务器通过TCP传输层连接,传输数据部分开始。这是一个双向传输通道(全双工),每个端都能独立、随意发送数据。
- 当建立 WebSocket 连接后,可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。
- websocket比http的请求头要小的多。
asgi
- ASGI(异步网关协议接口),一个介于网络协议服务和Python应用之间的标准接口,能够处理多种通用的协议类型,包括HTTP,HTTP2和WebSocket。
- ASGI对于WSGI原有的模式的支持和WebSocket的扩展,即ASGI是WSGI的扩展。
- 由于项目中需要使用webscoket进行实时通讯,但是生产环境又使用了Django+Nginx+uWSGI的部署方式,我们都知道uwsgi并不能处理websocket请求,所以需要asgi服务器来处理websocket请求,官方推荐的asgi服务器是daphne,daphne 服务器是最早为 Django_Channels 提供支持的 ASGI 服务器。
django_channels
django_channels 就是基于 wss (websockets)协议的一种实现,也就是说django_channels为 Django 项目添加 WebSocket 的支持。
- async/await:在 Python3.5 之后增加 async/await 特性之后,异步编程变得异常火爆,越来越多开发者投入异步的怀抱。使用async修饰将普通函数包装成异步函数(协程)在单线程环境中编写并发模型。
- 我的游戏项目中的同步通信:
(通信的逻辑基本都是先在本地完成,然后将结果返回给服务器,服务器再分发给其他客户端,达成同步)
(1)create-player : 在所有玩家的游戏界面,创建一个新加入的玩家
(2)move-to : 在所有玩家的游戏界面,将一个角色移动到一个位置
(3)shoot-fireball : 在所有玩家的游戏界面,让一个角色发射一个火球
(4)attack : 在所有玩家的游戏界面,让一个角色被攻击(注意:需在当前玩家界面进行判定) - redis使用:玩家的血量由server端维护,每一名玩家血量变化都需要通过wss协议广播给其他玩家,涉及数据读写,且要求延迟很低,故使用redis内存数据库。
- 在Django后台操作redis命令:
(1)cache.keys(’*’) # 查询redis里所有的关键字
(2)cache.set(‘gz’, 1, 5) # 插入一个key-val对,存在 5 s
(3)cache.has_key(‘abc’) # 查询是否有以abc为关键字的数据
(4)cache.get(‘yxc’) # 查询以yxc为关键字的value值
(5)cache.delete(‘yxc’) # 删除以yxc为关键字的数据
微服务架构 和 RPC框架
- RPC (Remote Procedure Call)远程过程调用是一个计算机通信协议。我们一般的程序调用是本地程序内部的调用,RPC允许你像调用本地函数一样去调用另一个程序的函数,这中间会涉及网络通信和进程间通信,但你无需知道实现细节,RPC框架为你屏蔽了底层实现。RPC是一种服务器-客户端(Client/Server)模式,经典实现是一个通过发送请求-接受回应进行信息交互的系统。
- RPC和微服务框架的关系:微服务框架一般都包含了RPC的实现和一系列「服务治理」能力,是一套软件开发框架。我们可以基于这个框架之上实现自己的微服务,方便的利用微服务框架提供的「服务治理」能力和RPC能力,所以微服务框架也被有些人称作RPC框架。
- 业界的一些微服务框架:
(1)Dubbo:是阿里巴巴公司开源的一个Java高性能优秀的服务框架
(2)Tars:腾讯内部使用的微服务架构 TAF(Total Application Framework)多年的实践成果总结而成的开源项目, 仅支持 C++ 语言。
(3)Motan:是新浪微博开源的一个Java 框架。
(4)Spring Cloud:国外 Pivotal 公司 2014 年对外开源的 RPC 框架,仅支持 Java 语言。
(5)gRPC:是Google开发的高性能、通用的开源RPC框架,支持多种语言。
(6)thrift:最初是由 Facebook 开发的内部系统跨语言的高性能 RPC 框架,支持多种语言。
消息队列
消息队列可以看作是一个存放消息的容器,当我们需要使用消息的时候,直接从容器中取出消息供自己使用即可。消息队列是分布式系统中重要的组件之一。使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。
消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。
- 通过异步处理提高系统性能(减少响应所需时间)
因为用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败。因此,使用消息队列进行异步处理之后,需要适当修改业务流程进行配合,比如加锁等操作。 - 削峰/限流
先将短时间高并发产生的事务消息存储在消息队列中,然后后端服务再慢慢根据自己的能力去消费这些消息,这样就避免直接把后端服务打垮掉。
- 降低系统耦合性
生产者(客户端)发送消息到消息队列中去,接受者(服务端)处理消息,需要消费的系统直接去消息队列取消息进行消费即可,而不需要和其他系统有耦合,这显然也提高了系统的扩展性。