Nginx进阶-常见配置

news2024/12/23 10:33:48

一、nginx Proxy 反向代理

1、代理原理

反向代理产生的背景:

在计算机世界里,由于单个服务器的处理客户端(用户)请求能力有一个极限,当用户的接入请求蜂拥而入时,会造成服务器忙不过来的局面,可以使用多个服务器来共同分担成千上万的用户请求,这些服务器提供相同的服务,对于用户来说,根本感觉不到任何差别。

反向代理服务的实现:

需要有一个负载均衡设备(即反向代理服务器)来分发用户请求,将用户请求分发到后端真正提供服务的服务器上。服务器返回自己的服务到负载均衡设备。负载均衡设备将服务器的服务返回用户。

在反向代理中,Nginx代表服务器端,接收和处理客户端的请求。与正向代理(如代理服务器)不同的是,反向代理是位于服务器端的代理服务器。客户端对其发送请求,并不知道实际处理请求的是后端服务器。

Nginx Proxy反向代理的主要优点包括:

  1. 负载均衡:Nginx可以将请求平均分发给多个后端服务器,以实现负载均衡,提高系统的性能和可扩展性。

  2. 高可用性:当某个后端服务器发生故障或不可用时,Nginx可以自动将请求转发给其他可用的后端服务器,确保服务的高可用性。

  3. 缓存功能:Nginx可以缓存静态资源,如图片、CSS和JavaScript文件等,减轻后端服务器的压力,加快访问速度。

  4. 安全性:Nginx可以作为反向代理服务器,过滤和防护恶意请求,提高系统的安全性。

2、正/反向代理的区别

正向代理

正向代理的过程隐藏了真实的请求客户端,服务器不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替请求。我们常说的代理也就是正向代理,正向代理代理的是请求方,也就是客户端;比如我们要访问youtube,可是不能访问,只能先安装个FQ软件代你去访问,通过FQ软件才能访问,FQ软件就叫作正向代理。

正向代理的作用
  • 为在防火墙内的局域网客户端提供访问Internet的途径
  • 可以使用缓冲特性减少网络使用率
  • 访问受地理位置限制的网络
  • 使用代理后会隐藏真实的IP地址

反向代理

反向代理:(reverse proxy),指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式。客户端不直接与后端服务器进行通信,而是与反向代理服务器进行通信,隐藏了后端服务器的 IP 地址

反向代理的过程隐藏了真实的服务器,客户不知道真正提供服务的人是谁,客户端请求的服务都被代理服务器处理。反向代理代理的是响应方,也就是服务端;我们请求www.baidu.com时这www.baidu.com就是反向代理服务器,真实提供服务的服务器有很多台,反向代理服务器会把我们的请求分转发到真实提供服务的各台服务器。Nginx就是性能非常好的反向代理服务器,用来做负载均衡。

访问www.baidu.com是反向代理的过程

两者的区别在于代理的对象不一样:正向代理中代理的对象是客户端。反向代理中代理的对象是服务端。

 反向代理可实现的功能

反向代理的主要作用是提供负载均衡和高可用性。

  • 负载均衡:Nginx可以将传入的请求分发给多个后端服务器,以平衡服务器的负载,提高系统性能和可靠性。
  • 缓存功能:Nginx可以缓存静态文件或动态页面,减轻服务器的负载,提高响应速度。
  • 动静分离:将动态生成的内容(如 PHP、Python、Node.js 等)和静态资源(如 HTML、CSS、JavaScript、图片、视频等)分别存放在不同的服务器或路径上。
  • 多站点代理:Nginx可以代理多个域名或虚拟主机,将不同的请求转发到不同的后端服务器上,实现多个站点的共享端口。

反向代理的可用模块

ngx_http_proxy_module: #将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module #用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组
ngx_stream_proxy_module:#将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module:#将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module: #将客户端对Python的请求以uwsgi协议转发至指定服务器处理

3、nginx Proxy 配置

1、代理模块

ngx_http_proxy_module

2、启用 nginx proxy 代理

环境两台nginx真实服务器

