晓铧.

Do more of what makes you happy.

第七周作业

1.总结I/O模型

1. 阻塞 I/O(Blocking I/O)

核心特点

应用程序发起 I/O 操作(如 read/write)后,进程会被挂起,直到内核完成数据准备或传输,才恢复执行。

  • 阻塞点:数据从内核空间拷贝到用户空间的过程(或等待数据到达内核缓冲区)。

优缺点

  • 优点:编程简单(无需处理复杂的非阻塞或事件循环)。
  • 缺点:进程在等待期间无法执行其他任务,并发能力差(单线程仅能处理一个 I/O)。

适用场景

短连接、低并发场景(如简单的命令行工具 cattelnet)。

2. 非阻塞 I/O(Non-blocking I/O)

核心特点

通过设置文件描述符为非阻塞模式(如 fcntl(fd, F_SETFL, O_NONBLOCK)),应用程序发起 I/O 操作后,内核立即返回(不会阻塞进程),但需主动轮询检查数据是否就绪。

优缺点

  • 优点:进程不会被长时间阻塞,可执行其他任务。
  • 缺点:轮询会浪费 CPU 资源(忙等待),尤其在数据未就绪时频繁空转。

适用场景

需要快速响应且 I/O 操作耗时极短的场景(如实时状态查询),但实际中很少单独使用。

3. I/O 多路复用(I/O Multiplexing)

核心特点

通过一个或多个系统调用(select/poll/epoll),同时监控多个文件描述符的状态(可读/可写/异常),当任意一个或多个描述符就绪时,内核通知应用程序处理。

关键实现

  • select:内核遍历所有被监控的描述符,时间复杂度 O(n),受限于 FD_SETSIZE(默认 1024)。
  • poll:基于链表存储描述符,无数量限制,但仍需遍历检查(O(n))。
  • epoll(Linux 特有):基于事件驱动,使用红黑树管理描述符,回调机制通知就绪事件,时间复杂度 O(1)(仅处理就绪的描述符),支持水平触发(LT,默认)和边缘触发(ET,更高效)。

优缺点

  • 优点:单线程/进程可同时处理大量 I/O 连接(高并发),避免了阻塞和轮询的浪费。
  • 缺点:编程复杂度较高(需处理事件循环);select/poll 性能在高并发下下降明显(epoll 更优)。

适用场景

高并发网络服务(如 Web 服务器 Nginx、Redis)、需要同时处理多个连接的场景。

4. 信号驱动 I/O(Signal-Driven I/O)

核心特点

应用程序通过 sigaction 注册信号处理函数(如 SIGIO),当内核完成数据准备(数据到达内核缓冲区)时,主动向进程发送信号,通知其进行 I/O 操作。

优缺点

  • 优点:无需轮询,内核主动通知,减少 CPU 空转。
  • 缺点:信号处理存在并发问题(如信号中断系统调用),编程复杂度高;实际应用中较少使用(被 epoll 等替代)。

适用场景

极少需要主动触发且对延迟敏感的场景(如实时信号处理)。

5. 异步 I/O(Asynchronous I/O, AIO)

核心特点

应用程序发起 I/O 操作后,完全不参与数据传输过程,内核在完成数据读写(从磁盘/网络到用户空间)后,通过回调函数或信号通知应用程序。整个过程应用程序可执行其他任务。

关键区别

与 I/O 多路复用的本质差异:

  • I/O 多路复用:应用程序需主动查询就绪的描述符(同步等待内核通知)。

  • 异步 I/O:内核完成数据拷贝后通知应用程序(真正异步,应用无需主动干预)。

    模型 阻塞性 同步性 核心机制 典型场景 代表接口/技术
    阻塞 I/O 阻塞 同步 进程睡眠等待内核完成 短连接、低并发服务 read/write(默认)
    非阻塞 I/O 非阻塞 同步 轮询检查内核状态 实时状态查询 fcntl(O_NONBLOCK) + 轮询
    I/O 多路复用 阻塞(单线程) 同步 内核监控多描述符就绪 高并发网络服务 select/poll/epoll
    信号驱动 I/O 非阻塞 同步 内核发送信号通知就绪 极少使用 sigaction(SIGIO)
    异步 I/O 非阻塞 异步 内核完成后通知应用 高吞吐量磁盘 I/O libaio/POSIX AIO

