自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

疯哥哥带你飞

世间风云兮幻亦真,天地无穷兮大道行

  • 博客(112)
  • 收藏
  • 关注

原创 1. Tornado实现聊天室

Tornado的异步I/O机制使其很适合处理长连接的场景,在官方提供的Demo中就有一个简单的聊天室实现,大致做法如下:1. 提供一个全局的消息缓存2. 每次获取新消息时,如果缓存中没有新消息出现,则一直等待3. 前端使用ajax不断轮询新消息并显示,当没有新消息时,意味着前端会和tornado保持一个长时间不活跃的连接然后,使用Nginx来为Tornado做反向代理,使用Chro...

2018-08-10 16:45:24 1880

原创 1. RabbitMQ安装

RabbitMQ作为消息队列,在分布式系统中具有举足轻重的作用,能够方便地解耦各个组件;OpenStack之所以具有高扩展性,RabbitMQ功不可没。虽然一直都在用,但没有进行过系统的学习,最近借着学习Celery的机会,也计划对RabbitMQ进行深入一点的了解。下面学习下RabbitMQ在Ubuntu 14.04下的安装方法 ::1. 更新软件包列表apt-get update2. 安装Ra...

2018-03-24 16:16:10 321

原创 6. 消息发送重试

当连接失败,Celery会自动重试发送消息,我们可以对重试行为进行设置,譬如说多久重试一次、最大重试次数或者干脆不重试!当然这只是官方文档说的,我在Windows上进行测试,故意设置了局域网中没有使用的ip地址作为broker的地址,本来以为会像文档中讲的那样,在重试3次后返回并提示错误,结果死活不返回;查看配置文档,找了各种配置项进行修改,都是这样,后来在Linux下面运行就正常了!感觉Ce...

2018-03-23 18:35:08 593

原创 5. 任务状态追踪on_message

