Thứ ba, 26/11/2013 | 00:00 GMT+7

Làm thế nào để mở rộng Django: Vượt ra ngoài những điều cơ bản


Bắt đầu


Bạn đã triển khai Django cho Server của bạn và cuộc sống vẫn tốt. Bạn đã gặp phải một số vấn đề về hiệu suất khi lưu lượng truy cập trang web tăng lên nhưng bạn đã tìm thấy điểm nghẽn và khắc phục nó. Tuy nhiên, lưu lượng truy cập trang web không ngừng tăng lên. Bằng cách nào đó bạn cần hiệu suất cao hơn… bạn có thể làm gì?

Hãy tìm hiểu sâu về cấu hình ứng dụng và server của ta một chút. Bài viết này được viết dựa trên giả định bạn đang sử dụng Ubuntu 12.04, nhưng các nguyên tắc hoạt động với bất kỳ version Linux nào.

Nếu bạn đang sử dụng Apache thì bạn nên làm theo các hướng dẫn để tối ưu hóa web server của bạn . Nếu bạn đang sử dụng Nginx, những mẹo này cũng sẽ hiệu quả với bạn.

Cache Mọi thứ


Nếu bạn đã tạo CMS để quản lý trang web của bạn , thì bạn có thể chịu được bộ nhớ đệm rất tích cực. Trong trường hợp đó, công cụ yêu thích của tôi là Varnish, một bộ nhớ đệm front-end nằm trước Apache hoặc Nginx. Trong trường hợp đó, hãy xem hướng dẫn hiện có này cho Apachehướng dẫn này cho Nginx (vâng, bài viết Nginx nói về PHP nhưng nó cũng sẽ hoạt động cho Django).

Nhược điểm là Varnish, trừ khi bạn cấu hình cẩn thận, sẽ lưu vào bộ nhớ cache toàn bộ trang web . Nếu bạn có nội dung động, chẳng hạn như nếu trang web thiên về ứng dụng, Varnish có thể gây ra nhiều rắc rối. Hãy tưởng tượng rằng user A truy cập trang web và thêm một mặt hàng vào giỏ hàng của họ. Sau đó, user B truy cập trang web và thấy version đã lưu trong bộ nhớ cache của giỏ hàng có mặt hàng của user A trong đó. Không tốt.

Một nhược điểm khác là Django, theo mặc định, cố gắng buộc các bộ nhớ đệm ngược dòng khỏi bộ nhớ đệm nội dung, điều này gây ra một chút trận chiến kết thúc bằng hành vi thất thường.

Nhưng tôi có tin tuyệt vời: Django có khung bộ nhớ cache của riêng nó sẽ cung cấp cho bạn hai điều.

  1. Nó sẽ làm cho ứng dụng của bạn thân thiện với bộ nhớ cache hơn để nó hoạt động tốt với Varnish (nếu bạn chọn sử dụng nó)

  2. Nó sẽ cho phép bạn kiểm soát những phần nào của trang web được lưu vào bộ nhớ đệm

Nếu bạn đang sử dụng server nhỏ hơn, tôi khuyên bạn nên sử dụng bộ nhớ đệm database . Nó dễ dàng bật và tránh phải chạy một quy trình server khác. Nếu bạn có đủ RAM, memcached sẽ cung cấp một chương trình backend bộ nhớ cache tuyệt vời. Bài viết này sẽ trình bày bộ nhớ đệm dựa trên database .

Hãy xem xét tài liệu được liên kết ở trên để biết rất nhiều chi tiết tuyệt vời, nhưng Đây là kết quả bạn cần làm để bắt đầu.

Tạo một bảng database cho bộ nhớ cache. Trong trường hợp này, bảng của ta được gọi là “cache_table”:

python manage.py createcachetable cache_table

Bây giờ hãy chỉnh sửa file settings.py của bạn và cấu hình bộ nhớ cache bằng cách thêm các dòng sau:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'cache_table',
    }
}

Có các tùy chọn cấu hình bổ sung mà bạn có thể cấu hình. Đọc về chúng trong tài liệu . Tôi đặc biệt muốn xem TIMEOUT và CULL_FREQUENCY.

Đến đây bạn cần quyết định những gì sẽ lưu vào bộ nhớ cache. Nếu bạn chỉ muốn làm cho trang web của bạn hoạt động tốt hơn với Varnish thì hãy kiểm tra cấu hình bộ nhớ cache của mỗi trang . Tuy nhiên, điều đó không thú vị lắm, vì vậy ta hãy đi sâu vào bộ nhớ đệm cho mỗi lần xem.

Giả sử bạn có trang sản phẩm giỏ hàng hiếm khi thay đổi và không hoạt động. Bạn có một dạng xem có tên product_detail(request, product_id) sẽ hoàn hảo cho việc lưu vào bộ nhớ đệm.