2.完成nginx编译安装脚本

1. 安装编译依赖

sudo apt update
sudo apt install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev libgd-dev libxml2 libxml2-dev uuid-dev

2. 下载 Nginx 源码

cd /data/soft/nginx
wget https://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0

3. 配置编译选项

./configure \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/run/nginx.lock \
    --http-client-body-temp-path=/var/cache/nginx/client_temp \
    --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
    --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
    --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
    --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
    --user=nginx \
    --group=nginx \
    --with-http_ssl_module \
    --with-http_realip_module \
    --with-http_addition_module \
    --with-http_sub_module \
    --with-http_dav_module \
    --with-http_flv_module \
    --with-http_mp4_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_random_index_module \
    --with-http_secure_link_module \
    --with-http_stub_status_module \
    --with-http_auth_request_module \
    --with-http_xslt_module=dynamic \
    --with-http_image_filter_module=dynamic \
    --with-http_geoip_module=dynamic \
    --with-threads \
    --with-stream \
    --with-stream_ssl_module \
    --with-stream_ssl_preread_module \
    --with-stream_realip_module \
    --with-stream_geoip_module=dynamic \
    --with-http_slice_module \
    --with-mail \
    --with-mail_ssl_module \
    --with-compat \
    --with-file-aio \
    --with-http_v2_module

4. 编译和安装

make -j $(nproc)
sudo make install

5. 创建 Nginx 用户

sudo useradd -r -s /bin/false nginx

6. 创建缓存目录

sudo mkdir -p /var/cache/nginx/client_temp
sudo chown -R nginx:nginx /var/cache/nginx

7. 创建 systemd 服务文件

sudo vim /etc/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

8. 启动 Nginx 服务

sudo systemctl daemon-reload
sudo systemctl enable nginx
sudo systemctl start nginx

9. 验证安装

sudo systemctl status nginx
curl http://localhost

3.完成nginx平滑升级,总结步骤

1. 备份现有配置与数据

sudo cp -r /etc/nginx /etc/nginx_backup
sudo cp -r /var/www/html /var/www/html_backup

2. 查看当前 Nginx 版本与编译参数

nginx -V 

3. 下载新版本 Nginx 源码

cd /tmp
wget https://nginx.org/download/nginx-1.26.0.tar.gz  # 替换为最新版本
tar -zxvf nginx-1.26.0.tar.gz
cd nginx-1.26.0

4. 配置编译选项(保持与旧版本一致)

./configure $(nginx -V 2>&1 | grep 'configure arguments:' | sed 's/configure arguments: //')
  • 关键点:复用旧版本的所有编译参数(如--with-http_ssl_module)。

5. 编译新版本(不安装)

make -j $(nproc)  # 不执行make install!

6. 验证新版本二进制文件

sudo cp objs/nginx /usr/sbin/nginx.new
sudo nginx.new -t  # 测试配置文件兼容性

7. 执行平滑升级

# 1. 发送USR2信号给旧进程
sudo kill -USR2 $(cat /var/run/nginx.pid)
# 2. 确认新旧进程共存
ps -ef | grep nginx  # 应有两个master进程
# 3. 验证新版本运行正常后,发送WINCH信号给旧进程
sudo kill -WINCH $(cat /var/run/nginx.pid.oldbin)

8. 完成升级(确认无误后)

# 1. 关闭旧进程
sudo kill -QUIT $(cat /var/run/nginx.pid.oldbin)
# 2. 验证版本
nginx -v

9. 更新 systemd 服务文件(可选)

若旧版本未使用 systemd 管理,需创建服务文件:

