gevent 使用踩坑
简单介绍
- gevent 基本概念:
调度器: hub
上下文切换管理: switch
主循环: loop
协程: greenlet - gevent 特性:
优点:
高效,实现简单,易维护
缺点:
和go不一样,并不是python原生支持的功能,所以使用起来难免会踩一些坑,但是由于并不是实现方式有问题,所以存在着点弊病并没有什么问题。
开始使用
- 什么情况下可以使用:
足够了解自己服务所使用的io, 写的代码足够规范,否则会出现出了问题都不知道那里有问题。
需要并行化的代码不能阻塞时间过长,否则没有意义。
存在大量的io, 前提是可以变成非阻塞的,否则不能满足条件2。 由于发现api的代码满足以上三条,所以开始进行优化:
第一版代码如下:classParallelTask(object):def__init__(self, timeout=5):# 覆盖python原生的socketgevent.monkey.patch_socket()self.timeout=timeoutself.task=[]deftaskAppend(self, task,*args):self.task.append(gevent.spawn(task,*args))defrun(self):errno, err_msg=get_error(AwemeStatus.SUCCESS)try:gevent.joinall(self.task, timeout=self.timeout)returnerrno, err_msgexceptException, ex:logger.exception("[ParallelTask] run task fail error=%s"%ex)errno, err_msg=get_error(AwemeStatus.REE_PARALLEL_TASK)returnerrno, err_msg# handlerdef__getAwemeList(self, category_id, req_type):pass# 创建一个并行处理的任务paralle_obj=ParallelTask()paralle_obj.taskAppend(self.__getAwemeList, category_id, req_type)errno, err_msg=paralle_obj.run()代码看似没有问题,自测也没发现什么问题。
- 上线观察:
果不其然,出问题了。。。
错误发生在 challengeDetail 接口, 也是奇怪,上的明明是category 接口。
不过看错误知道应该是掉RPC没有成功, 查看RPC的日志可以看到全是fail。 - 分析问题:
首先RPC失败肯定是由于使用gevent 引起的。但是我在这category使用gevent 为啥会影响challengeDetail 呢。
观察最上面的 ParallelTask 代码,里面使用了monkey patch , 没错就是这个东西,重写了python原生socket ,使其支持了非阻塞io。
所以在没有并行化的代码里使用RPC调用,里面使用的socket变成了非阻塞的,而这些调用不受hup控制,所以肯定会出现调用失败的情况。 解决:
解决办法很简单,在用完monkey patch 之后恢复原生的socket不久好了。 gevent 没有提供接口恢复,所以自己实现了下。defrepatching(item):try:# 需要重新写回的modulemodule=__import__(item)# 需要重写的属性saved=gevent.monkey.savedmapper=saved.get(item, {})forattrinmapper:old_value=mapper.get(attr)ifnotold_value:continuesetattr(module, attr, old_value)exceptException, ex:logger.exception("[gevent] repatching fail error=%s"%ex)classParallelTask(object):def__init__(self, timeout=5):# 覆盖python原生的socket, 使用完记得repatching 不然会有未知错误gevent.monkey.patch_socket()self.timeout=timeoutself.task=[]deftaskAppend(self, task,*args):self.task.append(gevent.spawn(task,*args))defrun(self):errno, err_msg=get_error(AwemeStatus.SUCCESS)try:gevent.joinall(self.task, timeout=self.timeout)returnerrno, err_msgexceptException, ex:logger.exception("[ParallelTask] run task fail error=%s"%ex)errno, err_msg=get_error(AwemeStatus.REE_PARALLEL_TASK)returnerrno, err_msgfinally:# 使用完非阻塞的网络io之后一定要改回来repatching('socket')- 线上观察:
bug 修复之后线上没有新的问题爆出来,至今稳定运行着, 本来打算用go优化的接口看样子也不需要了, 并行化之后接口的时延由3s 降低到了300ms, 降低的幅度也符合预期 (30个rpc并行)
gevent 使用踩坑的更多相关文章
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- 【踩坑速记】二次依赖?android studio编译运行各种踩坑解决方案,杜绝弯路,总有你想要的~
这篇博客,只是把自己在开发中经常遇到的打包编译问题以及解决方案给大家稍微分享一下,不求吸睛,但求有用. 1.大家都知道我们常常会遇到dex超出方法数的问题,所以很多人都会采用android.suppo ...
- NPOI导出Excel (C#) 踩坑 之--The maximum column width for an individual cell is 255 charaters
/******************************************************************* * 版权所有: * 类 名 称:ExcelHelper * 作 ...
- 我的微信小程序入门踩坑之旅
前言 更好的阅读体验请:我的微信小程序入门踩坑之旅 小程序出来也有一段日子了,刚出来时也留意了一下.不过赶上生病,加上公司里也有别的事,主要是自己犯懒,就一直没做.这星期一,赶紧趁着这股热乎劲,也不是 ...
- router路由去掉#!的踩坑记
项目中在研究去掉router#!的过程中的踩坑过程.
- vue+ vue-router + webpack 踩坑之旅
说是踩坑之旅 其实是最近在思考一些问题 然后想实现方案的时候,就慢慢的查到这些方案 老司机可以忽略下面的内容了 1)起因 考虑到数据分离的问题 因为server是express搭的 自然少 ...
- 记jQuery.fn.show的一次踩坑和问题排查
最近很少已经很少用jQuery,因为主攻移动端,常用Zepto,其实很多细节和jQuery并不一样.最近又无意中接触到了PC的需求和IE6, 使用了jQuery,刚好踩坑了,特意记录一下. 本文内容如 ...
- WebForm路由踩坑 ajax请求多次
WebForm路由踩坑 再次接触Asp.Net WebForm已是4年后的今天,源起新入职的公司,一个老的项目. Web接触的少,那就多动手写写. WebForm1.aspx <body> ...
随机推荐
- Java之instanceof
class Base{ int x = 1; static int y = 2; String name(){ return "mother" ...
- ThreadLocal遇到线程池时, 各线程间的数据会互相干扰, 串来串去
最近遇到一个比较隐蔽而又简单地问题,在使用ThreadLocal时发现出现多个线程中值串来串去,排查一番,确定问题为线程池的问题,线程池中的线程是会重复利用的,而ThreadLocal是用线程来做Ke ...
- php 正则符号说明
preg_match_all ("/<b>(.*)<\/b>/U", $userinfo, $pat_array); preg_match_all (&qu ...
- ZOJ 3626 Treasure Hunt I (树形DP,常规)
题意:给一棵树,一个人站在节点s,他有m天时间去获取各个节点上的权值,并且最后需要回到起点s,经过每条边需要消耗v天,问最少能收获多少权值? 思路: 常规的,注意还得跑回原地s. //#include ...
- HDU 3032 Nim or not Nim? (Nim,sg函数)
题意:给出几堆石子数量,每次可以取走一堆中任意数量的石头,也可以将一堆分成两堆,而不取.最后取走者胜. 思路:石子数量很大,不能直接算,sg打表找出规律:正常情况下a[i]=i,但是有例外的,就是i% ...
- CAD交互绘制圆形云线批注(网页版)
js中实现代码说明: 动态拖放时的绘制事件: function DoDynWorldDrawFun(dX,dY,pWorldDraw,pData) { //自定义实体的GUID标识符 var sGui ...
- JavaScript判断数组是否包含指定元素的方法
本文实例讲述了JavaScript判断数组是否包含指定元素的方法.分享给大家供大家参考.具体如下: 这段代码通过prototype定义了数组方法,这样就可以在任意数组调用contains方法 /** ...
- python小括号( )与中括号 [ ]
在python中小括号()表示的是tuple元组数据类型,元组是一种不可变序列. >>> a = (1,2,3) >>> a (1, 2, 3) >>& ...
- node mocha mochawesome报安装不成功
1.进行cnpm安装: npm install cnpm -g --registry=https://registry.npm.taobao.org 2.查看cnpm版本 cnpm -v 3.安装mo ...
- 一款App的开发成本是多少?
答一: 接触过上万名创业者,开发上线过超过30款App,没有比我更适合回答这个问题的了.. 本文对想做好一款App项目的人来说这是一篇价值百万的回答!因为这是我们花了几百万试错成本试出来的经验! &l ...