Bạn có thể sử dụng một trình trang trí đơn giản để kích hoạt bộ nhớ đệm cho việc này:

from django.views.decorators.cache import cache_page

@cache_page(60 * 60)
def product_detail(request, product_id):
    ...

Điều đó sẽ cho phép chế độ xem đó được lưu vào bộ nhớ cache trong 60 phút (60 giây * 60 phút).

, tôi muốn tham khảo các tài liệu để biết một số mẹo hay . Một khả năng đặc biệt mạnh mẽ là thay đổi dựa trên tiêu đề . Nếu bạn có một trang web được dịch sang nhiều ngôn ngữ hoặc bạn hiển thị nội dung khác nhau dựa trên version trình duyệt, đây có thể là một trợ giúp tuyệt vời.

Nội dung Thường xuyên thay đổi thì sao?


Nếu bạn có một trang bán động, chẳng hạn như ứng dụng của bạn nhận được nhiều comment hoặc dữ liệu được làm mới thường xuyên, bạn có thể lo lắng về việc sử dụng bộ nhớ đệm. Đây là một mối quan tâm hợp lệ.

Đầu tiên xác định tất cả các chế độ xem có thể được lưu trữ tích cực và sau đó lưu chúng vào bộ nhớ cache.

Thứ hai, xác định khoảng thời gian trì hoãn mà bạn có thể chịu đựng khi ai đó xem nội dung cũ. Ví dụ: một trang web có comment đang hoạt động có thể chịu được độ trễ từ 1 đến 5 phút. Lưu trữ các trang miễn là bạn có thể.

Bạn sẽ ngạc nhiên - ngay cả thời gian chờ của bộ nhớ cache 10 giây cũng có thể rất hữu ích. Trong nhiều trường hợp, một trang web bận rộn đột ngột bị quá tải thường do lưu lượng truy cập vào một trang cụ thể tấn công dữ dội.

Nếu 10.000 người truy cập một trang trên trang web trong thời gian một phút, nó sẽ làm tan server của bạn khi tất cả các truy vấn đến database chạy cùng một lúc. Nếu bạn đặt bộ nhớ cache là 10 giây, thì điều đó nghĩa là trang sẽ chỉ được tạo lại 6 lần mỗi phút, dù có bao nhiêu người yêu cầu. Bất kỳ server nào cũng có thể làm được điều đó!

Các trang web thương mại điện tử và các trang web sử dụng dữ liệu phiên phải rất cẩn thận. Điều tra các tùy chọn tiêu đề khác nhau để xem liệu bộ nhớ đệm có thể hoạt động trong trường hợp của bạn hay không. Đừng ngại sáng tạo!

Các trang web đôi khi sẽ phân phát tất cả các trang HTML dưới dạng nội dung tĩnh và tải thông tin về phiên của mỗi user bằng Ajax. Trong trường hợp của một trang thương mại điện tử, user thường sẽ không để ý xem số lượng giỏ hàng của họ có mất 5 giây để tải hay không miễn là họ có thể duyệt phần còn lại của trang một cách bình thường.

Cung cấp nội dung tĩnh


Server phát triển tích hợp sẵn của Django vui vẻ phục vụ nội dung tĩnh. Thông thường, tôi thấy các trang web Django được cấu hình để sử dụng production với nội dung tĩnh được Django phân phối.

Lần duy nhất bạn nên làm điều này là nếu bạn cần kiểm soát quyền truy cập vào nội dung. Nhưng ngay cả khi đó, hãy xem xét những cách khác.

  • CSS được tạo động - Không, hãy sử dụng một công cụ xây dựng như Grunt hoặc Less để xây dựng CSS của bạn trước khi triển khai. Nếu nó cần được tạo định kỳ trên server thì hãy sử dụng tác vụ nền .

  • Quyền truy cập của user được xác thực - Có, bạn có thể cần sử dụng Django cho việc này.

  • Mọi thứ khác - Không, hãy cấu hình lưu trữ nội dung tĩnh với web server của bạn.

Tôi đã phải đọc qua tài liệu về file tĩnh một vài lần trước khi tôi nhận được nó. Tôi nghĩ bạn nên tự đọc qua nó, nhưng trong trường hợp bạn cũng phải vật lộn với nó, đây là một tình huống bạn có thể sử dụng:

Trên máy phát triển local của bạn, trong “settings.py” thêm một dòng như sau:

STATIC_ROOT = os.path.join(BASE_DIR, "static")

Sau đó chạy lệnh management.py như sau:

python manage.py collectstatic