sudo systemctl edit nginx  # 添加或修改配置

4.总结nginx核心配置,并实现nginx多虚拟主机

一、Nginx 核心配置文件结构

Nginx 主配置文件通常位于/etc/nginx/nginx.conf,核心模块包括:

1. 全局块

user www-data;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
  • 关键指令user(工作进程用户)、worker_processes(工作进程数)。

2. events 块

events {
    worker_connections 1024;
    multi_accept on;
}
  • 关键指令worker_connections(每个进程最大连接数)。

3. 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" "$http_x_forwarded_for"';
    
    access_log  /var/log/nginx/access.log  main;
    
    sendfile        on;
    keepalive_timeout 65;
    
    # 虚拟主机配置(多个server块)
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
  • 关键指令sendfile(高效文件传输)、keepalive_timeout(长连接超时)。

二、多虚拟主机配置实现

虚拟主机配置通过server块实现,可基于IP、端口、域名区分。

1. 基于域名的虚拟主机(最常用)

步骤 1:创建网站目录

sudo mkdir -p /var/www/hua1.com/html
sudo mkdir -p /var/www/hua2.com/html
sudo chown -R www-data:www-data /var/www

步骤 2:配置虚拟主机文件

sudo vim /etc/nginx/sites-available/hua1.com

nginx

server {
    listen 80;
    server_name hua1.com www.hua1.com;  # 域名

    root /var/www/hua1.com/html;  # 网站根目录
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /var/www/html;
    }
}

步骤 3:复制配置并修改为第二个网站

sudo cp /etc/nginx/sites-available/hua1.com /etc/nginx/sites-available/hua2.com
sudo vim /etc/nginx/sites-available/hua2.com

步骤 4:激活配置

sudo ln -s /etc/nginx/sites-available/hua1.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/hua2.com /etc/nginx/sites-enabled/

步骤 5:测试并重启 Nginx

sudo nginx -t
sudo systemctl restart nginx

2. 基于端口的虚拟主机

server {
    listen 8080;  # 非标准端口
    server_name localhost;

    root /var/www/port8080/html;
    # 其他配置同上
}

3. 基于 IP 的虚拟主机(需多 IP)

server {
    listen 10.0.0.13:80;  # 特定IP
    server_name hua1.com;
    # 其他配置同上
}

server {
    listen 10.0.0.16:80;  # 另一个IP
    server_name hua2.com;
    # 其他配置同上
}

三、验证配置

  1. 检查语法

    sudo nginx -t
    
  2. 测试域名解析

    curl http://site1.com
    curl http://site2.com
    

5.根据课程演示,完成nginx日志格式定制

1. 编辑 Nginx 主配置文件

sudo vim /etc/nginx/nginx.conf

2. 在http块中定义自定义日志格式

http块内添加log_format指令,例如:

http {
    # 原有配置...
    
    # 自定义日志格式(示例:包含IP、时间、请求、状态码、响应时间等)
    log_format custom '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" '
                      '$request_time $upstream_response_time';
    
    # 访问日志位置
    access_log /var/log/nginx/access.log custom;
    
    # 其他配置...
}

3. 为特定虚拟主机定制日志

若需要为某个网站单独设置日志格式,可在server块中覆盖主配置:

server {
    listen 80;
    server_name example.com;
    
    # 单独的日志格式和路径
    access_log /var/log/nginx/example_access.log custom;
    
    # 其他配置...
}

4. JSON 格式日志(高级)

适合与 ELK Stack 等日志分析系统集成:

log_format json_log '{ "timestamp": "$time_iso8601", '
                    '"client_ip": "$remote_addr", '
                    '"method": "$request_method", '
                    '"uri": "$request_uri", '
                    '"status": $status, '
                    '"bytes": $body_bytes_sent, '
                    '"referer": "$http_referer", '
                    '"agent": "$http_user_agent", '
                    '"request_time": "$request_time" }';

access_log /var/log/nginx/json_access.log json_log;

