最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

記一次django內存異常排查及解決方法

 更新時間:2020年08月07日 09:10:51   作者:syncd  
這篇文章主要給大家介紹了關于一次django內存異常排查記解決方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用django具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

起因

Django 作為 Python著名的Web框架,相信很多人都在用,自己工作中也有項目項目在用,而在最近幾天的使用中發(fā)現(xiàn),部署Django程序的服務器出現(xiàn)了內存問題,現(xiàn)象就是運行一段時間之后,內存占用非常高,最終會把服務器的內存耗盡,對于Python項目出現(xiàn)內存問題,自己之前處理過一次,所以并沒有第一次解決時的慌張,自己之前把解決方法也整理了:http://www.fzitv.net/article/151604.htm

但是事情似乎并沒有我想的那么簡單,自己嘗試用之前的的方法tracemalloc庫進行問題的排查,但是問題來了實際的項目中有快一百多個接口,怎么排查?難道一個一個接口進行測試排查,但是時間又比較緊急,可能又來不及了。對比上次自己解決是因為上次的項目比較簡單,相對來說定位問題比較容易,那么這次怎么處理呢?

處理過程

一般Python項目其實是很少出現(xiàn)內存問題的,一般都是自己代碼寫的有問題導致的,而對于這次出現(xiàn)的問題,自己的排查思路(對于web 接口類型的項目):

  1. 先排查調用比較頻繁的接口
  2. 然后排查數(shù)據(jù)匯總接口(查詢比較復雜)
  3. 如果上述還沒有查出來,再排查剩余的接口

在這次的問題排查中,自己大致也是按照這個思路進行的,在對調用頻繁的接口進行排查時,并沒有發(fā)現(xiàn)內存的異常,而出現(xiàn)內存的問題則是在數(shù)據(jù)匯總的相關接口上。

其實這種接口對于初級開發(fā)可能是容易出問題的地方,首先這種接口查詢的數(shù)據(jù)相對其他接口會比較復雜,如果編碼基礎又不是特別好,可能就會在這些接口上出現(xiàn)bug.

而在這次的排查中,最終確定是在一個匯總數(shù)據(jù)的接口上,定位到問題處在了Django ORM 使用不當導致的。自己通過一個簡單代碼實例來說明:

class Student(models.Model):
 name = models.CharField(max_length=20)
 name2 = models.CharField(max_length=20)
 name3 = models.CharField(max_length=20)
 name4 = models.CharField(max_length=20)
 name5 = models.CharField(max_length=20)
 name6 = models.CharField(max_length=20)
 name7 = models.CharField(max_length=20)
 name8 = models.CharField(max_length=20)
 name9 = models.CharField(max_length=20)
 name10 = models.CharField(max_length=20)
 name11 = models.CharField(max_length=20)
 name12 = models.CharField(max_length=20)
 name13 = models.CharField(max_length=20)
 name14 = models.CharField(max_length=20)
 name15 = models.CharField(max_length=20)
 age = models.IntegerField(default=0)

正常情況,我們的表字段會比較多,這里就通過多個name來模擬,出現(xiàn)題的代碼就出在關于這個表的接口上:

def index(request):
 studets = Student.objects.filter(age__gt=20)
 if studets:
  pass
 return HttpResponse("test memory")

為了讓內存問題容易復現(xiàn),我通過腳本向Student中插入了20000條數(shù)據(jù),當然這里數(shù)據(jù)越多,問題越明顯

通過一個測試腳本并發(fā)請求這個接口,觀察內存情況,你會發(fā)現(xiàn),內存會出現(xiàn)瞬間上漲的情況,并且如果你的數(shù)據(jù)越多,請求越多,你的內存可能會在一段時間居高不下,并且逐漸上漲。問題出在哪里了?

其實很簡單,問題出在了代碼中的if 判斷那里,我們通過filter 查詢返回的是QuerySet 類型的數(shù)據(jù),而我們過濾之后的數(shù)據(jù)可能會存在非常多的時候,這個時候我們通過if 直接判斷,自己的理解這個地方會將整個QuerySet加載到內存中,從而出現(xiàn)內存占用過高的問題,而如果并且這個時候這個接口的響應速度也是非常會變慢,而這個QuerySet 中的數(shù)據(jù)越多,內存占用越明顯。

在Django的文檔中其實做了說明

exists()¶
Returns True if the QuerySet contains any results, and False if not. This tries to perform the query in the simplest and fastest way possible, but it does execute nearly the same query as a normal QuerySet query.

exists() is useful for searches relating to both object membership in a QuerySet and to the existence of any objects in a QuerySet, particularly in the context of a large QuerySet.

The most efficient method of finding whether a model with a unique field (e.g. primary_key) is a member of a QuerySet is:

entry = Entry.objects.get(pk=123)
if some_queryset.filter(pk=entry.pk).exists():
 print("Entry contained in queryset")