Celery支持捕获任务的所有状态变化,通过设置on_message回调函数,然后我写了以下代码,开始进行测试::import timefrom celery import Celeryfrom celery import statesapp = Celery('tasks', backend='amqp://agent:[email protected]...

2018-03-23 16:53:12 1406

原创 4. 任务限速Rate Limits

Celery真的有好多实用的特性,譬如今天学习的速率限制Rate Limits:我们在很多应用场景下可能需要对某些优先级不太高的任务进行限速,否则当此类任务产生的速度过快时,导致worker疲于奔命,从而导致高优先级的任务被饿死;此时Rate Limits就可以起作用了,我们可以给每个任务设置它们的rate limit,限制它们在一秒、一分或者一小时内能被每个worker处理的最大次数;注意,ra...

2018-03-22 18:49:46 2281

原创 多重继承

Python支持多重继承,但是多重继承势必会造成很多问题,譬如二义性;举栗子,假设类A继承类B和类C,类B和类C都实现了foo()方法,那么类A的实例对象在调用foo方法时, 是调用类B还是类C中的foo呢?Python中用于解决这种问题的算法就是MRO(Method Resolution Order),即方法解析顺序。很多文章中都讲了Python的MRO算法发展历史,包括Python2.2以前的...

2018-03-21 21:22:03 135

原创 3. Celery之主模块名字

我们在创建一个Celery app的时候,第一个参数需要指定主模块名字,大多数情况下我们都很随意,譬如用__name__; 这可能就造成了一个问题: 你使用Python解释器执行主模块来运行worker,然后client通过导入任务来异步执行某个任务,那么就会发现worker会如下错误:[2018-03-21 04:48:14,702: ERROR/MainProcess] Received un...

2018-03-21 17:21:37 1176

原创 2. Celery Bug: ValueError: need more than 0 values to unpack

按照Celery的官方文档,开始学习最简单的示例add,结果Celery worker收到任务后就报错了,错误堆栈如下:[2018-03-21 09:43:23,123: INFO/SpawnPoolWorker-2] child process 4404 calling self.run()[2018-03-21 09:43:23,207: INFO/SpawnPoolWorker-3] c...

2018-03-21 10:08:21 1199

原创 1. 开启Celery系统学习之路

在开发Web的过程中,用户可能在前端向后端提交一个比较费时的任务,那么显然不适宜在后端通过同步的方式进行处理;经过调研,选择了Celery这个分布式任务队列来进行解决,思路大致如下:1. 用户在前端提交一个任务2. 后端通过消息中间件向Celery worker传递此任务3. Celery worker处理接收到的任务,并将任务结果记录到Backend之前虽然一直在使用Celery,但是对Cele...

2018-03-21 10:00:21 275

原创 8. 事务隔离级别: 总结

通过前面的学习,我们可以总结出Mysql的4种事务隔离级别可能产生的问题如下所示:事务隔离界别脏读不可重复读幻读Read-Uncommitted(读未提交)有有有Read-Committed(读已提交)无有有Repeatable-Read(可重复读)无无有Serializable(可串行化)无无无通常生产实践中使用较多的事务隔离界别就是默认的Repeatable-Read和Read-Committ...

2018-03-20 13:03:01 469 2

原创 7.事务隔离级别之Serializable

最后我们学习一下最高的事务隔离级别Serializable,顾名思义,可串行化的,也即并发事务串行执行。很显然,该级别可以避免前面讲到的所有问题:“脏读”、“不可重复读”和“幻读”。代价是处理事务的吞吐量低,严重浪费数据库的性能,因此要慎用此事务隔离级别。下面演示Serializable如何解决这些问题:1. 小明连接数据库去查询自己本学期的成绩,他设置session(当前连接)的事务隔离级别为S...

2018-03-20 12:51:14 4994 4

原创 6. 事务隔离级别之Repeatable Read

接下来我们学习Mysql默认的事务隔离级别Repeatable Read,顾名思义,可重复读,也即在一个事务范围内相同的查询会返回相同的数据。延续上面的栗子:1. 小明很开心自己考了69分,于是他连接到数据库查询自己的成绩来炫耀给小伙伴,由于Repeatable Read是默认的事务隔离级别,因此这次他不需要进行修改:xiaoming> select @@tx_isolation;+---...

2018-03-20 11:32:09 10094

原创 5. 事务隔离级别之Read Committed

这篇我们学习事务隔离级别Read Committed,顾名思义,就是读已提交,一个事务只能看到其他并发的已提交事务所作的修改。很显然,该级别可以解决Read Uncommitted中出现的“脏读“问题。除了Mysql,很多数据库都以Read Committed作为默认的事务隔离级别。下面通过例子来演示Read Committed解决“脏读”:1. 小明连接数据库去查询自己本学期的成绩,他设置ses...

2018-03-20 11:03:43 25461 1

原创 4. 事务隔离级别之Read Uncommitted

前面我们说过,要获得最高的事务隔离性,可以采取序列化/串行的方式,代价是严重影响系统处理事务的吞吐量。就好像数据库是个多核CPU,事务串行后,那么意味着我们总是在使用单核,没办法发挥多核CPU的并行威力。基于以上这个问题,大多数的数据库实现都为使用者提供了多个事务隔离级别;Mysql提供的事务隔离级别有: Read Uncommitted,Read Committed,Repeatable Rea...

2018-03-20 10:26:50 15218

原创 3. 数据库事务

我们在开发数据库应用时,会遇到类似以下的场景:假设有个表users(id pk,name,age,sex)用于存放用户信息,有个表blogs(id pk, user_id fk, title, content)用于存放用户记录的博客信息,blogs的user_id字段记录博客拥有者的id。现在,我们需要删除某个用户,当然我们也会连同删掉其的博客信息delete from users where i...

2018-03-20 09:56:22 310

原创 HTTP基本认证

在最近的项目中,需要实现一个客户端,通过HTTP协议访问Web服务器,即C/S架构。使用客户端的功能前需要先进行登录认证,原本的设计是:客户端登录成功后,维护一个COOKIE用于保持当前的登录状态。但是最终的做法是,采用了”HTTP基本认证“,就是将用户的用户名和密码放在HTTP请求头部的Authorization字段中,当然不是放的明文,而是经过Base64编码过的,但是也毫无安全可言,因为Ba...

2018-03-19 14:51:58 733

原创 2. AUTO_INCREMENT 自增列

有些场景下,我们可能需要使用到自增列AUTO_INCREMENT,自增列必须为整数,当插入的数据中该字段值为0、或者不给值、给默认值,给null值,会触发自增,即系统会从该字段下当前的最大值进行+1操作然后赋给当前插入的记录。自增列有如下限制:1. 自增列必须为整数数据类型mysql> CREATE TABLE autoinc ( -> id char(10) AUTO...

2018-03-18 21:49:24 388

原创 1.内(外)连接、左(外)连接、右连接

目前有2个表:users和scores,它们的数据如下:可见, id为1的xiaoming在scores中没有对应的记录,同样,user_id为5的score在users中没有对应的记录mysql> SELECT * FROM users;+----+----------+| id | username |+----+----------+| 1 | xiaoming || 2 ...

2018-03-18 20:48:18 228

原创 生成器generator

Python提供了一个高级特性: 生成器,顾名思义,生成器就是不断生成结果的对象;那生成器有什么好处呢?假设我们现在需要对1亿以内的正整数做一个统计操作,那如果我们一次生成这么多整数,势必需要占用很大的内存空间,但是我们一次生成一个整数,然后下一次生成下一个整数,那么就只需要很少的内存即可,这里就是生成器的用武之地。生成器在惰性计算或者延迟处理的场景下非常有用,也即需要的时候才会产生结果,而不是一...

2018-03-18 11:36:07 365

原创 可迭代对象Iterable、迭代器Iterator

如果一个对象实现了__iter__方法,那么就是可迭代的IterablePython的collections模块提供了Iterable和Iterator这两个抽象类,可以让我们检测一个对象是否是可迭代的以及是否是迭代器In [16]: class MyIterable(object): ...: def __iter__(self): ...: return...

2018-03-18 11:16:18 339

原创 pdb调试

以前调试的时候,习惯用异常处理和print/logging输出信息的方式来进行。最近接触到一种新的调试方法,就是使用python自带的模块pdb(类比c的gdb)。1.python -m pdb <待执行py脚本>,进入pdb调试环境,进行单步执行2.import pdb   在待调试的地方插入pdb.set_trace() 设置断点,当程序执行至此,会暂停并进入pdb调试环境...

2018-03-16 20:06:07 198

原创 metaclass元类

在Python中一切皆为对象,class(类)作为模板同样也是对象。我们可以通过type在运行期间动态创建类,同样我们也可以通过metaclass(元类)来控制类的创建过程。简言之,我们可以先定义metaclass,然后使用它来创建(或者修改)class,这个class可以看成metaclass的实例,有点绕。下面我们使用metaclass来为我们自定义的MyString添加一个len方法:cla...

2018-03-16 19:05:58 221

原创 4. int类型之小整数对象池

Python假设小整数的使用频率非常高,所以使用对象池来避免小整数使用时频繁的创建工作。在Python初始化时,就会对这个小整数对象池进行初始化工作,具体就是创建小整数对应的对象。由于内存有限,故而不可能创建很多的小整数对象,所以需要定义小整数的范围,目前是-5到256,我们可以根据具体应用场景对此进行修改,然后重新编译Python解释器。/* intobject.c */#ifndef NSM...

2018-03-05 17:02:33 365

原创 3. 基本数据类型之int

不论何种编程语言,int都是很常见的基本数据类型之一,其定义如下:包含一个引用计数、一个指向类型对象的指针和一个long型值/* object.h */#ifdef Py_TRACE_REFS#define _PyObject_HEAD_EXTRA \ struct _object *_ob_next; \ struct _objec...

2018-03-05 16:47:29 1135

原创 2. 判断有符号整数(长整数)加法的溢出

在CPython的源码中,进行有符号整数的加法时,会进行溢出判断,以决定是否使用long型来存放结果,判断条件如下:int a, b, i;i = a + b;if ((i ^ a) < 0 && (i ^ b) < 0) printf("overflow\n");从上面可见(i ^ a) < 0 && (i ^ b) < 0是判...

2018-03-05 10:50:02 2675

原创 1. 将int类型转换为10进制字符串

在一个qq群遇到这样一个题目,首先int转字符串是比较常见的题目,书写起来并不难,但是有些临界条件容易出错而这个题目增加了几个限制条件,1. 参数、返回值无法修改2. 无法使用库函数,那我们当然无法使用itoa这样的库函数了3. 调用方不考虑内存释放,那意味着我们不能在堆区申请内存,上一条件与此有些契合,故此malloc这样的函数无法使用#define BUFFER_LEN 12const c...

2018-02-28 17:56:16 3477

原创 C内存空间分布

如上所示即为典型C内存空间分布图,从高地址向低地址进行说明:1.stack,即栈区,存放自动变量,以及函数调用时保存的信息。每当进行函数调用时,函数的实参和返回地址以及调用者的上下文环境会被存放在栈中;栈区由编译器自动分配,从高地址向低地址扩展,为什么会这样?我也不知道2.heap,即堆区,动态内存分配都是发生在堆区,堆区由程序员分配释放,或程序结束后由操作系统自动回收,从低地址向高地址扩展3.u...

2018-02-28 11:28:01 1174

原创 1.定长类型和变长类型

Python中一切皆对象,而一切对象皆有类型,而类型对象也有类型,理解起来有点绕!常用的类型有int、float、long、string、list、tuple、dict这些,而我们可以将这些类型分为以下2类:1. 定长类型int、float、long这些都是定长类型,且是不可变类型,即我们无法对这些类型的对象进行原地修改,我们通常看到的修改都是通过创建一个新的对象来实现的; 如下我们对一个long...

2018-02-28 09:38:55 3662

原创 1.工厂模式

from abc import ABC, abstractmethodclass Fruit(ABC): def __init__(self): self.name = None @abstractmethod def eat(self): passclass Apple(Fruit): def __init__(sel

2018-02-05 18:39:17 161

转载 设计模式之六大原则

1.开闭原则(Open Close Principle)对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。2.里氏代换原则(Liskov Substitution Principle)里氏代换原则是面向对象设计的基本原则之一: 任何基类可以出现的

2018-02-05 17:38:51 170

原创 协程踩坑记1

今天尝试着使用ucontext来实现一个轻量级的协程库,结果运行测试程序时,发生了段错误通过gdb调试发现错误是Cannot access memory at address,不过这个信息对我的帮助太小然后我加入了一些调试用的输出语句,就找到了真正的错误原因:我在创建一个协程时,需要传入一个执行函数,我对此函数进行了封装,作为makecontext的函数入口,这个封装函数会在原函数执行完毕后,做一...

2018-02-01 18:21:42 352

原创 协程之我见

在Python中我们知道关键字yield可以用来实现生成器,我们可以在函数A中访问生成器函数B,待B返回一个结果后,我们可以再次访问B,而B会延续之前的执行状态;这2个函数就像是2个线程一样,在宏观上看来在并行执行;但是与线程不同的是,线程的调度是由操作系统来完成的,对用户包括开发者来说是完全透明的,但是在这里2个函数的控制权切换却是由我们来完成的。从这里,我们就接触到协程的雏形。def A():...

2018-02-01 11:19:30 232

原创 使用Go开发HTTP服务器以及Benchmark测试

由于最近在学习Docker,而Docker是采用Go语言开发的;早就耳闻Go语言的威名,因此准备借机学习一下在学习了Go的原生HTTP库后,我写了个简单的HTTP服务器Demo,代码如下:// demo.gopackage mainimport ( "fmt" "net/http")func index(w http.ResponseWriter, req *h

2018-01-29 17:09:19 2417

原创 创建你的第一个Docker Services

前面我们通过创建一个Docker容器来运行我们的Web应用,已经初步了解了Docker的威力通常我们的Web应用没这么简单,一般至少包含一个Web服务器、一个数据库,我们称这二者为该App的Services;我们希望这些Services能作为一个整体进行管理,另外我们还要考虑服务的扩展、负载均衡等问题,万幸的是Docker已经为我们提供了解决方案。1. 编写我们的第一个docker-com

2018-01-24 17:03:57 387

原创 创建你的第一个Docker App

为了了解Docker到底是个什么东西,有什么作用,我们可以先参照Docker官方文档来创建我们的第一个Docker App,下面的步骤是在Ubuntu 16.04上进行的,其他系统可能只需要进行少量改动我们的第一个App是一个简单的Flask Web应用,使用Flask自带的单线程HTTP服务器运行1. 创建requirements.txt, 这个文件用来给pip安装Python库的,我们

2018-01-24 15:26:07 1933

原创 Ubuntu16.04部署Docker

下面是在Ubuntu 16.04上部署Docker的方法:设置软件仓库1. 更新apt软件包索引$ sudo apt-get update2. 为apt增加HTTPS方法, 以支持通过HTTPS访问软件仓库$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-commo

2018-01-24 11:59:43 413

原创 搭建私有Docker Registry

Registry是Docker的重要组件--镜像仓库, 与OpenStack的Glance有一些相似之处。我们可以使用Docker官方的Registry,但是可能会受到网络的影响,那么我们在本地搭建自己的私有Registry!下面是我在Ubuntu 14.04上搭建Docker Registry的具体过程:1.   docker-registry是使用Python来开发的,我们会使用p

2018-01-17 11:06:47 402

原创 Docker镜像加速

在pull Docker官方镜像的时候会发现io timeout错误,原因是无法访问docker.io; 那有什么办法来解决这个问题吗?我使用阿里云的镜像加速器来解决的,方法如下:1.   访问阿里云镜像加速器,使用淘宝账号登录,然后就可以获取专属加速器地址2.   修改docker服务的启动参数,使用systemd与否会影响修改的方法,判断方法如下:$ ls -d /run/sy

2018-01-16 18:33:44 724

原创 32.Nginx HTTP之ngx_http_handler函数

前面我们看到,在HTTP 0.9中处理完请求行后; 在HTTP>=1.0中处理完请求头后,Nginx会调用ngx_http_handler函数对请求进行处理。/* http/ngx_http_core_module.c *//* HTTP的phase事件处理函数 * param ev: 待处理的事件 */static void ngx_http_phase_event_han

2017-11-17 10:28:08 868

原创 31.Nginx HTTP之请求头解析函数ngx_http_parse_header_line

HTTP >= 1.0 的版本中,请求行后紧跟的就是请求头了,Nginx使用ngx_http_parse_header_line来对请求头进行解析。/* 解析HTTP请求头 * param r: 待处理的HTTP请求r * b: 存放请求头的缓冲区 * return : 解析完请求头的一行时返回NGX_OK; * 解析完整个请求头时返回NGX_HT

2017-11-16 18:34:52 2751

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除