Đến đây bạn sẽ thấy trong folder root dự án của bạn có tên là “static” và trong đó bạn sẽ thấy rất nhiều file tĩnh của bạn , chẳng hạn như CSS và Javascript. Đặc biệt nếu bạn đã bật ứng dụng quản trị.

Để sử dụng các file này, bạn cần phải cấu hình Django để nó biết nơi cần tìm chúng. Trong folder settings.py của bạn, bạn cần một tùy chọn cấu hình như sau:

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
)

Bây giờ, nếu bạn chạy server của nhà phát triển và truy cập khu vực quản trị và xem nguồn của bất kỳ trang nào, bạn sẽ thấy rằng các file CSS đang được cung cấp từ /static/admin/css/ .

Khi bạn triển khai ứng dụng của bạn , bây giờ bạn có thể trỏ Apache hoặc Nginx để phân phát các file bắt đầu bằng / static / bằng cách trỏ chúng trực tiếp vào file .

Nếu ứng dụng của bạn được triển khai tới / srv / myapp / và do đó bạn có một file có tên /srv/myapp/static/admin/css/base.css thì bạn có thể cấu hình web server của bạn như sau:

Apache:

Alias /static/ "/srv/myapp/static/"

Nginx:

server {
    ...
    location /static/ {
        alias /srv/myapp/static/;
    }
}

Trong cả hai trường hợp, bạn chỉ trỏ / static / URL đến vị trí chính xác trên ổ cứng nơi các file được tìm thấy. Apache và Nginx có thể phục vụ những thứ này nhanh hơn nhiều so với Django có thể.

Sử dụng uWSGI


Nếu tôi muốn xuất bản một trang web nhanh chóng, tôi sử dụng mod_wsgi của Apache. Nếu tôi muốn có hiệu suất tốt nhất, tôi sử dụng uWSGI. Trong trường hợp bạn muốn biết cách phát âm điều đó, đó là “you whisky”.

uWSGI là một tiến trình server chạy ứng dụng của bạn bên ngoài web server . Đối với Apache, bạn cần cài đặt các gói sau:

sudo apt-get install uwsgi uwsgi-plugin-python uwsgi-plugin-cgi

Nếu bạn đang sử dụng Apache làm web server của bạn , hãy cài đặt thêm:

sudo apt-get install libapache2-mod-uwsgi

Sau khi hoàn thành việc đó, bạn sẽ nhận thấy rằng bây giờ bạn có hai folder mới để cấu hình: /etc/uwsgi/apps-available/etc/uwsgi/apps-enabled , giống như bạn thấy cho cấu hình server ảo của bạn với Apache hoặc Nginx.

Khi bạn muốn tạo một ứng dụng mới, bạn đặt một file cấu hình vào /etc/uwsgi/apps-available và sau đó tạo một softlink cho nó từ các ứng dụng đã bật.

Giả sử bạn đã thực hiện một dự án có tên là newproject và bạn đã đặt nó tại /srv/newproject . Điển hình cho các dự án Django, có một file settings.py tại /srv/newproject/newproject/settings.py .