Which will be faster than the following which requires evaluating and iterating through the entire queryset:

if entry in some_queryset:
 print("Entry contained in QuerySet")

And to find whether a queryset contains any items:

if some_queryset.exists():
 print("There is at least one object in some_queryset")

Which will be faster than:

if some_queryset:
 print("There is at least one object in some_queryset")

… but not by a large degree (hence needing a large queryset for efficiency gains).

Additionally, if a some_queryset has not yet been evaluated, but you know that it will be at some point, then using some_queryset.exists() will do more overall work (one query for the existence check plus an extra one to later retrieve the results) than using bool(some_queryset), which retrieves the results and then checks if any were returned.

所以對于我們的代碼我們只需要把if 判斷地方改成if not studets.exists() 就可以解決問題。

這是一個很小的知識點,但是如果使用不對,可能就會造成非常嚴重的內存問題。

總結

除了單元測試,還需要做大數(shù)據(jù)量測試,這次的問題如果在測試的時候做過一定數(shù)據(jù)量的測試,可能很早就能及時發(fā)現(xiàn)

問題

對于基礎的庫的使用要更加熟悉

排查問題的思路要明確,不然可能會無從下手

延伸閱讀

到此這篇關于django內存異常排查及解決方法的文章就介紹到這了,更多相關django內存異常排查內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Python發(fā)送郵件封裝實現(xiàn)過程詳解

    Python發(fā)送郵件封裝實現(xiàn)過程詳解

    這篇文章主要介紹了Python發(fā)送郵件封裝實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • 用python做游戲的細節(jié)詳解

    用python做游戲的細節(jié)詳解

    在本篇內容里小編給大家分享的是關于python做游戲的細節(jié)相關知識點內容,有需要的朋友們跟著學習下。
    2019-06-06
  • Python json格式化打印實現(xiàn)過程解析

    Python json格式化打印實現(xiàn)過程解析

    這篇文章主要介紹了Python json格式化打印實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07
  • Python機器學習庫之Scikit-learn基本用法詳解

    Python機器學習庫之Scikit-learn基本用法詳解

    Scikit-learn?是?Python?中最著名的機器學習庫之一,它提供了大量實用的機器學習算法以及相關的工具,可以方便我們進行數(shù)據(jù)挖掘和數(shù)據(jù)分析,在這篇文章中,我們將介紹?Scikit-learn?的基本使用,包括如何導入數(shù)據(jù)、預處理數(shù)據(jù)、選擇和訓練模型,以及評估模型的性能
    2023-07-07
  • python如何構建mock接口服務

    python如何構建mock接口服務

    這篇文章主要介紹了python如何構建mock接口服務,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2021-01-01
  • Python 切片索引越界的問題(數(shù)組下標越界)

    Python 切片索引越界的問題(數(shù)組下標越界)

    Python語言處理字符串、數(shù)組類的問題時有一定概率需要使用切片方法,本文主要介紹了Python 切片索引越界的問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Python批量圖片去水印的方法

    Python批量圖片去水印的方法

    ​平常工作中,有時為了采用網(wǎng)絡的一些素材,但這些素材往往被打了水印,如果我們不懂PS就無法去掉水印,或者無法批量去掉水印。本文就介紹了Python批量圖片去水印的方法,感興趣的可以了解一下
    2021-05-05
  • python3.x+pyqt5實現(xiàn)主窗口狀態(tài)欄里(嵌入)顯示進度條功能

    python3.x+pyqt5實現(xiàn)主窗口狀態(tài)欄里(嵌入)顯示進度條功能

    這篇文章主要介紹了python3.x+pyqt5實現(xiàn)主窗口狀態(tài)欄里(嵌入)顯示進度條功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-07-07
  • 分析Python字符串拼接+=和join()哪個速度更快

    分析Python字符串拼接+=和join()哪個速度更快

    這篇文章主要分析了Python中字符串拼接+=和join()哪個速度更快,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Python實現(xiàn)數(shù)據(jù)濾波的示例詳解

    Python實現(xiàn)數(shù)據(jù)濾波的示例詳解

    這篇文章主要為大家詳細介紹了Python實現(xiàn)數(shù)據(jù)濾波的相關知識,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以跟隨小編一起學習一下
    2024-03-03

最新評論

金昌市| 祁连县| 阿拉善盟| 红桥区| 泉州市| 平远县| 洛阳市| 平果县| 汶川县| 阿拉善盟| 红原县| 平乡县| 扎赉特旗| 池州市| 界首市| 浦县| 搜索| 澜沧| 雅安市| 连州市| 泌阳县| 龙泉市| 和硕县| 宁陵县| 翁牛特旗| 黑河市| 保亭| 行唐县| 吕梁市| 宜兴市| 桓仁| 古丈县| 和顺县| 武陟县| 鄂托克旗| 木里| 普兰县| 连州市| 鄂托克前旗| 娱乐| 威远县|