Nginx、OpenResty和Kong的基本概念与使用方法
Nginx、OpenResty和Kong的基本概念与使用方法
作者: 李佶澳 转载请保留:原文地址 发布时间:2018-09-29 15:41:50 +0800
说明
Nginx、OpenRestry、Kong这三个项目紧密相连: Nginx是模块化设计的反向代理软件,C语言开发; OpenResty是以Nginx为核心的Web开发平台,可以解析执行Lua脚本(OpenResty与Lua的关系,类似于Jvm与Java,不过Java可以做的事情太多了,OpenResty主要用来做Web、API等); Kong是一个OpenResty应用,是一个api gateway,具有API管理和请求代理的功能。
Nginx
Nginx是HTTP Server、反向代理服务器、邮件代理服务器、通用的TCP/UDP代理服务器。nginx features详细列出了nginx的功能特性。
Nginx配置文件,指令与变量
Nginx的配置文件由单指令(simple directive)
和块指令(block directive)
组成,单指令只有一行,以“;”结尾,块指令后面是用“{ }”包裹的多行内容。
有些块指令后的花括号中可以继续包含单指令,这样的块指令被成为配置上下文(context)
,这样的指令有:events、http、server、location等。
context是嵌套的,最外层的context是main context
,配置文件中不在{}
的中指令都是位于main context
中。
events和http指令位于main context,server位于http context,location位于server context:
- main context
- - events
- - http
- - server
- - location
配置文件示例见: Beginner’s Guide,例如:
- http {
- server {
- listen 8080; # server监听端口,不指定默认80
- root /data/up1; # 默认文件查找根目录
- # 将请求按照uri进行分组处理
- location / { # 选择最常匹配的location,如果不匹配任何location,返回404
- root /data/www; # 文件查找根目录,覆盖server中的root配置
- }
- # uri路径匹配,优先级低于下面的正则匹配!
- location /images/ {
- root /data;
- }
- # 使用正则表达式匹配(必须带有"~ "前缀):匹配文件后缀名
- location ~ \.(gif|jpg|png)$ { # 优先级高于uri路径匹配
- root /data/images;
- }
- # 作为代理服务器的配置方法
- location /proxy/ { # 将uri匹配的请求转发到proxy_pass指定的地址
- proxy_pass http://IP地址:8080;
- }
- # 将请求代理到FastCGI
- # fastcgi_param是按照FastCGI的要求传递的参数,可以有多个,后面的`$XXX`是Nginx变量,拼成了参数的值
- location /fastcgi/ {
- fastcgi_pass localhost:9000; # fastCGI服务的地址
- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 传给fastCGI服务的参数: SCRIPT_FILENAME
- fastcgi_param QUERY_STRING $query_string; # 传给fastCGI服务的参数: QUERY_STRING
- }
- }
- }
上面的例子中的proxy_pass
和factcgi_pass
分别是nginx的http proxy module和http fastcgi moudle中指令。
Nginx有很多的module,在Nginx Documents中可以查看每个modules的用法。
Nginx: Alphabetical index of directives中列出了Nginx的所有指令。
Nginx: Alphabetical index of variables中列出了可以在配置文件中使用的所有变量。
在查看Nginx指令用法的时候,注意指令的context:
- Syntax: gzip on | off;
- Default: gzip off;
- Context: http, server, location, if in location # 可以使用gzip指令的地方
Nginx作为TCP/UDP负载均衡器
Nginx原本只能做7层(http)代理,在1.9.0版本中增加了4层(TCP/UDP)代理功能。
4层代理功能在Nginx的ngx_stream_core_module模块中实现,但默认没有编译,需要在编译时指定: –with-stream。
使用配置如下:
- worker_processes auto;
- error_log /var/log/nginx/error.log info;
- events {
- worker_connections 1024;
- }
- stream {
- upstream backend {
- hash $remote_addr consistent;
- server backend1.example.com:12345 weight=5;
- server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
- server unix:/tmp/backend3;
- }
- upstream dns {
- server 192.168.0.1:53535;
- server dns.example.com:53;
- }
- server {
- listen 12345;
- proxy_connect_timeout 1s;
- proxy_timeout 3s;
- proxy_pass backend;
- }
- server {
- listen 127.0.0.1:53 udp reuseport;
- proxy_timeout 20s;
- proxy_pass dns;
- }
- server {
- listen [::1]:12345;
- proxy_pass unix:/tmp/stream.socket;
- }
- }
Nginx模块
理解Nginx Module很重要,因为后面的OpenResty就是标准的Nginx加上很多Nginx Module。
Nginx是用C语言开发软件,采用模块化设计,可以通过开发模块扩展Nginx的功能。
Nginx Development guide中介绍了Nginx模块开发的方法Nginx Module develop。
插件可以编译成.so以后动态加载,也可以直接编译到nginx中,编译是通过--add-module
指定要集成的模块。
- ./configure --prefix=/opt/nginx \
- --with-ld-opt="-Wl,-rpath,/path/to/luajit-or-lua/lib" \
- --add-module=/path/to/ngx_devel_kit \
- --add-module=/path/to/lua-nginx-module
OpenResty
OpenResty是一个集成了Nginx、LuaJIT和其它很多moudels的平台,用来托管完整的web应用——包含业务逻辑,而不单纯是静态文件服务器: OpenResty® aims to run your server-side web app completely in the Nginx server, leveraging Nginx’s event model to do non-blocking I/O not only with the HTTP clients, but also with remote backends like MySQL, PostgreSQL, Memcached, and Redis.
OpenResty Components中列出了OpenResty集成的组件,数量不少,这里就不列出来了。
先通过OpenResty Getting Started感受一下OpenResty是咋回事。
OpenResty安装
Centos安装方式:
- sudo yum install yum-utils
- sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
- sudo yum install openresty
- sudo yum install openresty-resty
通过源代码编译:
- wget https://openresty.org/download/openresty-1.13.6.2.tar.gz
- tar -xvf openresty-1.13.6.2.tar.gz
- cd openresty-1.13.6.2/
- ./configure --with-pcre-jit --with-http_ssl_module --with-http_realip_module --with-http_stub_status_module --with-http_v2_module
- make -j2
- make install //默认安装在/usr/local/bin/openresty
- export PATH=/usr/local/openresty/bin:$PATH
为了后面顺利的使用kong,configure时要指定kong依赖的模块。
都包含以下文件:
- $ tree -L 2 /usr/local/openresty/
- /usr/local/openresty/
- |-- bin
- | |-- md2pod.pl
- | |-- nginx-xml2pod
- | |-- openresty -> /usr/local/openresty/nginx/sbin/nginx
- | |-- opm
- | |-- resty
- | |-- restydoc
- | `-- restydoc-index
- |-- COPYRIGHT
- |-- luajit
- | |-- bin
- | |-- include
- | |-- lib
- | `-- share
- ...
注意openresty命令就是nginx命令,OpenResty可以理解为一个集成了很多模块的定制版nginx:
- $ openresty -h
- nginx version: openresty/1.13.6.2
- Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
- Options:
- -?,-h : this help
- -v : show version and exit
- -V : show version and configure options then exit
- -t : test configuration and exit
- -T : test configuration, dump it and exit
- -q : suppress non-error messages during configuration testing
- -s signal : send signal to a master process: stop, quit, reopen, reload
- -p prefix : set prefix path (default: /usr/local/openresty/nginx/)
- -c filename : set configuration file (default: conf/nginx.conf)
- -g directives : set global directives out of configuration file
可以在openresty的配置文件中写入lua代码:
- $ cat nginx.conf
- worker_processes 1;
- error_log logs/error.log;
- events {
- worker_connections 1024;
- }
- http {
- server {
- listen 8080;
- location / {
- default_type text/html;
- content_by_lua '
- ngx.say("<p>hello, world</p>")
- ';
- }
- }
- }
启动:
openresty -p `pwd` -c nginx.conf
然后访问”127.0.0.1:8080”,可以看到输出:
- $ curl 127.0.0.1:8080
- <p>hello, world</p>
Kong
Kong是一个OpenResty应用,用来管理api。
Kong编译安装
Kong编译安装时需要先安装有OpenResty。
还需要lua包管理工具luarocks:
- git clone git://github.com/luarocks/luarocks.git
- ./configure --lua-suffix=jit --with-lua=/usr/local/openresty/luajit --with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1
- make install
下载kong代码编译:
- git clone https://github.com/Kong/kong.git
- cd kong
- make install
编译完成之后会在当前目录生成一个bin目录:
- $ ls bin/
- busted kong
查看bin/kong的内容,可以发现这是一个用resty执行的脚本文件:
- $ cat bin/kong
- #!/usr/bin/env resty
- require "luarocks.loader"
- package.path = "./?.lua;./?/init.lua;" .. package.path
- require("kong.cmd.init")(arg)
启动Kong
先准备数据库,kong支持PostgreSQL和Cassandra 3.x.x,这里使用PostgreSQL(需要版本在9.4及以上):
注意,如果使用其它版本的PostgreSQL,将下面的9.6换成对应版本号。
- yum install https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm
- yum install postgresql96
- yum install postgresql96-server
- export PATH=$PATH:/usr/pgsql-9.6/bin/
- postgresql96-setup initdb
- systemctl start postgresql-9.6
- su - postgres
- psql
- CREATE USER kong; CREATE DATABASE kong OWNER kong;
- alter user kong with encrypted password '123456';
- \q
在/var/lib/pgsql/9.6/data/pg_hba.conf的开始处
添加规则下面规则:
host kong kong 127.0.0.1/32 md5
然后重启PostgreSQL
,确保下面的命令能登陆PostgreSQL:
- # psql -h 127.0.0.1 -U kong kong -W
- Password for user kong:
- psql (9.6.10)
- Type "help" for help.
- kong=>
PostgreSQL的部署使用和通过密码登陆方式的设置参考:PostgresSQL数据库的基本使用、PostgreSQL的用户到底是这么回事?新用户怎样才能用密码登陆?。
准备kong的配置文件,
- cp kong.conf.default kong.conf
- # 在kong.conf中填入数据地址、用户、密码等
创建kong的数据库:
./bin/kong migrations up -c ./kong.conf
启动kong:
./bin/kong start -c ./kong.conf
kong默认的代理地址是:
proxy_listen = 0.0.0.0:8000, 0.0.0.0:8443
默认的管理地址是:
admin_listen = 127.0.0.1:8001, 127.0.0.1:8444 ssl
返回的是json字符串:
- $ curl -i http://localhost:8001/
- HTTP/1.1 200 OK
- Date: Sat, 29 Sep 2018 08:56:51 GMT
- Content-Type: application/json; charset=utf-8
- Connection: keep-alive
- Access-Control-Allow-Origin: *
- Server: kong/0.14.1
- Content-Length: 5667
- {"plugins":{"enabled_in_cluster":[],"availab...
部署Kong Dashboard
PGBI/kong-dashboard是一个第三方的Dashboard。
- docker run --rm -p 8080:8080 pgbi/kong-dashboard start \
- --kong-url http://kong:8001
- --basic-auth user1=password1 user2=password2
Kong的使用
停止:
kong stop
重新加载:
kong reload
注册API:添加服务、配置路由
添加一个名为example-service
的服务,服务地址是http://mockbin.org
:
- curl -i -X POST \
- --url http://localhost:8001/services/ \
- --data 'name=example-service' \
- --data 'url=http://mockbin.org'
执行后返回:
- {
- "connect_timeout": 60000,
- "created_at": 1538213979,
- "host": "mockbin.org",
- "id": "ebed2707-e2fb-4694-9e8e-fb66fe9dd7c8",
- "name": "example-service",
- "path": null,
- "port": 80,
- "protocol": "http",
- "read_timeout": 60000,
- "retries": 5,
- "updated_at": 1538213979,
- "write_timeout": 60000
- }
为example-service
添加一个route
,满足route的请求将被转发给example-service,执行:
- curl -i -X POST \
- --url http://localhost:8001/services/example-service/routes \
- --data 'hosts[]=example.com'
这里配置的route条件是:host为example.com。
返回:
- {
- "created_at": 1538185340,
- "hosts": [
- "example.com"
- ],
- "id": "4738ae2c-b64a-4fe5-9e2a-5855e769a9e8",
- "methods": null,
- "paths": null,
- "preserve_host": false,
- "protocols": [
- "http",
- "https"
- ],
- "regex_priority": 0,
- "service": {
- "id": "ebed2707-e2fb-4694-9e8e-fb66fe9dd7c8"
- },
- "strip_path": true,
- "updated_at": 1538185340
- }
这时候访问kong的proxy地址
时,如果host为example.com
,请求被转发到http://mockbin.org
:
- curl -i -X GET \
- --url http://localhost:8000/ \
- --header 'Host: example.com'
可以在/etc/hostsname中将example.com地址配置为kong所在的机器的地址:
10.10.192.35 example.com
然后就可以通过example.com:8000
打开http://mockbin.org。
插件启用方法
插件是用来扩展API的,例如为API添加认证、设置ACL、限制速率等、集成oauth、ldap等。
Kong Plugins中列出了已有的所有插件。
这里演示key-auth插件的用法,Kong Enabling Plugins,。
- curl -i -X POST \
- --url http://localhost:8001/services/example-service/plugins/ \
- --data 'name=key-auth'
返回:
- {
- "config": {
- "anonymous": "",
- "hide_credentials": false,
- "key_in_body": false,
- "key_names": [
- "apikey"
- ],
- "run_on_preflight": true
- },
- "created_at": 1538218948000,
- "enabled": true,
- "id": "f25f3952-d0d4-4923-baac-860554fc2fc1",
- "name": "key-auth",
- "service_id": "ebed2707-e2fb-4694-9e8e-fb66fe9dd7c8"
- }
这时候直接访问example.com,会返回401:
- curl -i -X GET \
- > --url http://localhost:8000/ \
- > --header 'Host: example.com'
- HTTP/1.1 401 Unauthorized
- Date: Sat, 29 Sep 2018 11:03:55 GMT
- Content-Type: application/json; charset=utf-8
- Connection: keep-alive
- WWW-Authenticate: Key realm="kong"
- Server: kong/0.14.1
- Content-Length: 41
在kong中创建一个名为Jason的用户:
- curl -i -X POST \
- --url http://localhost:8001/consumers/ \
- --data "username=Jason"
返回:
- {
- "created_at": 1538219225,
- "custom_id": null,
- "id": "f2450962-e4bb-477f-8df6-85984eb94e09",
- "username": "Jason"
- }
将Jason的密码设置为123456:
- curl -i -X POST \
- --url http://localhost:8001/consumers/Jason/key-auth/ \
- --data 'key=123456'
返回:
- {
- "consumer_id": "f2450962-e4bb-477f-8df6-85984eb94e09",
- "created_at": 1538219311000,
- "id": "0332d36f-61b9-425a-b563-510c11a85e85",
- "key": "123456"
- }
这时候可以用Jason的key访问API:
- curl -i -X GET \
- --url http://localhost:8000 \
- --header "Host: example.com" \
- --header "apikey: 123456"
返回的是mockbin.org的首页。
key-auth插件的详细用法参考Kong Plugin: key-auth。插件的作用范围可以是全局(global)、服务(service)、路由(router)。
启用key-auth后,通过认证的请求被转发给上游服务时,key-auth会增设下面的字段:
- X-Consumer-ID, the ID of the Consumer on Kong
- X-Consumer-Custom-ID, the custom_id of the Consumer (if set)
- X-Consumer-Username, the username of the Consumer (if set)
- X-Credential-Username, the username of the Credential (only if the consumer is not the 'anonymous' consumer)
- X-Anonymous-Consumer, will be set to true when authentication failed, and the 'anonymous' consumer was set instead.
Kong的插件
Kong Plugins中列出了已有的所有插件,有些插件只能在企业版使用,有些插件是社区成员开发的,大部分是Kong公司开发,并集成到社区版中。
下面是社区版集成的、Kong公司维护的插件(2018-09-30 14:33:03):
认证插件:
- Basic Auth
- HMAC Auth
- JWT Auth
- Key Auth
- LDAP Auth
- OAuth 2.0 Auth
安全插件:
- Bot Detection (机器人检测)
- CORS (跨域请求)
- IP Restriction (IP限制)
流控插件:
- ACL (访问控制)
- Rate Limiting (限速)
- Request Size Limiting
- Request Termination
- Response Rate Limiting
微服务插件:
- AWS Lambda
- Azure Functions
- Apache OpenWhisk
- Serverless Functions
分析和监控插件:
- Datadog
- Prometheus
- Zipkin
内容修改插件(Transformations):
- Correlation ID
- Request Transformer
- Response Transformer
日志插件:
- File Log
- HTTP Log
- Loggly
- StatsD
- Syslog
- TCP Log
- UDP Log
Kong与Kubernetes的集成
经过前面的学习,对Api网关是什么,以及Kong能够做什么已经有了足够的了解。现在Kubernetes一统计算资源与应用发布编排的趋势已经形成,我们更关心Kong能否和Kubernetes结合。
Kong是一个Api网关,也是一个特性更丰富的反向代理,既然它有代理流量的功能,那么能不能直接成为Kubernetes的流量入口?使Kubernetes内部的服务都通过Kong发布。
Kong实现了一个Kubernetes Ingress Controller来做这件事。在Kubernetes中部署kong的方法见Kong CE or EE on Kubernetes。
这部分内容比较多,单独开篇了: Kubernetes与API网关Kong的集成。
遇到的问题
ERROR: module ‘socket’ not found:No LuaRocks module found for socket
启动的时候:
- # ./bin/kong start -c ./kong.conf
- ...
- ERROR: ./kong/globalpatches.lua:63: module 'socket' not found:No LuaRocks module found for socket
- ...
这是因为编译kong之后,重新编译了luarocks,并且将luarocks安装在了其它位置。重新编译kong之后解决。
ERROR: function to_regclass(unknown) does not exist (8)
创建数据库的时候:
- # kong migrations up -c ./kong.conf
- ...
- [postgres error] could not retrieve current migrations: [postgres error] ERROR: function to_regclass(unknown) does not exist (8)
- ...
这是因为PostgreSQL的版本太低了,to_regclass
在PostgreSQL 9.4及以上的版本中才存在。
- yum install https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm
- yum install postgresql96
- yum install postgresql96-server
nginx: [emerg] unknown directive “real_ip_header” in /usr/local/kong/nginx-kong.conf:73
nginx: [emerg] unknown directive "real_ip_header" in /usr/local/kong/nginx-kong.conf:73
这是因为编译的openresty的时候,没有指定--with-http_realip_module
,重新编译安装:
- ./configure --with-pcre-jit --with-http_ssl_module --with-http_realip_module --with-http_stub_status_module --with-http_v2_module
- make -j2
- make install //默认安装在/usr/local/bin/openresty
- export PATH=/usr/local/openresty/bin:$PATH
参考
- nginx website
- OpenResty website
- Kong website
- Kong Compile Source
- nginx features
- nginx documentation
- Nginx Example Configuration & Directives
- Nginx: Alphabetical index of directives
- Nginx: Alphabetical index of variables
- Beginner’s Guide
- Nginx: ngx_http_fastcgi_module
- Nginx: ngx_http_proxy_module
- Nginx Documents
- Nginx: Module ngx_stream_core_module
- OpenResty website
- OpenResty Components
- OpenResty Getting Started
- Nginx Development guide
- Nginx Module develop
- PostgreSQL的用户到底是这么回事?新用户怎样才能用密码登陆?
- PostgresSQL数据库的基本使用
- Kong Enabling Plugins
- Kong Plugin: key-auth
- Kong Plugins
- Kong CE or EE on Kubernetes
- Kong/kubernetes-ingress-controller
- PGBI/kong-dashboard
限时活动,每邀请一人即返回25元!
相关文章
Kubernetes1.12从零开始(五):自己动手部署Kubernetes(待续)
Kubernetes1.12从零开始(四):必须先讲一下基本概念
Nginx、OpenResty和Kong的基本概念与使用方法的更多相关文章
- Kong03-Nginx、OpenResty、Kong 的基本概念和区别联系
Nginx.OpenRestry.Kong 这三个项目关系比较紧密: Nginx 是模块化设计的反向代理软件,C语言开发: OpenResty 是以 Nginx 为核心的 Web 开发平台,可以解析执 ...
- 我眼中的 Nginx(六):深入 Nginx/Openresty 服务里的 DNS 解析
张超:又拍云系统开发高级工程师,负责又拍云 CDN 平台相关组件的更新及维护.Github ID: tokers,活跃于 OpenResty 社区和 Nginx 邮件列表等开源社区,专注于服务端技术的 ...
- 使用NGINX+Openresty和unixhot_waf开源防火墙实现WAF功能
使用NGINX+Openresty实现WAF功能 一.了解WAF1.1 什么是WAF Web应用防护系统(也称:网站应用级入侵防御系统 .英文:Web Application Firewall,简称: ...
- 基于 orange(nginx+openresty) + docker 实现微服务 网关功能
摘要 基于 orange(nginx+openresty) + docker 实现微服务 网关功能 ;以实现 docker 独立容器 来跑 独立语言独立环境 在 同一个授权下 运行相关组合程序..年初 ...
- Nginx出现413 Request Entity Too Large错误解决方法
Nginx出现的413 Request Entity Too Large错误,这个错误一般在上传文件的时候出现,打开nginx主配置文件nginx.conf,找到http{}段,添加 解决方法就是 打 ...
- AWS Python SDK boto3中的基本概念与使用方法
最近在用boto3编写AWS的lamda函数,学习到了boto3中的一些基本概念与使用方法.在此进行总结. 1. boto3提供了两个级别的接口来访问AWS服务:High Level的Resource ...
- Nginx出现“413 Request Entity Too Large”错误解决方法
Nginx出现“413 Request Entity Too Large”错误解决方法 2011-03-25 13:49:55| 分类: 默认分类 | 标签:413 request entit ...
- UIImageView图片视图的基本概念和使用方法
IOS学习笔记(十)之UIImageView图片视图的基本概念和使用方法(博客地址: http://blog.csdn.net/developer_jiangqq ) Author:hmjiangqq ...
- 使用nginx的rewrite实现代理指定文件夹命令方法
使用nginx的rewrite实现代理指定文件夹命令方法 使用nginx代理Tomcat,Tomcat公布web的时候通常都是带着项目名称的. 比方项目名称为"aven".那么公布 ...
随机推荐
- 1.3 JAVA规范以及基础语法(if条件和循环)
一.规范以及运算符 1.命名规则 类名大驼峰规则方法名.变量名小驼峰原则常量大写.下划线分开见名释义.不与关键字冲突 关键字链接:https://www.runoob.com/java/java-ba ...
- vuecli3.0 webpack4 配置vuex
废话不说,直接写步骤 1. npm install vux --save 2. npm install less less-loader --save-dev 3. npm install @vux/ ...
- 22.从上往下打印二叉树 Java
题目描述 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 解题思路 就是二叉树的层序遍历.借助一个队列就可以实现.使用两个队列一个存放节点,一个存放值.先将根节点加入到队列中,然后遍历队列中的 ...
- VSCode查询快捷键对应功能技巧
- 异步发送表单数据到JavaBean,并响应JSON文本返回
1) 提交表单后,将JavaBean信息以JSON文本形式返回到浏览器 <form> 编号:<input type="text" name="id&q ...
- delphi设置鼠标图形
//Screen.Cursor := crHourGlass;//忙 //Screen.Cursor := crDefault;//不忙时
- Django学习之缓存和信号
Django学习之缓存和信号 一 缓存 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views ...
- Git(2):基本操作
Git 创建仓库 执行<git init>命令后,Git仓库会生成一个.git目录,该目录包含了资源的所有元数据,其他的项目目录保持不变(Git 只在仓库的根目录生成 .git 目录). ...
- HTML5 DOM 新增数据类型
HTML5 DOM 新增数据类型 前言 相对于HTML4当中的DOM,在HTML5中的DOM,新增了很多复杂数据类型,为实际的应用提供了便捷的操作. 在HTML5 DOM中,新增了如下的内容: HTM ...
- Django:(02)项目配置
上一篇我们创建了一个Django项目,并且让它运行了起来了. 当是,我们还没有使用到我们创建的应用,以及templates模版目录. 需求: 在此之前我们根据需要对我们的项目进行配置修改. 在项目开发 ...