a、nginx-1 应用服务器启动
nginx-1的ip:192.168.175.130(作为应用服务器)
已经编译安装好,检查nginx是否启动是否可以访问
b、nginx-2 代理服务器配置
nginx-2的ip:192.168.175.128
编辑nginx的子配置文件: /etc/nginx/conf.d/default.conf 
[root@nginx-server ~]# vim /etc/nginx/conf.d/default.conf
server {
    server {
    listen       80;
    server_name  localhost;
    location / {
        proxy_pass http://192.168.175.130:80;
        proxy_redirect default;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout 30;  
        proxy_send_timeout 60;
        proxy_read_timeout 60;
    }
}
为了不影响访问可以先把主配置文件里的server块注释掉
重新加载nginx配置文件
[root@nginx-server ~]# nginx -s reload
c、nginx proxy 具体配置详解
proxy_pass :指定后端服务器的地址,可以是ip也可以是域名和url地址
proxy_set_header:设置要传递给后端服务器的HTTP请求头。
proxy_set_header X-Real-IP $remote_addr
#只记录连接服务器的上一个ip地址信息。(一般为代理服务器的ip地址)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
#$proxy_add_x_forwarded_for会将客户端的IP地址添加到X-Forwarded-For请求头中,然后传递给后端服务器。X-Forwarded-For的请求头值为客户端的IP地址。通过这个选项可以记录真正客户端机器的ip地址。实现了IP透传
proxy_redirect :如果真实服务器使用的是的真实IP:非默认端口。则改成IP:默认端口。
proxy_connect_timeout:指定连接到后端服务器的超时时间,即发起三次握手等候响应超时时间。
proxy_send_timeout:指定向后端服务器发送请求的超时时间,即在规定时间之内后端服务器必须传完所有的数据。
proxy_read_timeout :指定从后端服务器读取响应的超时时间。
nginx接收upstream(上游/真实) server数据超时, 默认60s, 如果连续的60s内没有收到1个字节, 连接关闭,如长连接。

注意:proxy_pass http:// 填写nginx-1实际应用服务器的地址。

使用PC客户端访问nginx-2服务器地址
浏览器中输入http://192.168.175.128 (nginx-2代理服务器的ip)
​成功访问nginx-1应用服务器页面

观察nginx-1服务器的日志

# tail -f /var/log/nginx/access.log
10.0.105.202 - - [27/Jun/2019:15:54:17 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "10.0.105.207"
10.0.105.202  代理服务器地址
10.0.105.207 客户机地址。
访问成功。 记录了客户机的IP和代理服务器的IP

二、Nginx负载均衡

1、upstream配置

upstream指令来配置反向代理的后端服务器池。 upstream 配置:写一组被代理的服务器地址,然后配置负载均衡的算法.(80,443一般在七层,upstream做七层负载)

upstream testapp { 
      server 10.0.105.199:8081;
      server 10.0.105.202:8081;
    }
 server {
        ....
        location / {         
           proxy_pass  http://testapp;  #请求转向 testapp 定义的服务器列表         
        } 

2、负载均衡算法(nginx调度策略)

upstream 负载均衡调度算法
​
1. 轮询算法(Round Robin):每个请求按时间顺序逐一分配到不同的后端服务器;(默认不用写)
2. 加权轮询算法(Weighted Round Robin):根据服务器的处理能力分配权重,按照权重的比例分发请求。
3. IP地址散列算法(IP Hash):每个请求按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器。保证来自同一ip的请求被打到固定的机器上,解决session问题。(没有实现负载均衡)
4. 哈希算法(Hash)(也叫url hash):按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器。根据请求的某一特定属性(如源IP地址或请求URL),通过哈希函数计算后得到一个固定的值,再将该值与服务器列表进行匹配,将请求分发给对应的服务器。(没有实现负载均衡)​
5. fair算法:基于请求处理时间的负载均衡算法。此种算法可依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持 fair的,如果需要使用这种调度算法,必须下载Nginx的 upstream_fair模块。实现:通过维护一个请求队列,并记录每个后端服务器的处理时间。当新的请求到达时,Fair算法会选择处理时间最短的服务器来处理该请求,并将该请求加入到该服务器的请求队列中。当服务器的处理时间相差不大时,Fair算法的效果较为明显,可以达到较好的负载均衡效果。

3、配置实例

1、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB.....

upstream myweb { 
      server 172.17.14.2:8080; 
      server 172.17.14.3:8080 backup;  #热备     
    }

2、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB....

upstream myweb { 
      server 172.17.14.2:8080; 
      server 172.17.14.3:8080;      
    }

3、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB....

upstream myweb { 
      server 172.17.14.2:8080 weight=1;
      server 172.17.14.3:8080 weight=2;
}

4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。

upstream myweb { 
      server 172.17.14.2:8080; 
      server 172.17.14.3:8080;
      ip_hash;
    }

5、nginx负载均衡配置状态参数

- down,表示当前的server暂时不参与负载均衡。
- backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
- max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。(缺点:请求处理失败后需要重新转发请求,多一次请求转发)
- fail_timeout,在经历了max_fails次失败后,暂停服务的时间单位秒。max_fails可以和fail_timeout一起使用。(缺点:请求处理失败后需要重新转发请求,多一次请求转发)
 upstream myweb { 
      server 172.17.14.2:8080 weight=2 max_fails=2 fail_timeout=2 down;
      server 172.17.14.3:8080 weight=1 max_fails=2 fail_timeout=1;    
    }

4、nginx配置7层协议

举例讲解下什么是7层协议,什么是4层协议。

(1)7层协议

OSI(Open System Interconnection)是一个开放性的通行系统互连参考模型,他是一个定义的非常好的协议规范,共包含七层协议。直接上图,这样更直观些:

好,详情不进行仔细讲解,可以自行百度!

(2)协议配置

这里我们举例,在nginx做负载均衡,负载多个服务,部分服务是需要7层的,部分服务是需要4层的,也就是说7层和4层配置在同一个配置文件中。

准备三台机器:

代理服务IP:10.0.105. --配置本地host解析域名;
后端服务器IP:nginx-a :10.0.105.199/nginx-b:10.0.105.202(yum安装)后端服务器将nginx服务启动
配置代理服务器的nginx配置文件
worker_processes  4;
​
worker_rlimit_nofile 102400;
​​
events {
    worker_connections  1024;
}
​
http {
    include       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  logs/access.log  main;
​
    sendfile        on;
    keepalive_timeout  65;
    gzip  on;
​
    upstream testweb {
    #ip_hash;
    server 10.0.105.199:80 weight=2 max_fails=2 fail_timeout=2s;
    server 10.0.105.202:80 weight=2 max_fails=2 fail_timeout=2s;
     }
    server {
        listen       80;
        server_name  www.test.com;
        charset utf-8;
        #access_log  logs/host.access.log  main;
        location / {
        proxy_pass http://testweb;
         proxy_set_header Host $host:$server_port;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
​
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
            }
    }
}

202服务器yum安装的创建新的配置文件:

[root@nginx-server ~]# cd /etc/nginx/conf.d/
[root@nginx-server conf.d]# cp default.conf test.conf
[root@nginx-server conf.d]# cat test.conf 
server {
    listen       80;
    server_name  localhost;
​
    location / {
         root   /usr/share/nginx/html;
         index  index.html index.htm;
    }
}
[root@nginx-server ~]# nginx -s reload
浏览器测试访问:
http://www.test.com/

nginx 配置后端健康检查模块

ngx_http_proxy_module VS nginx_upstream_check_module

nginx自带的针对后端节点健康检查的功能比较简单,通过默认自带的ngx_http_proxy_module 模块和ngx_http_upstream_module模块中的参数来完成,当后端节点出现故障时,自动切换到健康节点来提供访问。但是nginx不能事先知道后端节点状态是否健康,后端即使有不健康节点,负载均衡器依然会先把请求转发给该不健康节点,然后再转发给别的节点,这样就会浪费一次转发,而且自带模块无法做到预警。所以我们可以使用第三方模块 nginx_upstream_check_module模块
​
nginx_upstream_check_module模块由淘宝团队开发 淘宝自己的 tengine 上是自带了该模块的。我们使用原生Nginx,采用添加模块的方式

获取nginx_upstream_check_module模块

从github上面获取就可以了。

[root@nginx-server ~]# yum install -y unzip
​
下载模块
[root@nginx-server ~]# wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/refs/heads/master.zip
[root@nginx-server ~]# unzip -d /usr/local/ master.zip
​
安装补丁:
注意 check版本和Nginx版本要求有限制 1.12以上版本的nginx,补丁为check_1.20.1+.patch 具体参考github
​# ls nginx_upstream_check_module-master/
# -p0,是“当前路径” -p1,是“上一级路径”
[root@nginx-server ~]# cd /usr/local/nginx-1.22.1/   #进入nginx的解压目录中
[root@nginx-server nginx-1.22.1]# yum install -y patch
[root@nginx-server nginx-1.22.1]# patch -p1 < ../nginx_upstream_check_module-master/check_1.20.1+.patch
[root@nginx-server nginx-1.22.1]# nginx -V #查看nginx配置路径
[root@nginx-server nginx-1.22.1]# ./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream --add-module=../nginx_upstream_check_module-master/
[root@nginx-server nginx-1.22.1]# make   #如果是添加模块只需要make 第一次安装需要make install
[root@nginx-server nginx-1.22.1]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak  #将原来的nginx二进制命令备份
[root@nginx-server nginx-1.22.1]# ls objs/
[root@nginx-server nginx-1.22.1]# /usr/local/nginx/sbin/nginx
[root@nginx-server nginx-1.22.1]# /usr/local/nginx/sbin/nginx stop
[root@nginx-server nginx-1.22.1]# cp objs/nginx /usr/local/nginx/sbin/ #将新生成的命令cp到nginx的命令目录中。# \cp不提醒,覆盖粘贴复制

配置健康检查

# vim /etc/nginx/nginx.conf
http {
upstream app {
        server 192.168.209.128 weight=1;
        server 192.168.209.130 weight=1;
        check interval=5000 rise=2 fall=3 timeout=4000 type=http port=80;
        check_http_send "HEAD / HTTP/1.0\r\n\r\n";
        check_http_expect_alive http_2xx http_3xx;
        }
        
server {
        listen       80;
        server_name  localhost;
​
        location / {
                proxy_pass http://app;
                proxy_redirect default;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                }
        location /status {   #开启监控状态页面,自定义如serverup
                check_status;
                access_log   off;
           }
        }
}
​​
参数解释:
interval:表示每隔多少毫秒向后端发送健康检查包;
rise:表示如果连续成功次数达到2 服务器就被认为是up;
fail:表示如果连续失败次数达到3 服务器就被认为是down;
timeout:表示后端健康请求的超时时间是多少毫秒;
type:表示发送的健康检查包是什么类型的请求;
port: 表示发送检查到后端的服务的端口;
check_http_send:表示http健康检查包发送的请求内容。为了减少传输数据量,推荐采用“head”方法;
check_http_expect_alive:指定HTTP回复的成功状态,默认认为2XX和3XX的状态是健康的;

浏览器查看访问状态

5、层协议方法(扩展)

(2)4层协议

TCP/IP协议

之所以说TCP/IP是一个协议族,是因为TCP/IP协议包括TCP、IP、UDP、ICMP、RIP、SMTP、ARP、TFTP等许多协议,这些协议一起称为TCP/IP协议。

从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层、网络层、传输层、应用层。

nginx在1.9.0的时候,增加了一个 stream 模块,用来实现四层协议(网络层和传输层)的转发、代理、负载均衡等。stream模块的用法跟http的用法类似,允许我们配置一组TCP或者UDP等协议的监听.

配置案例:  stream块是与http块同一级别

#4层tcp负载 
stream {
   upstream ssh_01 {
     server 192.168.209.129:22;
        }
​
   server {
    listen 6666;
    proxy_pass ssh_01;
    proxy_timeout 60s;
    proxy_connect_timeout 30s;
        }
}

三、nginx 会话保持

nginx会话保持主要有以下几种实现方式。

1、ip_hash

ip_hash使用源地址哈希算法,将同一客户端的请求总是发往同一个后端服务器,除非该服务器不可用。
ip_hash语法:
upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
}
ip_hash简单易用,但有如下问题:
当后端服务器宕机后,session会丢失;
来自同一局域网的客户端会被转发到同一个后端服务器,可能导致负载失衡;

2、sticky_cookie_insert---基于cookie实现

使用sticky_cookie_insert启用会话亲缘关系,让来自同一客户端的请求被传递到一组服务器的同一台服务器。与ip_hash不同之处在于,它不是基于IP来判断客户端的,而是基于cookie来判断。
第三方模块---sticky模块,可以避免上述ip_hash中来自同一局域网的客户端和前段代理导致负载失衡的情况。

过程:

编译安装sticky模块,#给yum安装的nginx添加模块
[root@nginx-server ~]# yum install -y pcre* openssl* gcc gcc-c++ make 安装编译环境
[root@nginx-server ~]# wget  https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip  #下载sticky模块
[root@nginx-server ~]# nginx -v
nginx version: nginx/1.18.0
[root@nginx-server ~]# wget  http://nginx.org/download/nginx-1.18.0.tar.gz #下载yum安装nginx对应版本的源码包
[root@nginx-server ~]# yum install -y unzip #安装解压工具
[root@nginx-server ~]# unzip 08a395c66e42.zip #解压模块包
[root@nginx-server ~]# mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42/ nginx-sticky-module-ng/  #重命名一个简洁的文件名
[root@nginx-server ~]# tar xzvf nginx-1.18.0.tar.gz -C /usr/local/ #解压nginx的源码包
[root@nginx-server ~]# cd /usr/local/nginx-1.18.0/
[root@nginx-server nginx-1.18.0]# nginx -V #查看yum安装nginx所有模块
[root@nginx-server nginx-1.18.0]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --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-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/root/nginx-sticky-module-ng
[root@nginx-server nginx-1.18.0]# make && make install
配置基于cookie会话保持
[root@nginx-server conf.d]# vim upstream.conf
upstream web1 {
        server 192.168.198.143;
        server 192.168.198.145;
        sticky;
}
[root@nginx-server conf.d]# vim proxy.conf
server {
    listen       80;
    server_name  localhost;
​
    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;
​
    location / {
        proxy_pass http://qfedu;
    }
}
[root@nginx-server conf.d]# nginx -t 
[root@nginx-server conf.d]# nginx -s reload
或者:
upstream web1 {
        server 192.168.198.143;
        server 192.168.198.145;
        sticky expires=1h domain=testpm.com path=/;
}​
说明:
expires:设置浏览器中保持cookie的时间 
domain:定义cookie的域 
path:为cookie定义路径

 浏览器测试访问

# nginx -s reload
# curl -I ip地址

注意:使用后端服务器自身通过相关机制保持session同步,如:使用数据库、redis、memcached 等做session复制

四、nginx 实现动静分离

为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。 简单来说,就是使用正则表达式匹配过滤,然后交个不同的服务器。动态内容通常是由后端应用程序生成的,而静态内容是指不经常变化的文件,如HTML、CSS、JavaScript、图片等。

准备环境

准备一个nginx代理 两个http 分别处理动态和静态。

expires功能说明---(为客户端配置缓存时间)
  nginx缓存的设置可以提高网站性能,对于网站的图片,尤其是新闻网站,图片一旦发布,改动的可能是非常小的,为了减小对服务器请求的压力,提高用户浏览速度,我们可以通过设置nginx中的expires,让用户访问一次后,将图片缓存在用户的浏览器中,且时间比较长的缓存。
原理:当nginx设置了expires后,例如设置为:expires 10d; 那么用户在10天内请求的时候,都只会访问浏览器中的缓存,而不会去请求nginx。
注:需要注意的是,这种缓存方式只能在用户不对浏览器强制刷新的情况下生效,如果用户通过url来进行访问,是可以访问到缓存的。

1.静态资源配置

server {
        listen 80;
        server_name     localhost;
​
        location ~ \.(html|jpg|png|js|css) {
        root /home/www/nginx;
        expires      1d; #为客户端设置静态资源缓存时间,如1h,1m
        }
}
​# \ 转义
测试:
[root@nginx-yum2 conf.d]# curl -I http://10.0.105.200/test.jpg
HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Mon, 07 Sep 2019 11:35:08 GMT
Content-Type: image/jpeg
Content-Length: 27961
Last-Modified: Mon, 07 Sep 2019 11:31:17 GMT
Connection: keep-alive
ETag: "5f561a05-6d39"
Expires: Tue, 08 Sep 2019 11:35:08 GMT  #缓存到期时间
Cache-Control: max-age=86400 #缓存持续时间(秒)
Accept-Ranges: bytes

2.动态资源配置

yum 安装php7.1
~]# yum install -y epel-release
~]# rpm -ivh  http://rpms.remirepo.net/enterprise/remi-release-7.rpm
~]# cd /etc/yum.repos.d/
~]# ls
remi-php73.repo              remi-php74.repo
remi-php80.repo              nginx.repo
remi-php81.repo              remi-modular.repo
remi-php82.repo              remi-php54.repo
remi-php83.repo              remi-php70.repo
remi.repo                    remi-php71.repo
remi-safe.repo               epel.repo
remi-php72.repo
~]# yum install -y yum-utils
~]# yum-config-manager --enable remi-php71 #启用remi-php71软件仓库
~]# yum install php-xsl php php-ldap php-cli php-common php-devel php-gd php-pdo php-mysql php-mbstring php-bcmath php-mcrypt -y
~]# yum install -y php-fpm
~]# systemctl start php-fpm
~]# systemctl enable php-fpm

动态服务器编辑nginx连接php
~]# vim /etc/nginx/conf.d/default.conf  #编辑nginx的配置文件:
server {
        listen      80;
        server_name     localhost;
        location ~ \.php$ {
            root           usr/share/nginx/html;  #指定网站目录
            fastcgi_pass   127.0.0.1:9000;    #开启fastcgi连接php地址
            fastcgi_index  index.php;       #指定默认文件
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name; 
            #站点根目录,取决于root配置项
            include        fastcgi_params;  #包含fastcgi使用的常量
            }
        }
~]# cd /usr/share/nginx/html
html]# vim index.php

3.配置nginx反向代理upstream,并实现客户端缓存时间

# vim /etc/nginx/conf.d/upstream.conf
upstream static {
        server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=60s;
        }
upstream php {
        server 10.0.105.200:80 weight=1 max_fails=1 fail_timeout=60s;
        }
​
        server {
        listen      80;
        server_name     localhost
        #动态资源加载
        location ~ \.(php|jsp)$ {
            proxy_pass http://php;
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                }
        #静态资源加载
        location ~ .*\.(html|jpg|png|css|js)$ {
            proxy_pass http://static;
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                }
        }
当访问静态页面的时候location 匹配到 (html|jpg|png|js|css) 通过转发到静态服务器,
静态服务通过location的正则匹配来处理请求。
当访问动态页面时location匹配到 .\php 结尾的文件转发到后端php服务处理请求。

五、nginx的localtion指令详解

nginx中的location指令用于指定请求的处理位置。它可以根据请求的URI进行匹配,并且根据匹配结果执行相应的操作。

location指令的语法如下:location [修饰符] 匹配规则 { ...操作内容... }

Nginx 的 HTTP 配置主要包括三个区块,结构如下:

http {                      # 这个是协议级别
  include mime.types;
  default_type application/octet-stream;
  keepalive_timeout 65;
  gzip on;
    server {             # 这个是服务器级别
      listen 80;
      server_name localhost;
        location / {  # 这个是请求级别
          root html;
          index index.html index.htm;
        }
      }
}

1、location 区段

- location 是在 server 块中配置,根据不同的 URI 使用不同的配置,来处理不同的请求。
- location 是有顺序的,会根据不同请求配置的优先级来匹配的location 处理。
基本语法如下:
location [=|~|~*|^~|@] pattern{……}

2、location 前缀含义

=    表示精确匹配,优先级最高,只有请求的URI与匹配规则完全一致时才会执行操作 
^~   普通字符串前缀匹配,表示uri以某个常规字符串开头
~    区分大小写的正则匹配  
~*   不区分大小写的正则匹配
!~   表示区分大小写不匹配的正则
!~*  表示不区分大小写不匹配的正则
/    通用匹配,任何请求都会匹配到,优先级最低

