更新了项目部分的文档
parent
b8a0a6c15a
commit
3b2ddfd473
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
![s](./res/web-application.png)
|
![s](./res/web-application.png)
|
||||||
|
|
||||||
问题2:描述项目的物理架构。(上图中补充负载均衡(反向代理)服务器、数据库服务器、文件服务器、邮件服务器、缓存服务器、防火墙等,而且每个节点都有可能是多节点构成的集群,如下图所示)
|
问题2:描述项目的物理架构。(上图中补充负载均衡(反向代理)服务器、数据库服务器、文件服务器、邮件服务器、缓存服务器、防火墙等,而且每个节点都有可能是多节点构成的集群,如下图所示,架构并不是一开始就是这样,而是逐步演进的)
|
||||||
|
|
||||||
![](./res/05.django_massive_cluster.png)
|
![](./res/05.django_massive_cluster.png)
|
||||||
|
|
||||||
|
@ -850,7 +850,7 @@ CACHES = {
|
||||||
'LOCATION': [
|
'LOCATION': [
|
||||||
'redis://1.2.3.4:6379/0',
|
'redis://1.2.3.4:6379/0',
|
||||||
],
|
],
|
||||||
'KEY_PREFIX': 'fangtx',
|
'KEY_PREFIX': 'teamproject',
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
|
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
|
||||||
'CONNECTION_POOL_KWARGS': {
|
'CONNECTION_POOL_KWARGS': {
|
||||||
|
@ -865,7 +865,7 @@ CACHES = {
|
||||||
'LOCATION': [
|
'LOCATION': [
|
||||||
'redis://1.2.3.4:6379/1',
|
'redis://1.2.3.4:6379/1',
|
||||||
],
|
],
|
||||||
'KEY_PREFIX': 'fangtx:page',
|
'KEY_PREFIX': 'teamproject:page',
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
|
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
|
||||||
'CONNECTION_POOL_KWARGS': {
|
'CONNECTION_POOL_KWARGS': {
|
||||||
|
@ -880,7 +880,7 @@ CACHES = {
|
||||||
'LOCATION': [
|
'LOCATION': [
|
||||||
'redis://1.2.3.4:6379/2',
|
'redis://1.2.3.4:6379/2',
|
||||||
],
|
],
|
||||||
'KEY_PREFIX': 'fangtx:session',
|
'KEY_PREFIX': 'teamproject:session',
|
||||||
'TIMEOUT': 1209600,
|
'TIMEOUT': 1209600,
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
|
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
|
||||||
|
@ -896,7 +896,7 @@ CACHES = {
|
||||||
'LOCATION': [
|
'LOCATION': [
|
||||||
'redis://1.2.3.4:6379/3',
|
'redis://1.2.3.4:6379/3',
|
||||||
],
|
],
|
||||||
'KEY_PREFIX': 'fangtx:api',
|
'KEY_PREFIX': 'teamproject:api',
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
|
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
|
||||||
'CONNECTION_POOL_KWARGS': {
|
'CONNECTION_POOL_KWARGS': {
|
||||||
|
@ -1357,17 +1357,55 @@ REST_FRAMEWORK = {
|
||||||
```
|
```
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
class EstateViewSet(CacheResponseMixin, ModelViewSet):
|
from django.utils.decorators import method_decorator
|
||||||
# 通过queryset指定如何获取数据(资源)
|
from django.views.decorators.cache import cache_page
|
||||||
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
|
from rest_framework.filters import OrderingFilter
|
||||||
|
from rest_framework.generics import RetrieveAPIView, ListCreateAPIView
|
||||||
|
|
||||||
|
from api.serializers import EstateSerializer
|
||||||
|
from common.models import Estate
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(decorator=cache_page(timeout=120, cache='api', key_prefix='estates'), name='get')
|
||||||
|
class EstateView(RetrieveAPIView, ListCreateAPIView):
|
||||||
queryset = Estate.objects.all().select_related('district').prefetch_related('agents')
|
queryset = Estate.objects.all().select_related('district').prefetch_related('agents')
|
||||||
# 通过serializer_class指定如何序列化数据
|
|
||||||
serializer_class = EstateSerializer
|
serializer_class = EstateSerializer
|
||||||
# 通过filter_backends指定如何提供筛选(覆盖默认的设置)
|
filter_backends = (DjangoFilterBackend, OrderingFilter)
|
||||||
# filter_backends = (DjangoFilterBackend, OrderingFilter)
|
filter_fields = ('name', 'district')
|
||||||
# 指定根据哪些字段进行数据筛选
|
ordering = ('-hot', )
|
||||||
filter_fields = ('district', )
|
ordering_fields = ('hot', 'estateid')
|
||||||
# 指定根据哪些字段对数据进行排序
|
```
|
||||||
ordering_fields = ('hot', )
|
|
||||||
|
```Python
|
||||||
|
from django_filters import rest_framework as drf
|
||||||
|
from common.models import HouseInfo
|
||||||
|
|
||||||
|
|
||||||
|
class HouseInfoFilter(drf.FilterSet):
|
||||||
|
"""自定义房源数据过滤器"""
|
||||||
|
|
||||||
|
title = drf.CharFilter(lookup_expr='starts')
|
||||||
|
dist = drf.NumberFilter(field_name='district')
|
||||||
|
min_price = drf.NumberFilter(field_name='price', lookup_expr='gte')
|
||||||
|
max_price = drf.NumberFilter(field_name='price', lookup_expr='lte')
|
||||||
|
type = drf.NumberFilter()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = HouseInfo
|
||||||
|
fields = ('title', 'district', 'min_price', 'max_price', 'type')
|
||||||
|
```
|
||||||
|
|
||||||
|
```Python
|
||||||
|
class HouseInfoViewSet(CacheResponseMixin, ReadOnlyModelViewSet):
|
||||||
|
queryset = HouseInfo.objects.all() \
|
||||||
|
.select_related('type', 'district', 'estate', 'agent') \
|
||||||
|
.prefetch_related('tags').order_by('-pubdate')
|
||||||
|
serializer_class = HouseInfoSerializer
|
||||||
|
filter_backends = (DjangoFilterBackend, OrderingFilter)
|
||||||
|
filterset_class = HouseInfoFilter
|
||||||
|
ordering = ('price',)
|
||||||
|
ordering_fields = ('price', 'area')
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 身份认证
|
#### 身份认证
|
||||||
|
|
67
README.md
67
README.md
|
@ -346,6 +346,14 @@
|
||||||
|
|
||||||
![](./res/the-daily-scrum-in-the-sprint-cycle.png)
|
![](./res/the-daily-scrum-in-the-sprint-cycle.png)
|
||||||
|
|
||||||
|
> 角色:产品所有者(决定做什么,能对需求拍板的人)、团队负责人(解决各种问题,专注如何更好的工作,屏蔽外部对开发团队的影响)、开发团队(项目执行人员,具体指开发人员和测试人员)
|
||||||
|
>
|
||||||
|
> 准备工作:商业案例和资金、合同、憧憬、初始产品需求、初始发布计划、入股、组建团队
|
||||||
|
>
|
||||||
|
> 敏捷团队通常人数为8-10人。
|
||||||
|
>
|
||||||
|
> 工作量估算:将开发任务量化,包括原型、Logo设计、UI设计、前端开发等,尽量把每个工作分解到最小任务量,最小任务量标准为工作时间不能超过两天,然后估算总体项目时间。把每个任务都贴在白板上面,白板上分三部分:to do(待完成)、in progress(进行中)和done(已完成)。
|
||||||
|
|
||||||
2. 项目团队组建
|
2. 项目团队组建
|
||||||
|
|
||||||
- 团队的构成和角色
|
- 团队的构成和角色
|
||||||
|
@ -370,7 +378,7 @@
|
||||||
- 敏捷闭环工具:[禅道](https://www.zentao.net/)、[JIRA](https://www.atlassian.com/software/jira/features)
|
- 敏捷闭环工具:[禅道](https://www.zentao.net/)、[JIRA](https://www.atlassian.com/software/jira/features)
|
||||||
- 持续集成:[Jenkins](https://jenkins.io/)、[Travis-CI](https://travis-ci.org/)
|
- 持续集成:[Jenkins](https://jenkins.io/)、[Travis-CI](https://travis-ci.org/)
|
||||||
|
|
||||||
请参考[《团队项目开发》](团队项目开发.md)。
|
请参考[《团队项目开发》](Day91-100/团队项目开发.md)。
|
||||||
|
|
||||||
##### 项目选题和理解业务
|
##### 项目选题和理解业务
|
||||||
|
|
||||||
|
@ -428,12 +436,14 @@
|
||||||
|
|
||||||
#### 第93-98天:使用Django开发项目
|
#### 第93-98天:使用Django开发项目
|
||||||
|
|
||||||
|
> 说明:具体内容请参考[《Django知识点概述》](Day91-100/Django知识点概述.md)
|
||||||
|
|
||||||
##### 项目开发中的公共问题
|
##### 项目开发中的公共问题
|
||||||
|
|
||||||
1. 数据库的配置(多库、主从、路由)
|
1. 数据库的配置(多数据库、主从复制、数据库路由)
|
||||||
2. 缓存的配置(分区缓存、键设置、超时设置、主从复制、故障恢复)
|
2. 缓存的配置(分区缓存、键设置、超时设置、主从复制、故障恢复(哨兵))
|
||||||
3. 日志的配置
|
3. 日志的配置
|
||||||
4. Django的使用技巧(Django-Debug-ToolBar)
|
4. 分析和调试(Django-Debug-ToolBar)
|
||||||
5. 好用的Python模块(日期计算、图像处理、数据加密、三方API)
|
5. 好用的Python模块(日期计算、图像处理、数据加密、三方API)
|
||||||
|
|
||||||
##### REST API设计
|
##### REST API设计
|
||||||
|
@ -442,15 +452,15 @@
|
||||||
- [理解RESTful架构](http://www.ruanyifeng.com/blog/2011/09/restful.html)
|
- [理解RESTful架构](http://www.ruanyifeng.com/blog/2011/09/restful.html)
|
||||||
- [RESTful API设计指南](http://www.ruanyifeng.com/blog/2014/05/restful_api.html)
|
- [RESTful API设计指南](http://www.ruanyifeng.com/blog/2014/05/restful_api.html)
|
||||||
- [RESTful API最佳实践](http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html)
|
- [RESTful API最佳实践](http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html)
|
||||||
2. API接口文档的撰写([《网络API接口设计》](网络API接口设计.md))
|
2. API接口文档的撰写([《网络API接口设计》](Day91-100/网络API接口设计.md))
|
||||||
- [RAP2](http://rap2.taobao.org/)
|
- [RAP2](http://rap2.taobao.org/)
|
||||||
- [Apizza](https://apizza.net/)
|
- [YAPI](http://yapi.demo.qunar.com/)
|
||||||
3. [django-REST-framework](https://www.django-rest-framework.org/)的应用(具体请参考[《Django知识点概述》](Django知识点概述.md))
|
3. [django-REST-framework](https://www.django-rest-framework.org/)的应用
|
||||||
|
|
||||||
##### 项目中的重点难点剖析
|
##### 项目中的重点难点剖析
|
||||||
|
|
||||||
1. 使用缓存缓解数据库压力 - Redis(具体请参考[《Django知识点概述》](Django知识点概述.md))
|
1. 使用缓存缓解数据库压力 - Redis
|
||||||
2. 使用消息队列缓解服务器压力 - Celery + RabbitMQ(具体请参考[《Django知识点概述》](Django知识点概述.md))
|
2. 使用消息队列做解耦合和削峰 - Celery + RabbitMQ
|
||||||
|
|
||||||
#### 第99-100天:测试和部署
|
#### 第99-100天:测试和部署
|
||||||
|
|
||||||
|
@ -462,6 +472,8 @@
|
||||||
|
|
||||||
##### 项目部署
|
##### 项目部署
|
||||||
|
|
||||||
|
> 说明:请参考[《项目部署上线指南》](Day91-100/项目部署上线指南.md)。
|
||||||
|
|
||||||
1. 部署前的准备工作
|
1. 部署前的准备工作
|
||||||
- 关键设置(SECRET_KEY / DEBUG / ALLOWED_HOSTS / 缓存 / 数据库)
|
- 关键设置(SECRET_KEY / DEBUG / ALLOWED_HOSTS / 缓存 / 数据库)
|
||||||
- HTTPS / CSRF_COOKIE_SECUR / SESSION_COOKIE_SECURE
|
- HTTPS / CSRF_COOKIE_SECUR / SESSION_COOKIE_SECURE
|
||||||
|
@ -478,6 +490,8 @@
|
||||||
|
|
||||||
##### 性能测试
|
##### 性能测试
|
||||||
|
|
||||||
|
> 说明:具体内容请参考[《Django知识点概述》](Day91-100/Django知识点概述.md)。
|
||||||
|
|
||||||
1. AB的使用
|
1. AB的使用
|
||||||
2. SQLslap的使用
|
2. SQLslap的使用
|
||||||
3. sysbench的使用
|
3. sysbench的使用
|
||||||
|
@ -493,22 +507,29 @@
|
||||||
|
|
||||||
##### 项目性能调优
|
##### 项目性能调优
|
||||||
|
|
||||||
1. 数据库性能调优
|
1. 数据库性能调优 - 请参考[《MySQL相关知识》](Day91-100/MySQL相关知识.md)
|
||||||
- 软硬件优化
|
- 软硬件优化
|
||||||
|
|
||||||
- SQL优化
|
- SQL优化
|
||||||
- 通过show status了解SQL的执行频率。
|
|
||||||
- 通过慢查询日志或show processlist定位低效率SQL。
|
|
||||||
- 通过EXPLAIN分析低效率SQL的执行计划。
|
|
||||||
- 通过show profile分析SQL。
|
|
||||||
- 合理的使用索引。
|
|
||||||
- 定期检查和优化表。
|
|
||||||
- 优化insert操作。
|
|
||||||
- 优化排序操作。
|
|
||||||
- 优化分组操作。
|
|
||||||
- 优化OR条件操作。
|
|
||||||
- 优化分页操作。
|
|
||||||
- 架构优化
|
- 架构优化
|
||||||
|
|
||||||
|
- 分表分库
|
||||||
|
|
||||||
- 主从复制,读写分离
|
- 主从复制,读写分离
|
||||||
- 集群架构
|
- 集群架构
|
||||||
2. 代码性能调优
|
|
||||||
3. 云存储和CDN加速
|
2. Web服务器性能优化
|
||||||
|
|
||||||
|
- Nginx负载均衡配置
|
||||||
|
|
||||||
|
- Keepalived实现高可用
|
||||||
|
|
||||||
|
3. 代码性能调优
|
||||||
|
|
||||||
|
- 多线程
|
||||||
|
- 异步化
|
||||||
|
|
||||||
|
4. 静态资源访问优化
|
||||||
|
- 云存储
|
||||||
|
- CDN
|
||||||
|
|
Loading…
Reference in New Issue