面试题答案
一键面试数据库层面优化
- 索引优化
- 对经常用于查询、排序、连接的字段添加索引。例如在博客文章表中,对文章标题、发布时间等字段添加索引。
from django.db import models class BlogPost(models.Model): title = models.CharField(max_length = 200, db_index=True) publish_date = models.DateTimeField(db_index=True) # 其他字段
- 数据库分区
- 当数据量很大时,按日期(如按月)对博客文章表进行分区。例如使用PostgreSQL,可以通过
CREATE TABLE
语句结合PARTITION BY RANGE
来实现按日期分区。
CREATE TABLE blog_posts ( id serial, title text, content text, publish_date date ) PARTITION BY RANGE (publish_date); CREATE TABLE blog_posts_2023_01 PARTITION OF blog_posts FOR VALUES FROM ('2023 - 01 - 01') TO ('2023 - 02 - 01');
- 当数据量很大时,按日期(如按月)对博客文章表进行分区。例如使用PostgreSQL,可以通过
- 使用连接池
- 在Django项目中使用
django - dj_db_conn_pool
库来管理数据库连接。安装后,在settings.py
中配置:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'blog_db', 'USER': 'user', 'PASSWORD': 'password', 'HOST': '127.0.0.1', 'PORT': '5432', 'CONN_MAX_AGE': 600, 'POOL_OPTIONS': { 'MAX_CONNS': 10, 'RECYCLE': 3600 } } }
- 在Django项目中使用
缓存机制优化
- 页面缓存
- 在
settings.py
中配置页面缓存。例如设置全站缓存60秒:
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'unique - cache - location' } } MIDDLEWARE = [ 'django.middleware.cache.UpdateCacheMiddleware', # 其他中间件 'django.middleware.cache.FetchFromCacheMiddleware' ] CACHE_MIDDLEWARE_SECONDS = 60
- 在
- 视图缓存
- 使用
cache_page
装饰器对视图函数进行缓存。例如:
from django.views.decorators.cache import cache_page from django.http import HttpResponse @cache_page(60 * 15) # 缓存15分钟 def blog_post_view(request, post_id): # 视图逻辑 return HttpResponse('Blog post content')
- 使用
- 对象缓存
- 对于频繁访问的对象(如博客文章对象),手动缓存。例如:
from django.core.cache import cache def get_blog_post(post_id): post = cache.get(f'blog_post_{post_id}') if not post: post = BlogPost.objects.get(id = post_id) cache.set(f'blog_post_{post_id}', post, 60 * 10) # 缓存10分钟 return post
Django自身配置优化
- 优化模板加载
- 使用
cached_loaders
。在settings.py
中:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, 'OPTIONS': { 'loaders': [ ('django.template.loaders.cached.Loader', [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader' ]) ], # 其他选项 }, }, ]
- 使用
- 减少中间件使用
- 检查并移除不必要的中间件,只保留核心功能所需的中间件。例如,如果项目不需要国际化支持,可以移除
django.middleware.locale.LocaleMiddleware
。
- 检查并移除不必要的中间件,只保留核心功能所需的中间件。例如,如果项目不需要国际化支持,可以移除
部署到Linux服务器步骤
- 安装依赖
- 确保服务器安装了Python和
pip
。如果没有,可以使用包管理器安装,例如在Ubuntu上:
sudo apt update sudo apt install python3 python3 - pip
- 创建虚拟环境(可选但推荐):
python3 -m venv blog_venv source blog_venv/bin/activate
- 安装项目依赖,假设项目的依赖在
requirements.txt
中:
pip install -r requirements.txt
- 确保服务器安装了Python和
- 配置服务器
- 配置Web服务器(以Nginx为例):
- 安装Nginx:
sudo apt install nginx
- 创建Nginx配置文件,例如
/etc/nginx/sites - available/blog.conf
:
server { listen 80; server_name your_domain.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X - Real - IP $remote_addr; proxy_set_header X - Forwarded - For $proxy_add_x_forwarded_for; proxy_set_header X - Forwarded - Proto $scheme; } }
- 启用配置:
sudo ln -s /etc/nginx/sites - available/blog.conf /etc/nginx/sites - enabled/
- 检查Nginx配置并重启:
sudo nginx -t sudo systemctl restart nginx
- 配置Gunicorn:
- 安装Gunicorn:
pip install gunicorn
- 创建Gunicorn启动脚本,例如
gunicorn_start
:
#!/bin/bash NAME='blog_project' DJANGODIR=/path/to/your/django/project SOCKFILE=/path/to/your/django/project/run/gunicorn.sock LOGFILE=/path/to/your/django/project/logs/gunicorn.log NUM_WORKERS=3 DJANGO_SETTINGS_MODULE=blog_project.settings DJANGO_WSGI_MODULE=blog_project.wsgi cd $DJANGODIR source../blog_venv/bin/activate export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE export PYTHONPATH=$DJANGODIR:$PYTHONPATH mkdir -p `dirname $SOCKFILE` exec gunicorn ${DJANGO_WSGI_MODULE}:application \ --name $NAME \ --workers $NUM_WORKERS \ --bind=unix:$SOCKFILE \ --log - level = info \ --log - file = $LOGFILE 2>&1
- 赋予脚本执行权限:
chmod +x gunicorn_start
- 配置Web服务器(以Nginx为例):
- 启动项目
- 启动Gunicorn:
- **设置开机自启(以systemd为例)**: - 创建`/etc/systemd/system/gunicorn.service`: ```ini [Unit] Description = Gunicorn instance to serve blog_project After = network.target [Service] User = your_username Group = www - data WorkingDirectory = /path/to/your/django/project ExecStart = /path/to/your/django/project/blog_venv/bin/gunicorn \ --workers 3 \ --bind unix:/path/to/your/django/project/run/gunicorn.sock \ blog_project.wsgi:application [Install] WantedBy = multi - user.target
- 重新加载systemd:
sudo systemctl daemon - reload
- 启动并设置开机自启:
sudo systemctl start gunicorn sudo systemctl enable gunicorn
- 启动Gunicorn: