Joyber 发布的文章

user  www www;
worker_processes auto;
error_log  /www/wwwlogs/nginx_error.log  crit;
pid        /www/server/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;

events
    {
        use epoll;
        worker_connections 65535;
        multi_accept on;
    }

http
    {
        include       mime.types;

        include proxy.conf;
        # proxy.conf匹配如下:
proxy_temp_path /www/server/nginx/proxy_temp_dir;
proxy_cache_path /www/server/nginx/proxy_cache_dir levels=1:2 keys_zone=cache_one:20m inactive=1d max_size=5g;
client_body_buffer_size 25m;
proxy_connect_timeout 60;
proxy_read_timeout 60;
proxy_send_timeout 60;
proxy_buffer_size 32k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_cache cache_one;

        default_type  application/octet-stream;

        server_names_hash_bucket_size 512;
        client_header_buffer_size 32k;
        large_client_header_buffers 4 32k;
        client_max_body_size 50m;

        sendfile   on;
        tcp_nopush on;
        keepalive_timeout 60;
        tcp_nodelay on;

        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        fastcgi_buffer_size 64k;
        fastcgi_buffers 4 64k;
        fastcgi_busy_buffers_size 128k;
        fastcgi_temp_file_write_size 256k;
        fastcgi_intercept_errors on;

        gzip on;
        gzip_min_length 1k;
        gzip_buffers     4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 2;
        gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
        gzip_vary on;
        gzip_proxied   expired no-cache no-store private auth;
        gzip_disable   "MSIE [1-6]\.";
        # 限流匹配,注意使用IP限流时,要使用real_ip模块获取用户真实IP地址,以免CDN被整体限流
        limit_conn_zone $binary_remote_addr zone=perip:10m;
        limit_conn_zone $server_name zone=perserver:10m;
  
        server_tokens off;
        access_log off;

server
    {
...
# 限流匹配
    limit_conn perserver 300;
    limit_conn perip 25;
    limit_rate 512k;

    ssl_certificate    /www/fullchain.pem;
    ssl_certificate_key    /www/privkey.pem;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    add_header Strict-Transport-Security "max-age=31536000";
...
}
}

event段:
这段配置是用来优化 Nginx 的性能和并发处理能力的。它位于 events 块中,主要用于控制 Nginx 处理连接的方式。下面是各项配置的作用:

use epoll;: 指定 Nginx 使用 epoll 作为事件处理机制。这是一种高效的 I/O 多路复用技术,适用于 Linux 系统,可以处理大量的并发连接。相比于其他事件处理机制(如 select 和 poll),epoll 在处理大量并发连接时性能更好。

worker_connections 65535;: 设置每个 Nginx 工作进程可以同时处理的最大连接数。这个值决定了单个工作进程的最大并发连接数。设置为 65535 表示每个工作进程可以处理最多 65535 个连接。这对于高流量网站或需要处理大量并发请求的场景很有用。

multi_accept on;: 允许 Nginx 在每个事件循环中接受多个连接。默认情况下,Nginx 每次事件循环只接受一个新连接。启用 multi_accept 可以让 Nginx 更高效地处理新连接,尤其是在高并发的环境中,这有助于减少延迟和提高处理能力。

总的来说,这些设置旨在提高 Nginx 的并发处理能力和性能,特别是在高负载和高并发的环境中。

http 段:
这些配置项用于优化 Nginx 的性能,特别是在处理文件传输和保持长连接方面:

sendfile on;: 启用 sendfile 系统调用,允许 Nginx 直接在文件系统中将文件传输到网络套接字,而无需将数据从内核空间拷贝到用户空间。这可以提高文件传输的效率,减少 CPU 使用率。

tcp_nopush on;: 在使用 sendfile 时,启用 TCP_NOPUSH 标志,直到整个文件数据准备好再发送。这有助于减少小数据包的发送,优化大文件的传输性能。

keepalive_timeout 60;: 设置保持连接的超时时间为 60 秒。这意味着在客户端与服务器之间保持持久连接的时间。如果客户端在 60 秒内没有发送新请求,连接将被关闭。这有助于减少建立和拆除连接的开销,同时避免长时间保持闲置连接。

tcp_nodelay on;: 启用 TCP_NODELAY 标志,禁用 Nagle 算法。Nagle 算法会延迟小的数据包的发送以减少网络拥塞,但启用 TCP_NODELAY 可以确保数据包立即发送,从而减少延迟,适合需要快速响应的应用场景。

这些设置有助于提高文件传输的效率、减少延迟,并优化长期连接的性能。

真实IP获取:real_ip模块
https://blog.qqvbc.com/default/1101.html

nginx使用limit_req模块
nginx使用limit_req模块时,如果使用CDN的话,能按真实的用户IP来限流吗?如果使用的是CDN的IP,从而把CDN直接限流了,影响正常访问:

http_limit_req 模块文档:
https://nginx.org/en/docs/http/ngx_http_limit_req_module.html

limit_req 模块配置实例:

http {

        limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;

server {
...
    limit_conn perserver 300;
    limit_conn perip 25;
    limit_rate 512k;

...
}

}

在使用 Nginx 的 limit_req 模块时,如果你使用了 CDN,默认情况下限流是基于 CDN 的 IP 地址的,而不是真实用户的 IP 地址。这是因为 CDN 会将请求转发到你的 Nginx 服务器时,源 IP 地址通常是 CDN 的 IP。

要按真实用户 IP 限流,你需要配置 Nginx 以正确识别用户的真实 IP 地址。通常,这可以通过设置 real_ip 模块来实现。你需要确保 Nginx 从 CDN 请求头(如 X-Forwarded-For 或 X-Real-IP)中提取真实用户 IP 地址,并将其用于限流。

http_realip 模块文档:
https://nginx.org/en/docs/http/ngx_http_realip_module.html
确保nginx有这个模块,查看命令(包含有 --with-http_realip_module 字样):

nginx -V

nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.1.1g  21 Apr 2020
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/www/server/nginx --add-module=srclib/ngx_devel_kit --add-module=srclib/lua_nginx_module --add-module=srclib/ngx_cache_purge --add-module=srclib/nginx-sticky-module --with-openssl=srclib/openssl --with-pcre=srclib/pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-http_dav_module --add-module=srclib/nginx-dav-ext-module

示例配置

set_real_ip_from  192.168.1.0/24;
set_real_ip_from  192.168.2.1;
set_real_ip_from  2001:0db8::/32;
real_ip_header    X-Forwarded-For;
real_ip_recursive on;

匹配项说明:

  • set_real_ip_from 指定了哪些 IP 地址可以作为信任的代理来源,通常可以设置为 CDN 提供的 IP 范围。 0.0.0.0/0; # 允许所有 IP 的 CDN 代理
  • real_ip_header 设置了使用哪个请求头来获取真实 IP 地址。
  • real_ip_recursive 使 Nginx 从请求头链中递归提取真实 IP 地址。

嵌入变量
$realip_remote_addr
保留原始客户端地址 (1.9.7)
$realip_remote_port
保留原始客户端端口 (1.11.0)

常见配置实例:

http {
    # 信任的代理 IP 范围
    set_real_ip_from 192.168.0.0/24;  # 负载均衡器或 CDN 的 IP 范围
    set_real_ip_from 10.0.0.0/8;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    server {
        location / {
            # 其他配置
        }
    }
}

当使用 real_ip 模块时,$remote_addr 变量将反映真实的客户端 IP 地址,而不是中间代理或负载均衡器的 IP 地址。这是因为 real_ip 模块会根据你配置的规则修改 $remote_addr 变量的值。

**如何工作**
没有代理的情况: $remote_addr 直接表示客户端的 IP 地址,无需 real_ip 模块的干预。

有代理或 CDN 的情况: 当你配置了 real_ip 模块并正确设置了信任的代理 IP 地址和请求头(如 X-Forwarded-For),Nginx 会从这些请求头中提取真实的客户端 IP 地址,并将其赋值给 $remote_addr。这使得 $remote_addr 始终反映真实的客户端 IP,而不是代理或负载均衡器的 IP。
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;

另一种得到真实IP的方法

  map $http_x_forwarded_for  $clientRealIp {
                ""      $remote_addr;
                ~^(?P<firstAddr>[0-9\.]+),?.*$  $firstAddr;
        }

$clientRealIp就得到了真实IP

进制和整型
整型值可以使用十进制,十六进制,八进制或二进制表示,前面可以加上可选的符号(- 或者 +)。

注意:要使用八进制表达,数字前必须加上 0。要使用十六进制表达,数字前必须加上 0x。要使用二进制表达,数字前必须加上 0b。

<?php
$a = 1234; // 十进制数
$b = -123; // 负数
$c = 0123; // 八进制数 (等于十进制 83)
$d = 0x1A; // 十六进制数 (等于十进制 26)
?>

整数溢出
如果给定的一个数超出了 integer 的范围,将会被解释为 float。同样如果执行的运算结果超出了 integer 范围,也会返回 float。
对于32位的操作系统,最大的整型是2147483647,即2的31次方,最小为-2的31次方。本次实验环境:PHP 7.2,Ubuntu 14.04。

<?php

$a = 123445566;
$b = 9223372036854775807;
$c = 9223372036854775808;
$d = 50000000000000 * 1000000;

var_dump($a);
var_dump($b);
var_dump($c);
var_dump($d);

执行得到结果为:

int(123445566)
int(9223372036854775807)
float(9.2233720368548E+18)
float(5.0E+19)

ubuntu版本是22.04.3 安装的 mysql-server 是 mysql 8.0

默认账号密码:

sudo cat /etc/mysql/debian.cnf

[client]
host     = localhost
user     = debian-sys-maint
password = xezrqqkk9Dely8hv
socket   = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
host     = localhost
user     = debian-sys-maint
password = xezrqqkk9Dely8hv
socket   = /var/run/mysqld/mysqld.sock

连接数据库,并修改密码(账户密码替换成你自己的):

mysql -u debian-sys-maint -p xezrqqkk9Dely8hv
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';FLUSH PRIVILEGES;

报错问题:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

修改mysql配置文件,原本是空的只有[mysql]一行,增加如下配置,重启mysql服务

sudo vim /etc/mysql/conf.d/mysql.cnf

[mysql]

[client]
socket=/var/run/mysqld/mysqld.sock

[mysqld]
socket=/var/run/mysqld/mysqld.sock