查找顺序和优先级
= 大于 ^~  大于 ~|~*|!~|!~* 大于 /
多个location配置的情况下匹配顺序为:
首先匹配 =,其次匹配^~, 其次是按正则匹配,最后是交给 / 通用匹配。
当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

3、location 配置示例

1、没有修饰符 表示:必须以指定模式开始

# mkdir -p /data/www/abc
# echo abc >> /data/www/abc/1.html
# vim vim /etc/nginx/conf.d/app.conf
server {
    listen       80;
    server_name  localhost;
​
    location  /abc {
        root    /data/www;
        index   1.html;
        }

# nginx -t
# systemctl restart nginx
​
访问测试
http://192.168.1.9/abc

2、=表示:必须与指定的模式精确匹配

# vim /etc/nginx/conf.d/app.conf
server {
    listen       80;
    server_name  localhost;
    access_log  /var/log/nginx/http_access.log  main;
    
​    location  /abc {
        root    /data/www;
        index   1.html;
        } 

    location / {
                return https://www.baidu.com;
        }
    
    
    location = / {
                return https://www.jd.com;
        }
}
# nginx -s reload

测试:访问192.168.1.9/abc(注意浏览器无缓存)
可以看的直接跳转到京东

3、~ 表示:指定的正则表达式要区分大小写

# mkdir /data/www/nginx
# ls /data/www/
# 
server {
server_name localhost;
  location ~ /abc {
          root /data/www/nginx;
          index 2.html index.html;
        }
}
测试访问:
http://192.168.1.9/abc
不正确的
http://192.168.1.9/ABC
========================================
如果将配置文件修改为
      location ~ /ABC {
            root /home/www/nginx;
            index 2.html index.html;
        }
创建目录和文件:
[root@ansible-server html]# cd /home/www/nginx/
[root@ansible-server nginx]# mkdir ABC
[root@ansible-server nginx]# vim ABC/2.html
 访问:
 http://192.168.1.9/ABC/
 
 结论:~ 需要区分大小写。而且目录需要根据大小写定义。
404原因:访问路径是否正确;访问目录是否存在;路径大小写是否正确;

4、^~和~*匹配案例

~*:表示不区分大小写的正则匹配
[root@localhost conf.d]# vim /etc/nginx/conf.d/default.conf 
server {
    listen       80;
    server_name  localhost;
​
    #access_log  /var/log/nginx/host.access.log  main;
​
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
​
    location ~* /a/b/ {
        return 888;
    }
​
}
​
测试:
[root@localhost ~]# curl -I http://192.168.209.200/a/b/
HTTP/1.1 888 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:14:09 GMT
Content-Length: 0
Connection: keep-alive
​
[root@localhost ~]# curl -I http://192.168.209.200/A/B/
HTTP/1.1 888 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:16:52 GMT
Content-Length: 0
Connection: keep-alive
​
​
​^~:表示uri以某个常规字符串开头,理解为匹配url路径即可
例如:下面配置文件有两条规则,分别匹配url以字母a开头,但是长度不同,首先将长的规则先注释掉,如下:
# vim /etc/nginx/conf.d/default.conf 
server {
    listen       80;
    server_name  localhost;
​
    #access_log  /var/log/nginx/host.access.log  main;
​
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
​
    location ^~ /a/ {
        return 123;
        }
​
    #location ^~ /a/b/ {    #注释掉/a/b
        #return 12345;
        #}
​
}
测试:
# curl -I http://192.168.209.200/a/
HTTP/1.1 678 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:28:03 GMT
Content-Length: 0
Connection: keep-alive
[root@localhost ~]# curl -I http://192.168.209.200/a/b/
HTTP/1.1 678 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:28:07 GMT
Content-Length: 0
Connection: keep-alive
[root@localhost ~]# curl -I http://192.168.209.200/a/b/dsdfsdf
HTTP/1.1 678 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:28:10 GMT
Content-Length: 0
Connection: keep-alive
结论:
当前只有一个规则开启,因此当匹配url以/a/开头的任何url时,都会返回状态码678
​
# vim /etc/nginx/conf.d/default.conf  
server {
    listen       80;
    server_name  localhost;​
    #access_log  /var/log/nginx/host.access.log  main;

    location ^~ /a/ {
        return 678;
        }
​
    location ^~ /a/b/ {             # 取消注释
        return 876;
        }
}​
​
测试:
# curl -I http://192.168.209.200/a/
HTTP/1.1 678 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:44:52 GMT
Content-Length: 0
Connection: keep-alive
​
# curl -I http://192.168.209.200/a/b/
HTTP/1.1 876 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:44:56 GMT
Content-Length: 0
Connection: keep-alive
​
# curl -I http://192.168.209.200/a/b/sdgsdgdg
HTTP/1.1 876 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:44:58 GMT
Content-Length: 0
Connection: keep-alive
​
结论:
两条规则同时被匹配成功,但是第二条规则比较长,因此第二条规则优先被匹配。(最长匹配)

六、nginx 地址重写 rewrite

1、什么是Rewrite

Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程

  • 从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客利用,对你的系统造成一定的破坏,所以静态化的URL地址可以给我们带来更高的安全性。

  • 实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问tianyun.com的80端口时,将其跳转到443端口。

2、Rewrite 相关指令

  • Nginx Rewrite 相关指令有 if、rewrite、set、return

  • 语法

rewrite regex replacement [flag];

regex是用来匹配请求URI的正则表达式,
replacement是用来替换匹配到的部分的字符串。
flag是可选的标志,用于指定重写规则的行为。

2.1、if 语句

  • 应用环境

    作用域:
    server块
    location块

    语法:

    if (condition) { … }
    if 可以支持如下条件判断匹配符号
    ~                   正则匹配 (区分大小写)
    ~*                  正则匹配 (不区分大小写)
    !~                  正则不匹配 (区分大小写)
    !~*                 正则不匹配  (不区分大小写)
    -f 和!-f             用来判断是否存在文件
    -d 和!-d             用来判断是否存在目录
    -e 和!-e             用来判断是否存在文件或目录
    -x 和!-x             用来判断文件是否可执行
    ​
    在匹配过程中可以引用一些Nginx的全局变量
    $args               请求中的参数;
    $document_root      针对当前请求的根路径设置值;
    $host               请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
    $limit_rate         对连接速率的限制;
    $request_method     请求的方法,比如"GET"、"POST"等;
    $remote_addr        客户端地址;
    $remote_port        客户端端口号;
    $remote_user        客户端用户名,认证用;
    $request_filename   当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images/a.jpg)
    $request_uri        当前请求的文件路径名(不带网站的主目录/images/a.jpg)
    $query_string       与$args相同;
    $scheme             用的协议,比如http或者是https
    $server_protocol    请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
    $server_addr        服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
    $server_name        请求到达的服务器名;
    $document_uri       与$uri一样,URI地址;
    $server_port        请求到达的服务器端口号;

    2.2、Rewrite flag

    rewrite 指令根据表达式来重定向URI,或者修改字符串。可以应用于server,location, if环境下每行rewrite指令最后跟一个flag标记,支持的flag标记有:

    last                表示完成rewrite。默认为last。
    break               本条规则匹配完成后,终止匹配,不再匹配后面的规则
    redirect            返回302临时重定向,浏览器地址会显示跳转后的URL地址
    permanent           返回301永久重定向,浏览器地址会显示跳转后URL地址

    redirect 和 permanent区别则是返回的不同方式的重定向:

    对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。

    使用302重定向时,搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,也许地址栏不会更改。