5. 测试配置并重启 Nginx

# 测试配置语法
sudo nginx -t

# 重启Nginx
sudo systemctl restart nginx

6. 验证日志格式

查看日志文件确认格式是否正确:

tail -f /var/log/nginx/access.log

7. 日志分割(避免日志过大)

使用logrotate自动分割日志:

sudo vim /etc/logrotate.d/nginx

添加以下内容:

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

6.完成基于Nginx和Python的动态站点安装配置

1. 安装依赖环境

# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装Nginx
sudo apt install nginx -y

# 安装Python3和虚拟环境
sudo apt install python3 python3-pip python3-venv -y

2. 创建 Python 应用(以 Flask 为例)

# 创建项目目录
mkdir -p /var/www/myapp && cd /var/www/myapp

# 创建虚拟环境并激活
python3 -m venv venv
source venv/bin/activate

# 安装Flask
pip install flask gunicorn

# 创建示例应用
cat > app.py << EOF
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello, World! This is a Flask app behind Nginx."

@app.route('/api/data')
def data():
    return {"message": "Dynamic data from Python backend"}

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
EOF

3. 配置 Gunicorn 作为 WSGI 服务器

# 测试Gunicorn是否能正确启动应用
gunicorn --bind 0.0.0.0:5000 app:app

# 按Ctrl+C停止测试

# 创建systemd服务文件
sudo nano /etc/systemd/system/myapp.service

添加以下内容:

[Unit]
Description=Gunicorn instance to serve myapp
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/myapp
Environment="PATH=/var/www/myapp/venv/bin"
ExecStart=/var/www/myapp/venv/bin/gunicorn --workers 3 --bind unix:myapp.sock -m 007 app:app

[Install]
WantedBy=multi-user.target

4. 启动并启用 Gunicorn 服务

# 重载systemd管理器配置
sudo systemctl daemon-reload

# 启动服务
sudo systemctl start myapp

# 设置开机自启
sudo systemctl enable myapp

# 检查服务状态
sudo systemctl status myapp

5. 配置 Nginx 反向代理

# 创建Nginx配置文件
sudo nano /etc/nginx/sites-available/myapp

# 添加以下内容
server {
    listen 80;
    server_name your_domain_or_ip;  # 替换为你的域名或IP

    location / {
        include proxy_params;
        proxy_pass http://unix:/var/www/myapp/myapp.sock;
    }
}

# 创建软链接启用配置
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/

# 测试配置并重启Nginx
sudo nginx -t
sudo systemctl restart nginx

6. 验证部署

# 检查Nginx服务状态
sudo systemctl status nginx

# 访问网站
curl http://your_domain_or_ip
curl http://your_domain_or_ip/api/data

7. 关键配置说明

  1. Gunicorn 参数
    • --workers 3:启动 3 个工作进程
    • --bind unix:myapp.sock:使用 Unix 套接字通信(更安全高效)
  2. Nginx 反向代理
    • proxy_pass:转发请求到 Gunicorn 套接字
    • proxy_params:包含常用代理参数(位于/etc/nginx/proxy_params

8. 安全强化

  1. 配置防火墙

    sudo ufw allow 'Nginx Full'
    sudo ufw enable
    
  2. 启用 HTTPS(使用 Certbot):

    sudo apt install certbot python3-certbot-nginx -y
    sudo certbot --nginx -d your_domain
    

9. 日志配置

在 Nginx 配置中添加自定义日志:

server {
    # 其他配置...
    
    access_log /var/log/nginx/myapp_access.log;
    error_log /var/log/nginx/myapp_error.log;
}

10. 应用更新流程

# 1. 停止服务
sudo systemctl stop myapp

# 2. 更新代码
cd /var/www/myapp
git pull  # 如果使用版本控制

# 3. 重启服务
sudo systemctl start myapp
posted @ 2025-06-09 23:48  晓铧  阅读(30)  评论(0)    收藏  举报
访问统计