Web架构笔记
一、Web项目概述
1.1 Web项目介绍
Web项目是基于浏览器/服务器(B/S)架构的应用程序,用户通过浏览器访问服务器提供的服务。
Web项目组成
| 组成部分 |
说明 |
示例 |
| 前端 |
用户界面,运行在浏览器中 |
HTML、CSS、JavaScript |
| 后端 |
业务逻辑,运行在服务器中 |
PHP、Java、Python |
| 数据库 |
数据存储 |
MySQL、MariaDB、MongoDB |
| Web服务器 |
处理HTTP请求 |
Nginx、Apache、Tomcat |
Web访问流程
┌─────────┐ HTTP请求 ┌─────────┐ 查询 ┌─────────┐
│ 浏览器 │ ───────────────> │Web服务器 │ ───────────> │ 数据库 │
│ (客户端) │ │ (后端) │ │ │
│ │ <─────────────── │ │ <─────────── │ │
└─────────┘ HTTP响应 └─────────┘ 结果 └─────────┘
1.2 网站架构组合
常见架构组合
| 架构名称 |
组成 |
说明 |
| LAMP |
Linux + Apache + MySQL + PHP |
经典架构,适合PHP项目 |
| LNMP |
Linux + Nginx + MySQL + PHP |
高性能架构,Nginx处理静态资源更强 |
| LNMT |
Linux + Nginx + MySQL + Tomcat |
Java项目常用架构 |
| LEMP |
Linux + Nginx + MySQL + Python |
Python项目架构 |
架构选择建议
| 项目类型 |
推荐架构 |
原因 |
| PHP项目 |
LNMP |
Nginx高并发处理能力强 |
| Java项目 |
LNMT |
Tomcat是Java Web容器 |
| Python项目 |
LEMP |
Python生态完善 |
| 静态网站 |
Nginx |
配置简单,性能高 |
二、HTML基础
2.1 HTML介绍
HTML(HyperText Markup Language,超文本标记语言)是构建网页的基础语言,使用标签来描述网页结构。
HTML文档基本结构
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>网页标题</title>
</head>
<body>
<!-- 网页内容 -->
<h1>一级标题</h1>
<p>段落内容</p>
</body>
</html>
2.2 常用HTML标签
文本标签
| 标签 |
说明 |
示例 |
<h1> ~ <h6> |
标题标签 |
<h1>一级标题</h1> |
<p> |
段落标签 |
<p>段落内容</p> |
<br> |
换行标签 |
第一行<br>第二行 |
<hr> |
水平线 |
<hr> |
<strong> |
加粗 |
<strong>加粗文字</strong> |
<em> |
斜体 |
<em>斜体文字</em> |
列表标签
<!-- 无序列表 -->
<ul>
<li>项目1</li>
<li>项目2</li>
</ul>
<!-- 有序列表 -->
<ol>
<li>第一步</li>
<li>第二步</li>
</ol>
超链接标签
<a href="https://www.example.com">访问网站</a>
<a href="https://www.example.com" target="_blank">新窗口打开</a>
<a href="#section1">页内跳转</a>
<a href="mailto:admin@example.com">发送邮件</a>
图片标签
<img src="image.jpg" alt="图片描述" width="300" height="200">
多媒体标签
<!-- 音频 -->
<audio controls>
<source src="audio.mp3" type="audio/mpeg">
</audio>
<!-- 视频 -->
<video controls width="640" height="360">
<source src="video.mp4" type="video/mp4">
</video>
2.3 表格标签
<table border="1">
<tr>
<th>姓名</th>
<th>年龄</th>
</tr>
<tr>
<td>张三</td>
<td>25</td>
</tr>
</table>
2.4 表单标签
表单基本结构
<form action="/submit" method="POST">
<input type="text" name="username" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<input type="submit" value="提交">
</form>
| type属性 |
说明 |
示例 |
| text |
文本输入框 |
<input type="text"> |
| password |
密码输入框 |
<input type="password"> |
| radio |
单选按钮 |
<input type="radio"> |
| checkbox |
复选框 |
<input type="checkbox"> |
| file |
文件上传 |
<input type="file"> |
| hidden |
隐藏字段 |
<input type="hidden"> |
| submit |
提交按钮 |
<input type="submit"> |
| button |
普通按钮 |
<input type="button"> |
select下拉框
<select name="city">
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
</select>
多行文本框
<textarea name="content" rows="5" cols="30">默认内容</textarea>
2.5 div与span
| 标签 |
类型 |
说明 |
<div> |
块级元素 |
独占一行,用于布局容器 |
<span> |
行内元素 |
不换行,用于文本样式 |
2.6 HTML实体编码
| 实体 |
显示 |
说明 |
< |
< |
小于号 |
> |
> |
大于号 |
& |
& |
和号 |
" |
" |
双引号 |
|
空格 |
不间断空格 |
三、HTTP协议
3.1 HTTP协议简介
HTTP(HyperText Transfer Protocol,超文本传输协议)是浏览器与服务器之间通信的协议,规定了请求和响应的格式。
HTTP协议特点
| 特点 |
说明 |
| 无状态 |
服务器不保存客户端状态 |
| 基于TCP |
建立在TCP连接之上 |
| 请求-响应模式 |
客户端发起请求,服务器返回响应 |
| 灵活 |
可传输任意类型数据 |
3.2 HTTP请求报文
请求报文结构
请求行
请求头部
空行
请求体
请求报文示例
POST /login HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
User-Agent: Mozilla/5.0
username=admin&password=123456
请求行组成
| 组成部分 |
说明 |
示例 |
| 请求方法 |
操作类型 |
GET、POST、PUT、DELETE |
| 请求URL |
资源路径 |
/index.html |
| HTTP版本 |
协议版本 |
HTTP/1.1 |
HTTP请求方法
| 方法 |
说明 |
是否有请求体 |
| GET |
获取资源 |
无 |
| POST |
提交数据 |
有 |
| PUT |
更新资源 |
有 |
| DELETE |
删除资源 |
可有可无 |
| HEAD |
获取响应头 |
无 |
| OPTIONS |
获取支持的方法 |
无 |
常见请求头
| 请求头 |
说明 |
示例 |
| Host |
目标主机名 |
Host: www.example.com |
| User-Agent |
客户端信息 |
User-Agent: Mozilla/5.0 |
| Accept |
接受的内容类型 |
Accept: text/html |
| Content-Type |
请求体类型 |
Content-Type: application/json |
| Content-Length |
请求体长度 |
Content-Length: 1024 |
| Cookie |
携带的Cookie |
Cookie: sessionid=abc123 |
| Referer |
来源页面 |
Referer: https://www.google.com |
| Authorization |
认证信息 |
Authorization: Basic xxx |
3.3 HTTP响应报文
响应报文结构
状态行
响应头部
空行
响应体
响应报文示例
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
Server: nginx/1.20.1
Set-Cookie: sessionid=abc123
<!DOCTYPE html>
<html>
<head><title>首页</title></head>
<body><h1>Hello World</h1></body>
</html>
状态行组成
| 组成部分 |
说明 |
示例 |
| HTTP版本 |
协议版本 |
HTTP/1.1 |
| 状态码 |
响应状态 |
200 |
| 原因短语 |
状态描述 |
OK |
HTTP状态码分类
| 类别 |
范围 |
说明 |
| 1xx |
100-199 |
信息性响应 |
| 2xx |
200-299 |
成功响应 |
| 3xx |
300-399 |
重定向 |
| 4xx |
400-499 |
客户端错误 |
| 5xx |
500-599 |
服务器错误 |
常见状态码
| 状态码 |
说明 |
常见原因 |
| 200 |
OK,请求成功 |
正常响应 |
| 301 |
永久重定向 |
域名更换 |
| 302 |
临时重定向 |
页面临时跳转 |
| 304 |
Not Modified |
缓存有效 |
| 400 |
Bad Request |
请求格式错误 |
| 401 |
Unauthorized |
未认证 |
| 403 |
Forbidden |
无权限访问 |
| 404 |
Not Found |
资源不存在 |
| 500 |
Internal Server Error |
服务器内部错误 |
| 502 |
Bad Gateway |
网关错误 |
| 503 |
Service Unavailable |
服务不可用 |
| 504 |
Gateway Timeout |
网关超时 |
常见响应头
| 响应头 |
说明 |
示例 |
| Content-Type |
响应体类型 |
Content-Type: text/html |
| Content-Length |
响应体长度 |
Content-Length: 1024 |
| Server |
服务器信息 |
Server: nginx/1.20.1 |
| Set-Cookie |
设置Cookie |
Set-Cookie: sessionid=abc123 |
| Location |
重定向地址 |
Location: https://www.example.com |
| Cache-Control |
缓存控制 |
Cache-Control: max-age=3600 |
3.4 HTTPS协议
HTTPS与HTTP区别
| 对比项 |
HTTP |
HTTPS |
| 端口 |
80 |
443 |
| 传输 |
明文传输 |
SSL/TLS加密传输 |
| 安全性 |
低 |
高 |
| 证书 |
无需 |
需要SSL证书 |
HTTPS工作原理
1. 客户端发起HTTPS请求
2. 服务器返回SSL证书(包含公钥)
3. 客户端验证证书有效性
4. 客户端生成对称密钥,用公钥加密发送给服务器
5. 服务器用私钥解密获取对称密钥
6. 双方使用对称密钥加密通信
四、Nginx Web服务器
4.1 Nginx简介
Nginx是一款高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。
Nginx特点
| 特点 |
说明 |
| 高并发 |
支持数万并发连接 |
| 低内存 |
内存占用少 |
| 反向代理 |
支持反向代理和负载均衡 |
| 静态处理 |
静态文件处理能力强 |
| 模块化 |
功能模块化设计 |
4.2 Nginx安装
CentOS安装
# 安装EPEL源
yum install -y epel-release
# 安装Nginx
yum install -y nginx
# 启动Nginx
systemctl start nginx
systemctl enable nginx
# 查看状态
systemctl status nginx
Ubuntu安装
# 更新包列表
sudo apt update
# 安装Nginx
sudo apt install -y nginx
# 启动Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
编译安装
# 安装依赖
yum install -y gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
# 下载源码
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# 配置编译选项
./configure --prefix=/usr/local/nginx --with-http_ssl_module
# 编译安装
make && make install
4.3 Nginx目录结构
| 目录/文件 |
说明 |
/etc/nginx/ |
配置文件目录 |
/etc/nginx/nginx.conf |
主配置文件 |
/etc/nginx/conf.d/ |
额外配置目录 |
/usr/share/nginx/html/ |
默认网站根目录 |
/var/log/nginx/ |
日志目录 |
/var/log/nginx/access.log |
访问日志 |
/var/log/nginx/error.log |
错误日志 |
4.4 Nginx基本命令
| 命令 |
说明 |
nginx |
启动Nginx |
nginx -s stop |
快速停止 |
nginx -s quit |
优雅停止 |
nginx -s reload |
重新加载配置 |
nginx -t |
测试配置文件语法 |
nginx -v |
查看版本 |
4.5 Nginx配置文件结构
# 全局配置
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# 事件配置
events {
worker_connections 1024;
}
# HTTP配置
http {
# 全局HTTP配置
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
access_log /var/log/nginx/access.log main;
# 包含其他配置文件
include /etc/nginx/conf.d/*.conf;
# 服务器配置
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}
配置层级结构
main(全局配置)
├── events(事件配置)
└── http(HTTP配置)
├── upstream(上游服务器组)
└── server(虚拟主机)
└── location(URL匹配)
五、Nginx虚拟主机配置
5.1 虚拟主机概述
虚拟主机是在一台物理服务器上运行多个网站的技术,Nginx支持三种虚拟主机配置方式:
| 方式 |
说明 |
适用场景 |
| 多端口 |
不同端口对应不同站点 |
测试环境、内部系统 |
| 多IP |
不同IP对应不同站点 |
多网卡服务器 |
| 多域名 |
不同域名对应不同站点 |
生产环境最常用 |
5.2 多端口部署多站点
配置示例
# 站点1 - 监听80端口
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/site1;
index index.html;
}
}
# 站点2 - 监听8080端口
server {
listen 8080;
server_name localhost;
location / {
root /usr/share/nginx/site2;
index index.html;
}
}
创建站点目录
mkdir -p /usr/share/nginx/site1
mkdir -p /usr/share/nginx/site2
echo "<h1>Site 1 - Port 80</h1>" > /usr/share/nginx/site1/index.html
echo "<h1>Site 2 - Port 8080</h1>" > /usr/share/nginx/site2/index.html
5.3 多IP部署多站点
配置示例
# 站点1 - IP 192.168.1.100
server {
listen 192.168.1.100:80;
server_name localhost;
location / {
root /usr/share/nginx/site1;
index index.html;
}
}
# 站点2 - IP 192.168.1.101
server {
listen 192.168.1.101:80;
server_name localhost;
location / {
root /usr/share/nginx/site2;
index index.html;
}
}
5.4 多域名部署多站点
配置示例
# 站点1 - 域名 www.site1.com
server {
listen 80;
server_name www.site1.com;
location / {
root /usr/share/nginx/site1;
index index.html;
}
}
# 站点2 - 域名 www.site2.com
server {
listen 80;
server_name www.site2.com;
location / {
root /usr/share/nginx/site2;
index index.html;
}
}
域名解析配置
# DNS解析记录
www.site1.com -> 192.168.1.100
www.site2.com -> 192.168.1.100
5.5 include配置加载
配置分离
# /etc/nginx/nginx.conf
http {
# ... 其他配置 ...
# 包含站点配置
include /etc/nginx/conf.d/*.conf;
}
独立站点配置文件
# /etc/nginx/conf.d/site1.conf
server {
listen 80;
server_name www.site1.com;
location / {
root /usr/share/nginx/site1;
index index.html;
}
}
# /etc/nginx/conf.d/site2.conf
server {
listen 80;
server_name www.site2.com;
location / {
root /usr/share/nginx/site2;
index index.html;
}
}
六、Nginx高级配置
6.1 日志配置
日志格式定义
http {
# 定义日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format json escape=json '{'
'"time":"$time_local",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":"$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';
}
日志变量说明
| 变量 |
说明 |
$remote_addr |
客户端IP地址 |
$remote_user |
客户端用户名 |
$time_local |
访问时间 |
$request |
请求方法和URL |
$status |
响应状态码 |
$body_bytes_sent |
响应体大小 |
$http_referer |
来源页面 |
$http_user_agent |
客户端信息 |
$http_x_forwarded_for |
代理IP链 |
站点独立日志
server {
listen 80;
server_name www.example.com;
access_log /var/log/nginx/example.access.log main;
error_log /var/log/nginx/example.error.log;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
6.2 Basic认证
创建密码文件
# 安装httpd-tools
yum install -y httpd-tools
# 创建密码文件
htpasswd -c /etc/nginx/.htpasswd admin
# 添加用户
htpasswd /etc/nginx/.htpasswd user1
配置Basic认证
server {
listen 80;
server_name www.example.com;
location /admin {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
root /usr/share/nginx/html;
index index.html;
}
}
6.3 SSL证书配置
证书文件准备
/etc/nginx/ssl/
├── example.com.crt # 证书文件
└── example.com.key # 私钥文件
HTTPS配置
server {
listen 443 ssl;
server_name www.example.com;
# SSL证书配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# SSL优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
# HTTP跳转HTTPS
server {
listen 80;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}
6.4 return跳转
跳转配置示例
# 301永久重定向
return 301 https://www.example.com$request_uri;
# 302临时重定向
return 302 http://www.newsite.com;
# 返回指定状态码和内容
return 200 "OK";
return 403 "Access Denied";
return 444; # 关闭连接,不返回响应
域名跳转
server {
listen 80;
server_name example.com;
return 301 http://www.example.com$request_uri;
}
6.5 rewrite重写
rewrite语法
rewrite regex replacement [flag];
flag标志说明
| flag |
说明 |
last |
停止处理,重新搜索location |
break |
停止处理,不再搜索 |
redirect |
返回302临时重定向 |
permanent |
返回301永久重定向 |
rewrite示例
# 将旧URL重写到新URL
rewrite ^/old-page.html$ /new-page.html permanent;
# 将带参数的URL重写
rewrite ^/article/([0-9]+)$ /article.php?id=$1 last;
# 域名跳转
if ($host = 'example.com') {
rewrite ^/(.*)$ http://www.example.com/$1 permanent;
}
# 伪静态规则
rewrite ^/products/([0-9]+)/?$ /products.php?id=$1 last;
6.6 gzip压缩
gzip配置
http {
# 开启gzip
gzip on;
# 压缩级别(1-9)
gzip_comp_level 6;
# 最小压缩大小
gzip_min_length 1k;
# 压缩类型
gzip_types text/plain text/css text/javascript application/json application/javascript application/xml;
# 压缩缓冲区
gzip_buffers 4 16k;
# 压缩版本
gzip_http_version 1.1;
# 是否传输Vary头
gzip_vary on;
}
6.7 目录浏览
配置目录浏览
location /files {
alias /data/files/;
autoindex on; # 开启目录浏览
autoindex_exact_size off; # 显示文件大小(人性化)
autoindex_localtime on; # 显示本地时间
charset utf-8; # 设置编码
}
6.8 访问控制
IP访问控制
# 允许特定IP访问
location /admin {
allow 192.168.1.0/24;
allow 10.0.0.1;
deny all;
root /usr/share/nginx/html;
}
# 拒绝特定IP访问
location / {
deny 192.168.1.100;
allow all;
}
基于用户认证
location /private {
auth_basic "Private Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
6.9 location匹配规则
location语法
location [=|~|~*|^~] /uri/ { ... }
匹配符号说明
| 符号 |
说明 |
示例 |
= |
精确匹配 |
location = /exact {} |
~ |
正则匹配(区分大小写) |
location ~ \.php$ {} |
~* |
正则匹配(不区分大小写) |
`location ~* .(gif |
^~ |
前缀匹配,匹配后不检查正则 |
location ^~ /images/ {} |
| 无 |
普通前缀匹配 |
location / {} |
匹配优先级
1. = 精确匹配(最高优先级)
2. ^~ 前缀匹配
3. ~ 和 ~* 正则匹配(按配置顺序)
4. 无符号前缀匹配(最长匹配优先)
location配置示例
server {
# 精确匹配首页
location = / {
root /usr/share/nginx/html;
index index.html;
}
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
root /usr/share/nginx/html;
}
# PHP处理
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 图片目录
location ^~ /images/ {
root /usr/share/nginx/html;
expires 7d;
}
# 默认匹配
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
6.10 Nginx常用变量
| 变量 |
说明 |
示例 |
$host |
请求的主机名 |
www.example.com |
$server_name |
服务器名称 |
www.example.com |
$remote_addr |
客户端IP |
192.168.1.100 |
$request_uri |
完整请求URI |
/path?arg=value |
$uri |
当前URI(不含参数) |
/path |
$args |
URL参数 |
arg=value |
$request_method |
请求方法 |
GET、POST |
$scheme |
协议 |
http、https |
$server_port |
服务器端口 |
80、443 |
$http_referer |
来源页面 |
https://www.google.com |
$http_user_agent |
客户端信息 |
Mozilla/5.0... |
$http_cookie |
Cookie信息 |
sessionid=abc123 |
$document_root |
根目录路径 |
/usr/share/nginx/html |
6.11 防盗链配置
基于Referer防盗链
location ~* \.(jpg|jpeg|png|gif|bmp|swf)$ {
valid_referers none blocked www.example.com *.example.com;
if ($invalid_referer) {
return 403;
# 或返回防盗链图片
# rewrite ^/.*$ /images/deny.png break;
}
root /usr/share/nginx/html;
}
6.12 多语言站点配置
基于Accept-Language
server {
listen 80;
server_name www.example.com;
# 中文站点
location / {
if ($http_accept_language ~* "^zh") {
rewrite ^(.*)$ /cn$1 redirect;
}
if ($http_accept_language ~* "^en") {
rewrite ^(.*)$ /en$1 redirect;
}
root /usr/share/nginx/html;
}
location /cn {
alias /usr/share/nginx/html/cn/;
}
location /en {
alias /usr/share/nginx/html/en/;
}
}
6.13 PHP动态网站配置
PHP-FPM配置
server {
listen 80;
server_name www.example.com;
root /usr/share/nginx/html;
index index.php index.html;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
安装PHP-FPM
# CentOS
yum install -y php php-fpm php-mysql
systemctl start php-fpm
systemctl enable php-fpm
# Ubuntu
sudo apt install -y php php-fpm php-mysql
sudo systemctl start php7.4-fpm
sudo systemctl enable php7.4-fpm
七、Nginx反向代理与负载均衡
7.1 正向代理
正向代理是客户端通过代理服务器访问外部资源,代理服务器代表客户端访问目标服务器。
正向代理示意图
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 客户端 │ ──> │ 代理服务器 │ ──> │ 目标服务器 │
└─────────┘ └─────────┘ └─────────┘
正向代理配置
server {
listen 8080;
resolver 8.8.8.8;
location / {
proxy_pass $scheme://$host$request_uri;
proxy_set_header Host $host;
}
}
7.2 反向代理
反向代理是代理服务器接收客户端请求,然后将请求转发给内部服务器,客户端不知道真实服务器地址。
反向代理示意图
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 客户端 │ ──> │ 反向代理 │ ──> │ 后端服务器 │
└─────────┘ └─────────┘ └─────────┘
反向代理配置
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://192.168.1.100:8080;
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;
}
}
常用proxy指令
| 指令 |
说明 |
proxy_pass |
后端服务器地址 |
proxy_set_header |
设置转发请求头 |
proxy_redirect |
修改响应头中的Location |
proxy_connect_timeout |
连接超时时间 |
proxy_read_timeout |
读取超时时间 |
proxy_send_timeout |
发送超时时间 |
7.3 负载均衡
负载均衡是将请求分发到多台后端服务器,提高系统可用性和性能。
负载均衡示意图
┌─────────────┐
│ 客户端 │
└──────┬──────┘
│
▼
┌─────────────┐
│ 负载均衡器 │
│ (Nginx) │
└──────┬──────┘
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 服务器A │ │ 服务器B │ │ 服务器C │
└──────────┘ └──────────┘ └──────────┘
负载均衡配置
# 定义后端服务器组
upstream backend {
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
负载均衡算法
| 算法 |
说明 |
配置方式 |
| 轮询(默认) |
按顺序分发 |
无需配置 |
| 权重 |
按权重分发 |
weight=n |
| IP哈希 |
同一IP固定服务器 |
ip_hash |
| 最少连接 |
分发到连接最少的服务器 |
least_conn |
| URL哈希 |
同一URL固定服务器 |
hash $request_uri |
负载均衡算法配置
# 权重配置
upstream backend {
server 192.168.1.101:8080 weight=3;
server 192.168.1.102:8080 weight=2;
server 192.168.1.103:8080 weight=1;
}
# IP哈希
upstream backend {
ip_hash;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}
# 最少连接
upstream backend {
least_conn;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}
服务器状态参数
| 参数 |
说明 |
weight |
权重值 |
max_fails |
最大失败次数 |
fail_timeout |
失败超时时间 |
backup |
备用服务器 |
down |
标记服务器离线 |
upstream backend {
server 192.168.1.101:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8080 weight=2;
server 192.168.1.103:8080 backup; # 备用服务器
server 192.168.1.104:8080 down; # 离线维护
}
八、Cookie与Session
8.1 Cookie
Cookie是服务器发送到浏览器并保存在本地的一小段数据,每次请求时会自动携带。
Cookie特点
| 特点 |
说明 |
| 存储位置 |
客户端(浏览器) |
| 存储大小 |
单个Cookie不超过4KB |
| 存储内容 |
ASCII字符串 |
| 安全性 |
较低,易被窃取或篡改 |
Cookie属性
| 属性 |
说明 |
Name=Value |
Cookie名称和值 |
Expires |
过期时间 |
Max-Age |
有效期(秒) |
Domain |
作用域名 |
Path |
作用路径 |
Secure |
仅HTTPS传输 |
HttpOnly |
禁止JavaScript访问 |
SameSite |
跨站限制 |
Cookie工作流程
1. 客户端首次请求服务器
2. 服务器生成Cookie,通过Set-Cookie响应头返回
3. 浏览器保存Cookie
4. 后续请求自动携带Cookie
5. 服务器识别Cookie,判断用户身份
HTTP Cookie示例
# 响应头设置Cookie
Set-Cookie: sessionid=abc123; Path=/; HttpOnly; Secure
# 请求头携带Cookie
Cookie: sessionid=abc123
8.2 Session
Session是服务器端存储用户会话数据的机制,通过Session ID与客户端关联。
Session特点
| 特点 |
说明 |
| 存储位置 |
服务器端 |
| 存储大小 |
无限制 |
| 存储内容 |
任意数据类型 |
| 安全性 |
较高 |
Session工作流程
1. 客户端首次请求服务器
2. 服务器创建Session,生成唯一Session ID
3. 服务器通过Set-Cookie返回Session ID
4. 浏览器保存Session ID到Cookie
5. 后续请求携带Session ID
6. 服务器根据Session ID查找对应Session数据
Session与Cookie关系
┌──────────────────────────────────────────────────────────────┐
│ 服务器 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Session存储区 │ │
│ │ Session ID: abc123 │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ 用户ID: 1001 │ │ │
│ │ │ 用户名: admin │ │ │
│ │ │ 登录时间: 2024-01-01 10:00:00 │ │ │
│ │ │ 权限: admin │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
▲
│ Session ID: abc123
│
┌──────────────────────────────────────────────────────────────┐
│ 浏览器 │
│ Cookie: sessionid=abc123 │
└──────────────────────────────────────────────────────────────┘
8.3 Cookie与Session对比
| 对比项 |
Cookie |
Session |
| 存储位置 |
客户端 |
服务器端 |
| 存储大小 |
≤4KB |
无限制 |
| 存储类型 |
ASCII |
任意类型 |
| 安全性 |
较低 |
较高 |
| 有效期 |
可设置长时间 |
一般较短 |
| 服务器资源 |
不占用 |
占用 |
8.4 登录认证流程
1. 用户输入用户名和密码
2. 服务器验证用户信息
3. 验证通过,创建Session
4. 生成Session ID,返回给客户端
5. 客户端保存Session ID到Cookie
6. 后续请求携带Session ID
7. 服务器验证Session ID有效性
8. 有效则允许访问,无效则跳转登录
九、数据库与动态网站
9.1 数据库介绍
数据库是存储和管理数据的系统,Web项目常用的数据库分为关系型和非关系型。
数据库分类
| 类型 |
说明 |
常见数据库 |
| 关系型数据库 |
结构化数据,使用SQL |
MySQL、MariaDB、PostgreSQL、Oracle |
| 非关系型数据库 |
灵活数据结构 |
MongoDB、Redis、Elasticsearch |
9.2 MariaDB安装
CentOS安装
# 添加MariaDB源
vim /etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.5/centos7-amd64
gpgkey = https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck = 1
# 安装MariaDB
yum install -y MariaDB-server MariaDB-client
# 启动服务
systemctl start mariadb
systemctl enable mariadb
# 安全配置
mysql_secure_installation
Ubuntu安装
sudo apt update
sudo apt install -y mariadb-server
sudo systemctl start mariadb
sudo systemctl enable mariadb
sudo mysql_secure_installation
9.3 MySQL基本操作
数据库操作
-- 创建数据库
CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4;
-- 查看数据库
SHOW DATABASES;
-- 使用数据库
USE mydb;
-- 删除数据库
DROP DATABASE mydb;
表操作
-- 创建表
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(100) NOT NULL,
email VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 查看表结构
DESC users;
-- 删除表
DROP TABLE users;
数据操作
-- 插入数据
INSERT INTO users (username, password, email)
VALUES ('admin', 'password123', 'admin@example.com');
-- 查询数据
SELECT * FROM users;
SELECT username, email FROM users WHERE id = 1;
-- 更新数据
UPDATE users SET email = 'newemail@example.com' WHERE id = 1;
-- 删除数据
DELETE FROM users WHERE id = 1;
用户权限管理
-- 创建用户
CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'password123';
-- 授权
GRANT ALL PRIVILEGES ON mydb.* TO 'webuser'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;
-- 查看用户权限
SHOW GRANTS FOR 'webuser'@'localhost';
9.4 网站架构组合
LNMP架构
┌─────────────────────────────────────────────────────────────┐
│ 用户浏览器 │
└─────────────────────────┬───────────────────────────────────┘
│ HTTP请求
▼
┌─────────────────────────────────────────────────────────────┐
│ Nginx (80/443) │
│ 处理静态请求、反向代理PHP请求 │
└─────────────────────────┬───────────────────────────────────┘
│ FastCGI
▼
┌─────────────────────────────────────────────────────────────┐
│ PHP-FPM (9000) │
│ 处理PHP动态请求 │
└─────────────────────────┬───────────────────────────────────┘
│ MySQL协议
▼
┌─────────────────────────────────────────────────────────────┐
│ MariaDB/MySQL (3306) │
│ 数据存储 │
└─────────────────────────────────────────────────────────────┘
9.5 WordPress站点搭建
环境准备
# 安装必要软件
yum install -y nginx php php-fpm php-mysql mariadb-server
# 启动服务
systemctl start nginx php-fpm mariadb
systemctl enable nginx php-fpm mariadb
数据库配置
-- 创建WordPress数据库
CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4;
-- 创建WordPress用户
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'wppassword';
-- 授权
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
下载WordPress
cd /usr/share/nginx
wget https://wordpress.org/latest.tar.gz
tar -zxvf latest.tar.gz
chown -R nginx:nginx wordpress
Nginx配置
server {
listen 80;
server_name www.example.com;
root /usr/share/nginx/wordpress;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
9.6 伪静态配置
伪静态原理
伪静态是将动态URL转换为静态URL形式,实际仍由动态程序处理。
动态URL: /article.php?id=123
伪静态URL: /article/123.html
WordPress伪静态
location / {
try_files $uri $uri/ /index.php?$args;
}
# 重写规则
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
Discuz伪静态
location / {
rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last;
rewrite ^([^\.]*)/article-([0-9]+)-([0-9]+)\.html$ $1/portal.php?mod=view&aid=$2&page=$3 last;
rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last;
rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last;
}
十、CDN内容分发网络
10.1 CDN概述
CDN(Content Delivery Network,内容分发网络)是分布在各地的边缘服务器网络,将内容缓存到离用户最近的节点,加速内容访问。
CDN工作原理
┌─────────────────┐
│ 源站服务器 │
│ (原始内容存储) │
└────────┬────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ CDN节点(北京) │ │ CDN节点(上海) │ │ CDN节点(广州) │
│ 缓存内容副本 │ │ 缓存内容副本 │ │ 缓存内容副本 │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 北京用户 │ │ 上海用户 │ │ 广州用户 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
CDN访问流程
1. 用户请求域名
2. DNS解析到最近的CDN节点IP
3. CDN节点检查是否有缓存
4. 有缓存:直接返回内容
5. 无缓存:回源站获取内容,缓存后返回
10.2 CDN配置
阿里云CDN配置步骤
1. 开通CDN服务
2. 添加加速域名
3. 配置源站信息
4. 配置CNAME解析
5. 等待CDN生效
CNAME配置示例
# DNS解析配置
www.example.com CNAME www.example.com.w.kunlunsl.com
10.3 CDN检测方法
| 方法 |
说明 |
| 多地Ping |
使用多地Ping工具检测IP是否一致 |
| nslookup |
查看解析结果是否为CDN厂商IP |
| IP归属查询 |
查询IP归属是否为CDN厂商 |
CDN检测工具
10.4 绕过CDN获取真实IP
常见绕过方法
| 方法 |
说明 |
| 子域名查询 |
子域名可能未配置CDN |
| 邮件服务头 |
邮件服务器可能暴露真实IP |
| 国外访问 |
部分CDN未覆盖国外节点 |
| 历史DNS记录 |
查询历史解析记录 |
| SSL证书查询 |
证书可能包含真实IP |
| 网络空间搜索 |
Shodan、Fofa等搜索 |
子域名查询
# 使用工具查询子域名
subfinder -d example.com
sublist3r -d example.com
邮件头分析
查看邮件头中的Received字段,可能包含真实服务器IP
国外访问测试
# 使用国外代理或VPN访问
curl -x http://国外代理:端口 http://example.com
十一、Java项目部署
11.1 Java环境安装
JDK安装
# CentOS安装OpenJDK
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
# 验证安装
java -version
javac -version
配置环境变量
# 编辑配置文件
vim /etc/profile
# 添加环境变量
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
export PATH=$JAVA_HOME/bin:$PATH
# 使配置生效
source /etc/profile
11.2 Tomcat安装
下载安装
# 下载Tomcat
wget https://downloads.apache.org/tomcat/tomcat-9/v9.0.80/bin/apache-tomcat-9.0.80.tar.gz
# 解压
tar -zxvf apache-tomcat-9.0.80.tar.gz -C /usr/local/
# 创建软链接
ln -s /usr/local/apache-tomcat-9.0.80 /usr/local/tomcat
Tomcat目录结构
| 目录/文件 |
说明 |
bin/ |
启动和关闭脚本 |
conf/ |
配置文件 |
lib/ |
库文件 |
logs/ |
日志文件 |
temp/ |
临时文件 |
webapps/ |
Web应用目录 |
work/ |
工作目录(编译后的文件) |
Tomcat基本操作
# 启动
/usr/local/tomcat/bin/startup.sh
# 停止
/usr/local/tomcat/bin/shutdown.sh
# 查看日志
tail -f /usr/local/tomcat/logs/catalina.out
11.3 WAR包部署
WAR包说明
WAR(Web Application Archive)是Java Web应用的打包格式,需要部署到Servlet容器(如Tomcat)中运行。
WAR包结构
myapp.war
├── META-INF/
│ └── MANIFEST.MF
├── WEB-INF/
│ ├── web.xml # Web应用配置
│ ├── classes/ # 编译后的class文件
│ └── lib/ # 依赖的jar包
├── static/ # 静态资源
└── index.jsp # 首页
部署步骤
# 将WAR包复制到webapps目录
cp myapp.war /usr/local/tomcat/webapps/
# Tomcat自动解压部署
# 访问地址: http://localhost:8080/myapp/
11.4 JAR包部署
JAR包说明
JAR(Java Archive)是Java应用的打包格式,Spring Boot项目通常打包为可执行JAR,内置Tomcat容器。
JAR包结构(Spring Boot)
myapp.jar
├── META-INF/
│ └── MANIFEST.MF # Main-Class指定启动类
├── BOOT-INF/
│ ├── classes/ # 应用代码和配置
│ └── lib/ # 依赖包
└── org/ # Spring Boot启动器
部署运行
# 前台运行
java -jar myapp.jar
# 后台运行
nohup java -jar myapp.jar > app.log 2>&1 &
# 指定端口运行
java -jar myapp.jar --server.port=8081
# 指定JVM参数
java -Xms512m -Xmx1024m -jar myapp.jar
Systemd服务配置
# 创建服务文件
vim /etc/systemd/system/myapp.service
[Unit]
Description=My Java Application
After=syslog.target network.target
[Service]
Type=simple
User=root
ExecStart=/usr/bin/java -jar /opt/myapp.jar
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
# 启动服务
systemctl daemon-reload
systemctl start myapp
systemctl enable myapp
11.5 Nginx反向代理Tomcat
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
11.6 WAR包与JAR包对比
| 对比项 |
WAR包 |
JAR包 |
| 部署方式 |
需外部Tomcat |
内置Tomcat |
| 启动方式 |
Tomcat启动 |
java -jar启动 |
| 配置修改 |
需重启Tomcat |
需重启应用 |
| 适用场景 |
传统Java Web项目 |
Spring Boot项目 |
| 灵活性 |
较低 |
较高 |
附录:常用配置速查
Nginx常用配置模板
静态网站配置
server {
listen 80;
server_name www.example.com;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
PHP网站配置
server {
listen 80;
server_name www.example.com;
root /usr/share/nginx/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
反向代理配置
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
负载均衡配置
upstream backend {
server 192.168.1.101:8080 weight=3;
server 192.168.1.102:8080 weight=2;
server 192.168.1.103:8080 backup;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://backend;
}
}
HTTPS配置
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
root /usr/share/nginx/html;
}
}
server {
listen 80;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}
常用端口速查
| 端口 |
服务 |
说明 |
| 80 |
HTTP |
Web服务 |
| 443 |
HTTPS |
安全Web服务 |
| 8080 |
HTTP备用 |
常用备用端口 |
| 3306 |
MySQL |
MySQL数据库 |
| 9000 |
PHP-FPM |
PHP FastCGI |
| 8009 |
Tomcat AJP |
Tomcat AJP协议 |
| 8080 |
Tomcat HTTP |
Tomcat默认HTTP端口 |
常用命令速查
Nginx命令
nginx # 启动
nginx -s stop # 停止
nginx -s reload # 重载配置
nginx -t # 测试配置
nginx -v # 查看版本
MySQL命令
mysql -u root -p # 登录MySQL
mysqldump -u root -p db > db.sql # 备份数据库
mysql -u root -p db < db.sql # 恢复数据库
Tomcat命令
./startup.sh # 启动
./shutdown.sh # 停止
./catalina.sh run # 前台运行
Java命令
java -jar app.jar # 运行JAR包
java -version # 查看版本
javac # 编译Java文件