1、Rewrite匹配参考示例

本地解析host文件--wind
# http://www.testpm.com/a/1.html ==> http://www.testpm.com/b/2.html
    location /a {
        root    /html;             #可不写
        index   1.html index.htm;  #可不写
        rewrite .* /b/2.html permanent;
        }
    location /b {
        root    /html;
        index   2.html index.htm;
        }
例2:(二级目录跳转,(.*)捕获了所有/2019/二级目录后面的路径和查询参数)
# http://www.testpm.com/2019/a/1.html ==> http://www.testpm.com/2018/a/1.html
     location /2019/a {
        root    /var/www/html;
        index   1.html index.hml;
        rewrite ^/2019/(.*)$ /2018/$1 permanent; 
        }
     location /2018/a {
        root    /var/www/html;
        index   1.html index.htl;
        }
​
例3:
# http://www.qf.com/a/1.html ==> http://jd.com
location /a {
        root    /html;
        if ($host ~* www.baidu.com ) {
        rewrite .* http://jd.com permanent;
        }
}
​
例4:
# http://www.qf.com/a/1.html ==> http://jd.com/a/1.html
location /a {
        root /html;
        if ( $host ~* baidu.com ){
        rewrite .* http://jd.com$request_uri permanent;
        }
}
​
例5:
# http://www.tianyun.com/login/tianyun.html ==> http://www.tianyun.com/reg/login.html?user=tianyun
    location /login {
        root   /usr/share/nginx/html;
        rewrite ^/login/(.*)\.html$ http://$host/reg/login.html?user=$1;
        }
    location /reg {
        root /usr/share/nginx/html;
        index login.html;
        }
​
例6:
#http://www.tianyun.com/qf/11-22-33/1.html  ==>  http://www.tianyun.com/qf/11/22/33/1.html
location /qf {
            rewrite ^/qf/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /qf/$1/$2/$3$4 permanent;
        }
​
        location /qf/11/22/33 {
                root /html;
                index   1.html;
        }

2、set 指令

set 指令是用于定义一个变量,并且赋值

应用环境:

server,location,if

应用示例

例8:
#http://alice.testpm.com ==> http://www.testpm.com/alice
#http://jack.testpm.com ==> http://www.testpm.com/jack
​
[root@nginx-server conf.d]# cd /usr/share/nginx/html/
[root@nginx-server html]# mkdir jack alice
[root@nginx-server html]# echo "jack.." >> jack/index.html
[root@nginx-server html]# echo "alice.." >> alice/index.html
​
本地解析域名host文件
打开windows本地文件:C:\Windows\System32\drivers\etc\hosts
10.0.105.202 www.testpm.com
10.0.105.202 alice.testpm.com
10.0.105.202 jack.testpm.com