Tạo một file có tên là `/etc/uwsgi/apps-available/newproject.ini và chỉnh sửa nó để trông giống như sau:

[uwsgi]
touch-reload = /tmp/newproject
socket = 127.0.0.1:3031
workers = 2
chdir = /srv/newproject
env = DJANGO_SETTINGS_MODULE=newproject.settings
module = django.core.handlers.wsgi:WSGIHander()

Bây giờ, hãy tạo một file trống có tên /tmp/newproject :

touch /tmp/newproject

Bạn phải kích hoạt ứng dụng bằng cách liên kết file với các ứng dụng hỗ trợ:

sudo ln -s /etc/uwsgi/apps-available/newproject.ini /etc/uwsgi/apps-enabled/newproject.ini

và sau đó khởi động lại uWSGI:

sudo service uwsgi restart

Nếu bạn kiểm tra kết quả của “ps ax”, bạn sẽ thấy một vài quy trình đang chạy liên quan đến ứng dụng của bạn.

Lưu ý nếu bạn có nhiều ứng dụng chạy trên cùng một server thì bạn cần sử dụng một cổng khác nhau cho socket của mỗi ứng dụng.

Ngoài ra, nếu bạn cập nhật ứng dụng của bạn , bạn chỉ cần “chạm” vào file / tmp / newproject và uWSGI sẽ tự reload .

Bất cứ lúc nào bạn cũng có thể xem /var/log/uwsgi/app/newproject.log để xem thông báo thông tin và lỗi.

Cấu hình Apache


Nếu bạn đang sử dụng mod wsgi bây giờ là thời điểm của sự thật. Bạn nên tắt mod wsgi và bật mod_uwsgi. Điều này có thể gây ra lỗi vì vậy hãy thực hiện việc này trên server thử nghiệm cho đến khi bạn tìm thấy cấu hình phù hợp.

sudo a2dismod wsgi
sudo a2enmod uwsgi

Bây giờ hãy cập nhật cấu hình cho ứng dụng của bạn. Trong cấu hình apache của bạn, bạn có thể có một dòng như sau:

WSGIScriptAlias / /srv/newproject/newproject.wsgi

Và bạn sẽ cập nhật thành như thế này:

SetHandler uwsgi-handler
uWSGISocket 127.0.0.1:3031

Bây giờ reload cấu hình Apache của bạn:

sudo service apache2 reload

Cấu hình Nginx


Trong cấu hình server của bạn , bạn cần thay thế các chỉ thị wsgi hiện có của bạn bằng:

uwsgi_pass      127.0.0.1:3031;
include         uwsgi_params;
uwsgi_param     UWSGI_SCHEME $scheme;

Khá đơn giản!

Lợi ích của uWSGI


Một trong những khía cạnh tuyệt vời của việc sử dụng uWSGI là bạn có thể giới hạn số lần ứng dụng của bạn đang chạy trong bộ nhớ. Thường sẽ có một quy trình mẹ và nếu bạn đã sử dụng cấu hình được chia sẻ ở trên, sẽ có 2 công nhân. Nếu bạn cần thêm nhân công, bạn có thể chỉ cần chỉnh sửa file .ini cho ứng dụng và tăng số lượng “nhân công”. Sau đó reload uWSGI với “ reload uwsgi dịch vụ sudo” để cập nhật thay đổi.

Trước khi tăng số lượng quy trình, hãy xem xét lượng bộ nhớ server bạn đang sử dụng. Nếu bạn đang chạy mod_wsgi trước đó, bạn sẽ thấy mức sử dụng bộ nhớ giảm. Hãy xem quy mô của công nhân uWSGI. Chúng có xu hướng tăng kích thước khi ứng dụng được sử dụng. Không phải do bộ nhớ bị rò rỉ mà đơn giản là do tập dữ liệu trong bộ nhớ nhỏ.

Tối đa hóa việc sử dụng


Sau khi ứng dụng của bạn đã khởi động và sử dụng được một thời gian, hãy xem lại việc sử dụng bộ nhớ của server .

Sử dụng lệnh free -m để xem cache / bộ nhớ đệm đang được sử dụng bao nhiêu bộ nhớ so với các ứng dụng. Giá trị chính là số trên cùng trong cột “miễn phí”. Lý tưởng nhất là một server bận sẽ sử dụng gần như tất cả RAM.

Nếu bạn thấy rằng mình còn trống RAM và trang web chạy chậm thì hãy tìm hiểu những gì đang được sử dụng kém.

Thông thường, bạn sẽ thấy rằng các quy trình đang chờ MySQL. Có thể là bạn cần cấp phát thêm bộ nhớ hệ thống cho database . Điều này cực kỳ phổ biến vì cấu hình mặc định cho MySQL sử dụng RAM rất ít.

Cũng có thể là không có đủ RAM được phân bổ cho bộ nhớ cache trên đĩa. Bạn có các quy trình không cần thiết chiếm bộ nhớ không? Theo mặc định, Linux sẽ phân bổ càng nhiều RAM vào bộ nhớ đệm đĩa càng tốt, miễn cưỡng từ bỏ nó khi các ứng dụng cần.

Trong một tình huống lý tưởng, điều này không bao giờ xảy ra với môi trường VPS hạn chế bộ nhớ, tất cả các tài sản chỉ đọc sẽ được lưu vào cache trong cache . Do đó, loại bỏ các quy trình không cần thiết.

Gói (lại


Bạn đã học một số kỹ thuật để lưu vào bộ nhớ đệm, bao gồm lưu vào bộ nhớ đệm toàn bộ trang web bằng Varnish hoặc kiểm soát cài đặt bộ nhớ cache trên cơ sở mỗi lần xem.

Bạn đã đảm bảo các file tĩnh đang được cung cấp bằng web server , không phải Django.

Bạn đã học cách sử dụng uWSGI để tăng hiệu suất của ứng dụng Django của bạn bằng cách chạy nó khỏi quy trình từ web server . (Nhân tiện, cảm ơn Ricardo Pascal về tài liệu Apache / uWSGI tuyệt vời của anh ấy)

Cuối cùng, bạn đã học về cách cấp phát càng nhiều bộ nhớ cho các ứng dụng server của bạn càng tốt để tối đa hóa việc sử dụng.

<div class = “author”> Gửi bởi: <a href=osystemhttp://www.bearfruit.org/[> Matthew Nuzum </div>


Tags:

Các tin liên quan