# echo alice >> /usr/share/nginx/html/alice/index.html
# echo jack >> /usr/share/nginx/html/jack/index.html
# vim /etc/nginx/conf.d/app.conf  
#编辑配置文件,不同配置文件需要区别域名或者端口,如下端口设置为81
server {
    listen       81;   
    server_name  www.testpm.com;
​
    location / {
         root   /usr/share/nginx/html;
         index  index.html index.htm;
         if ( $host ~* ^www.testpm.com$) {
                break;
                }
         if ( $host ~* "^(.*)\.testpm\.com$" ) {
                set $user $1;
                rewrite .* http://www.testpm.com/$user permanent;
                }
        }
    location /jack {
         root /usr/share/nginx/html;
         index  index.html;
        }
    location /alice {
         root /usr/share/nginx/html;
         index index.html;
        }
}

3、return 指令

return 指令用于返回状态码给客户端

server,location,if

应用示例:

例9:如果访问的.sh结尾的文件则返回403操作拒绝错误
server {
    listen       80;
    server_name  www.testpm.cn;
    #access_log  /var/log/nginx/http_access.log  main;
​
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        }
​
    location ~* \.sh$ {
        return 403;
        }
}
​
例10:80 ======> 443 :80转443端口
server {
    listen       80;
    server_name  www.testpm.cn;
    access_log  /var/log/nginx/http_access.log  main;
    return 301 https://www.testpm.cn$request_uri;
}
​
server {
    listen 443 ssl;
    server_name www.testpm.cn;
    access_log  /var/log/nginx/https_access.log  main;
​
    #ssl on;
    ssl_certificate   /etc/nginx/cert/2447549_www.testpm.cn.pem;
    ssl_certificate_key  /etc/nginx/cert/2447549_www.testpm.cn.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers on;
​
    location / {
        root  /usr/share/nginx/html;
        index index.html index.htm;
    }
}
​
[root@nginx-server ~]# curl -I http://www.testpm.cn
HTTP/1.1 301 Moved Permanently
Server: nginx/1.16.0
Date: Wed, 03 Jul 2019 13:52:30 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://www.testpm.cn/

4、last,break详解

last指令:当使用last指令时,Nginx会重新开始处理匹配的location块。它会重新解析URI,并在重新匹配的location块中继续处理请求。

break指令:当使用break指令时,Nginx会停止在当前的location块中处理请求,并直接返回对应的内容。这个指令在重写URI时特别有用,它会停止后续的location匹配过程。

[root@localhost test]# cat /etc/nginx/conf.d/last_break.conf 
server {
    listen       80;
    server_name  localhost;
    access_log  /var/log/nginx/last.access.log  main;
​
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    location /break/ {
        root /usr/share/nginx/html;
        rewrite .* /test/break.html break;
    }
    location /last/ {
        root /usr/share/nginx/html;
        rewrite .* /test/last.html last;
    }
    location ~ /test/ {                     #二级目录test后要加/,因为要进入test匹配内容
        root /usr/share/nginx/html;
        rewrite .* /test/test.html break;
    }
​
}
[root@localhost conf.d]# cd /usr/share/nginx/html/
[root@localhost html]# mkdir test       #最终跳转路径需要有对应目录和文件内容
[root@localhost html]# echo "last" > test/last.html
[root@localhost html]# echo "break" > test/break.html
[root@localhost html]# echo "test" > test/test.html
​
http://10.0.105.196/break/break.html
http://10.0.105.196/last/last.html

注意:

- last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求;

- break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配;

- 使用 proxy_pass 指令时,则必须使用break。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1970402.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计选题推荐-预制菜平台-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

传输限速的方案那么多,却都没有这一个全面

在很多行业和领域&#xff0c;传输速度并不是无限制地越快越好&#xff0c;反而基于很多原因&#xff0c;在很多情况下&#xff0c;需要对传输的速度进行限制&#xff0c;原因如下&#xff1a; 带宽分配&#xff1a;在有限的网络资源下&#xff0c;对传输进行限速可以确保关键…

MIT-离散数学笔记

离散数学 PropositionEx 1:Ex 2:Ex 3:Ex 4:Ex 5:Ex 6:Ex 7:Ex 8: Proposition In mathematics, we have a mathematical proof is a verification of a proposition by a chain of logical deductions from a set of axioms. 在数学中&#xff0c;数学证明是通过一组公理的一系…

强化学习-alphazero 算法理论

一、算法简介 简单地说&#xff0c;AlphazeroMCTS SL(策略网络价值网络) Selfplay resnet。 其中MCTS指的是蒙特卡洛树搜索&#xff0c;主要用于记录所有访问过的棋盘状态的各种属性&#xff0c;包括该状态访问次数&#xff0c;对该状平均评价分数等。 SL指监督学习算法&…

PCDN技术如何提高数据传输的可靠性?

PCDN技术通过以下方式提高数据传输的可靠性: 1.负载均衡与故障转移: PCDN系统具备负载均衡的能力&#xff0c;可以根据节点的负载情况动态分配请求&#xff0c;避免单点故障和过载情况。此外&#xff0c;当某个节点发生故障时&#xff0c;PCDN可以迅速将流量转移到其他可用节…

OpenAI推出GPT-4o长输出版版本

&#x1f989; AI新闻 &#x1f680; OpenAI推出GPT-4o长输出版版本 摘要&#xff1a;OpenAI宣布正在测试每次请求可输出最多64K tokens的GPT-4o长输出版版本&#xff0c;目前仅Alpha测试参与者可使用。该版本推理成本较高&#xff0c;定价每百万tokens输入6美元&#xff0c;…

从微架构到向量化--CPU性能优化指北

引入 定位程序性能问题&#xff0c;相信大家都有很多很好的办法&#xff0c;比如用top/uptime观察负载和CPU使用率&#xff0c;用dstat/iostat观察io情况&#xff0c;ptrace/meminfo/vmstat观察内存、上下文切换和软硬中断等等&#xff0c;但是如果具体到CPU问题&#xff0c;我…

用于跟踪个人图书馆的BookLogr

什么是 BookLogr &#xff1f; BookLogr 是一款网络应用&#xff0c;旨在帮助您轻松管理个人图书馆。这项自托管服务可确保您完全控制数据&#xff0c;提供安全且私密的方式来跟踪您拥有、阅读或希望阅读的所有书籍。您也可以选择向公众自豪地展示您的图书馆&#xff0c;与您的…

申请流量卡不通过,这是什么原因呢,又该如何解决?

在申请流量卡时&#xff0c;有些人会出现被拒绝的情况&#xff0c;你知道这是怎么回事吗&#xff1f;申请流量卡被拒绝又该如何解决呢&#xff1f;下面这些问题都给你整理下了&#xff01; ​ 常见原因&#xff1a; 1.信息有误&#xff1a;收件人/办卡人&#xff1a;必须是同一…

How to specify the LangSmith project name for each Chain?

题意&#xff1a;如何为每个链指定LangSmith项目名称&#xff1f; 问题背景&#xff1a; According to the LangSmith documentation you need to set the LANGCHAIN_PROJECT environment variable to specify the project name in langsmith. 根据LangSmith的文档&#xff0…

Vmware ubuntu20.04 虚拟文件夹

目录 1.vmware 设置 2.ubuntu设置 1.vmware 设置 设置完成后我们开机 2.ubuntu设置 我们打开终端 输入命令 vmware-hgfsclient可以看到你当前的共享文件 然后我们输入以下命令&#xff0c;用于将共享文件夹挂载到虚拟机中 sudo vmhgfs-fuse .host:/ /mnt -o nonempty -o …

(24)(24.1) FPV和仿真的机载OSD(一)

文章目录 前言 1 参数 2 第二OSD 3 屏幕和屏幕切换 4 面板项目 5 呼号面板 6 用户可编程警告 7 使用SITL测试OSD 8 OSD面板列表 前言 使用 MAX7456 型芯片的板载操作系统和基于 MSP 的外部操作系统&#xff08;包括 DJI 护目镜和使用DisplayPort 的护目镜&#xff09…

【IEEE Fellow特邀报告,JPCS独立出版】第四届电子通信与计算机科学技术国际学术会议(ECCST 2024,9月20-22)

2024年第四届电子通信与计算机科学技术国际学术会议将于2024年9月20-22日在中国上海举行。 会议旨在为从电子与通信、网络、人工智能与计算机技术研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术&#xff0c;了解学术发展趋势&#xff0c;拓宽研究思…

delphi 11其中改变组件以及IDE的字体大小

1、先将form的font改好。 2、保证组件的parentfont为true即可。比如edit1.parentfont&#xff1a;true procedure TForm1.Button1Click(Sender: TObject); beginif self.FontDialog1.Execute() thenbeginform1.Font:self.FontDialog1.Font;self.Edit1.ParentFont:true;end; en…

string习题:字符串最后一个单词的长度

字符串最后一个单词的长度 因为原字符串中可能会有很多个单词&#xff0c;所以我们需要寻找字符串中的最后一个" "的位置pos 接着用&#xff08;size-pos-1&#xff09;&#xff0c;这样计算出来的就是字符串中最后一个单词的长度 按照这样的逻辑&#xff0c;我们会…

MySQL 的binlog 、undolog 、redolog

Binlog (二进制日志) bin Log 作用 用于记录所有修改数据库数据的 SQL 语句或行级别的变化&#xff0c;主要用于主从复制和数据恢复。 binlog格式 STATEMENT模式&#xff1a;binlog里面记录的就是SQL语句的原文。优点是并不需要记录每一行的数据变化&#xff0c;减少了binlo…

1990-2022年 上市公司-战略差异度(原始数据、计算代码、参考文献和最终计算结果)

上市公司战略差异度是衡量企业在战略制定和实施过程中所展现的独特性和创新性的指标。它体现了公司对市场环境、行业趋势及自身能力的独特见解和战略布局。通过分析上市公司的战略差异度&#xff0c;可以深入理解企业的市场竞争策略、行业定位和发展方向。 战略差异度的重要性…

Docker镜像拉取失败解决方案

文章目录 问题及分析解决方案1.先排查DNS2.修改源3.代理配置4.重启docker服务 问题解决 问题及分析 今天我用docker拉取镜像的时候报错 error pulling image configuration: download failed after attempts6: dial tcp xxx.xx.xxx.xx:xxx: i/o timeout 连接超时大概率以下两个…

在 Mac 上进行本地 LLM 微调(M1 16GB)

适合初学者的 Python 代码演练 (ft. MLX) 欢迎来到雲闪世界。本文展示了如何使用 Google Colab 上的单个&#xff08;免费&#xff09;GPU 微调 LLM。虽然该示例&#xff08;以及许多其他示例&#xff09;可以在 Nvidia 硬件上轻松运行&#xff0c;但它们并不容易适应 M 系列 M…

Windows10点击文件夹右键卡死的解决办法

1、首先同时按下【WinR】打开运行页面&#xff0c;输入命令【regedit】按下回车或者点击确定。 2、打开注册表编辑器后&#xff0c;定位到如下位置“HKEY_CLASSES_ROOT\Directory\Background\Shellex\ContextMenuHandlers”。 3、然后在其中将所有名为“New”的文件或项全部删…