当前位置: 首页 > news >正文

Nginx 性能优化技巧与实践(二)

五、性能优化之负载均衡篇

5.1 负载均衡算法介绍

Nginx 作为一款强大的 Web 服务器和反向代理服务器,其负载均衡功能是提升 Web 服务性能和可靠性的关键。Nginx 支持多种负载均衡算法,每种算法都有其独特的原理和特点,适用于不同的业务场景。

轮询(Round Robin)是 Nginx 的默认负载均衡算法,它就像一个有条不紊的调度员,按照顺序将请求依次分发到后端服务器。比如,假设有三个后端服务器 A、B、C,当有请求到来时,第一个请求会被分配到服务器 A,第二个请求分配到服务器 B,第三个请求分配到服务器 C,然后再循环回到服务器 A,依次类推。这种算法简单直接,易于实现,在后端服务器性能相近的情况下,能够均匀地分配负载,确保每个服务器都能得到充分利用。然而,它的局限性在于无法感知服务器的实际负载情况,如果某个服务器的性能突然下降或出现故障,轮询算法仍然会按照顺序将请求分配给它,可能导致部分请求响应缓慢或失败。

加权轮询(Weighted Round Robin)算法则是在轮询的基础上,考虑了服务器的性能差异。它为每个后端服务器分配一个权重值,权重越高,表示该服务器的处理能力越强,能够承担更多的请求。在实际分配请求时,Nginx 会根据权重比例将请求分配到不同的服务器上。例如,服务器 A 的权重为 3,服务器 B 的权重为 2,服务器 C 的权重为 1,那么在每 6 个请求中,服务器 A 可能会被分配到 3 个请求,服务器 B 被分配到 2 个请求,服务器 C 被分配到 1 个请求。这种算法适用于后端服务器配置和性能参差不齐的场景,能够更加合理地分配负载,提高整体系统的处理能力。

源地址哈希(IP Hash)算法依据客户端 IP 地址的哈希值来分配请求。它通过对客户端 IP 地址进行哈希计算,得到一个固定的哈希值,然后根据这个哈希值将请求分配到特定的后端服务器。这样一来,来自同一客户端的请求总是会被分配到同一台服务器上,这对于需要保持会话一致性的应用场景非常重要,比如用户登录系统后,后续的请求需要始终由同一台服务器处理,以确保用户的会话状态不丢失。然而,这种算法也存在一定的局限性,由于哈希值的计算与客户端 IP 地址紧密相关,如果客户端 IP 地址分布不均匀,可能会导致某些服务器负载过高,而其他服务器负载过低,出现负载不均衡的情况。

最小连接数(Least Connections)算法会将请求分配给当前连接数最少的后端服务器。它实时监控每个后端服务器的连接数,当有新的请求到来时,Nginx 会自动选择当前连接数最少的服务器来处理该请求。这种算法能够动态地感知服务器的负载情况,将请求分配到负载较轻的服务器上,从而保证系统的整体性能。在处理长连接的场景,如 WebSocket、数据库连接等,最小连接数算法能够有效地避免服务器因为连接数过多而导致性能下降,确保每个服务器都能高效地处理请求。

Fair 算法是一种相对智能的负载均衡算法,它需要安装第三方模块ngx_http_upstream_fair_module。该算法会根据后端服务器的响应时间来分配请求,响应时间短的服务器会被优先分配更多的请求。它的工作原理是通过实时监测后端服务器处理请求的响应时间,动态地调整请求的分配策略。对于那些对访问响应速度有较高要求的业务场景,如在线游戏、实时金融交易等,Fair 算法能够确保用户的请求能够快速得到响应,提升用户体验。然而,由于需要实时监测和计算响应时间,Fair 算法的实现相对复杂,对系统资源的消耗也相对较大。

url_hash 算法需要安装第三方模块ngx_http_upstream_hash_module,它根据请求 URL 的哈希值来分配请求。相同 URL 的请求会被分配到固定的服务器上,这在后端服务器为缓存服务器时非常有效。例如,对于一个图片资源网站,大量的图片请求可能会集中在某些特定的 URL 上,使用 url_hash 算法可以将这些相同 URL 的图片请求始终分配到同一台缓存服务器上,提高缓存命中率,减少后端服务器的压力,从而加快图片的加载速度,提升用户访问网站的体验。

5.2 选择合适的算法

在实际应用中,选择合适的负载均衡算法是优化 Nginx 性能的关键环节。不同的业务场景对负载均衡算法有不同的要求,需要根据具体情况进行综合考虑。

当后端服务器性能相近时,轮询算法是一个不错的选择。这种情况下,服务器的处理能力基本相同,轮询算法能够简单有效地将请求均匀地分配到各个服务器上,保证每个服务器都能充分发挥其性能,不会出现某个服务器负载过高或过低的情况。例如,对于一个小型的企业网站,后端服务器的配置和性能差异不大,使用轮询算法就可以满足基本的负载均衡需求,实现高效稳定的服务。

若后端服务器配置差异较大,加权轮询算法则更为合适。由于服务器的性能参差不齐,通过为不同性能的服务器分配不同的权重,可以使性能较强的服务器承担更多的请求,性能较弱的服务器承担较少的请求,从而实现资源的合理分配,提高整个系统的处理能力。比如,在一个电商平台中,部分服务器配置了高性能的 CPU 和大容量的内存,而部分服务器配置相对较低,此时使用加权轮询算法,为高性能服务器设置较高的权重,为低性能服务器设置较低的权重,能够确保系统在高并发情况下依然能够稳定运行,为用户提供快速的服务响应。

对于有会话保持需求的场景,如用户登录系统、购物车功能等,源地址哈希算法是首选。它能够保证来自同一客户端的请求始终被分配到同一台服务器上,确保用户的会话状态不丢失,提供连贯的用户体验。以在线购物为例,用户在浏览商品、添加商品到购物车、结算等一系列操作过程中,需要保持会话一致性,使用源地址哈希算法可以确保用户的所有请求都由同一台服务器处理,避免出现购物车数据丢失或订单处理错误等问题。

在处理长连接的场景,如 WebSocket 实时通信、数据库长连接等,最小连接数算法能够根据服务器的实时连接数动态分配请求,将请求分配到连接数最少的服务器上,避免服务器因为连接数过多而导致性能下降,保证系统的整体性能和稳定性。例如,在一个实时聊天应用中,大量用户同时保持 WebSocket 连接进行实时通信,使用最小连接数算法可以确保每个服务器都能高效地处理用户的连接请求,实现快速稳定的消息传输。

当对访问响应速度有一定要求时,Fair 算法能够根据后端服务器的响应时间来分配请求,优先将请求分配给响应时间短的服务器,从而提高整体的访问响应速度。在一些对实时性要求较高的业务场景,如在线游戏、视频直播等,使用 Fair 算法可以确保用户能够快速地获取游戏数据、观看视频直播,提升用户体验。

若后端服务器为缓存服务器,url_hash 算法可以根据请求 URL 的哈希值将相同 URL 的请求分配到固定的服务器上,提高缓存命中率,减少后端服务器的压力。例如,在一个内容分发网络(CDN)中,大量的静态资源请求(如图片、CSS、JavaScript 文件等)可以通过 url_hash 算法分配到特定的缓存服务器上,当用户再次请求相同的资源时,能够直接从缓存服务器中获取,大大加快了资源的加载速度。

5.3 负载均衡配置实例

下面通过一个简单的负载均衡配置示例,展示如何在 Nginx 中配置负载均衡,将请求分发到多个后端服务器。假设我们有三个后端服务器,分别为backend1.example.combackend2.example.combackend3.example.com,我们希望使用轮询算法将请求分发到这三个服务器上。

首先,在 Nginx 的配置文件中,通过upstream模块定义后端服务器组:

 

http {

upstream backend {

server backend1.example.com;

server backend2.example.com;

server backend3.example.com;

}

server {

listen 80;

server_name example.com;

location / {

proxy_pass http://backend;

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;

}

}

}

在上述配置中:

  • upstream backend定义了一个名为backend的后端服务器组,其中包含了三个后端服务器backend1.example.combackend2.example.combackend3.example.com。由于没有指定负载均衡算法,Nginx 会默认使用轮询算法,按照顺序依次将请求分配到这三个服务器上。
  • server块定义了 Nginx 服务器的监听端口和域名,这里监听 80 端口,域名为example.com
  • location /表示对根路径的请求进行处理,proxy_pass http://backend将请求代理到backend服务器组,即按照负载均衡算法将请求分发到三个后端服务器中的一个。
  • 后面的proxy_set_header指令用于设置一些请求头信息,将客户端的真实 IP 地址、请求协议等信息传递给后端服务器,以便后端服务器能够正确处理请求并记录日志。

通过这样的配置,Nginx 就能够实现简单的负载均衡功能,将客户端的请求均匀地分发到多个后端服务器上,提高系统的性能和可靠性。在实际应用中,可以根据业务需求和服务器的实际情况,灵活调整负载均衡算法和相关配置参数,以达到最佳的性能优化效果。

六、性能优化之压缩篇

6.1 Gzip 压缩开启与配置

在 Nginx 的性能优化中,Gzip 压缩是一项重要的技术手段,它能够显著减少数据传输量,提高网站的加载速度,为用户带来更流畅的访问体验。

Gzip 压缩的原理基于数据的重复性。在许多类型的数据中,如文本文件、HTML 文件、CSS 文件和 JavaScript 文件等,存在大量的重复信息,像重复的单词、标签、样式声明等。Gzip 压缩通过使用 DEFLATE 算法,该算法结合了 LZ77 算法和哈夫曼编码。首先,LZ77 算法会在数据中查找重复出现的数据片段,并用指向先前出现位置的指针来表示这些片段,从而实现初步的压缩;接着,哈夫曼编码会对这些经过 LZ77 处理后的数据进行进一步编码,它为文件中的每个字符分配一个可变长度的代码字,频率更高的字符使用较短的代码字,频率较低的字符使用较长的代码字,以此来减少数据的整体大小,最终达到高效压缩数据的目的 。在 Web 传输中,当客户端请求资源时,服务器会将这些资源进行 Gzip 压缩,然后再发送给客户端,客户端接收到压缩后的数据后,会自动解压缩并使用其中的内容,这样大大减少了数据在网络传输中的时间,提高了传输效率。

在 Nginx 中开启 Gzip 压缩并进行配置是一个相对简单的过程。以下是一个基本的配置示例:

 

http {

gzip on;

gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/json;

gzip_comp_level 6;

gzip_min_length 1024;

gzip_buffers 4 16k;

gzip_http_version 1.1;

gzip_vary on;

gzip_disable "MSIE[1-6]\.";

}

在上述配置中:

  • gzip on;:这是开启 Gzip 压缩功能的关键指令,当设置为on时,Nginx 会对符合条件的响应数据进行 Gzip 压缩。
  • gzip_types:用于指定需要进行 Gzip 压缩的文件类型,这里列举了常见的文本类型、JavaScript 类型、CSS 类型、XML 类型和 JSON 类型等。只有当响应数据的 MIME 类型与这些指定类型匹配时,才会进行压缩。例如,对于一个包含大量 JavaScript 脚本的网页,当客户端请求该网页时,Nginx 会对其中的 JavaScript 文件进行 Gzip 压缩,从而减少传输的数据量。
  • gzip_comp_level:设置 Gzip 压缩级别,取值范围是 1 - 9 。数字越大,压缩比越高,即压缩后的文件越小,但同时压缩过程所消耗的 CPU 资源也越多,压缩时间也会更长;数字越小,压缩速度越快,但压缩比相对较低。这里设置为 6,是在压缩比和 CPU 消耗之间取得一个较为平衡的选择,既能有效减小数据传输量,又不会过度消耗服务器 CPU 资源。
  • gzip_min_length:表示只有当响应数据的大小大于这个值时,才会进行 Gzip 压缩。这里设置为 1024 字节(即 1KB),如果响应数据小于 1KB,Nginx 将不会对其进行压缩,因为对于过小的数据进行压缩,可能压缩后的文件大小并不会显著减小,反而会增加额外的压缩和解压缩开销。
  • gzip_buffers:用于设置压缩响应数据时所使用的缓冲区大小和数量。4 16k表示以 16KB 为单位,分配 4 个缓冲区,即总共 64KB 的缓冲区空间。这些缓冲区用于存储压缩过程中的临时数据,合理设置缓冲区大小可以提高压缩效率。
  • gzip_http_version:指定压缩响应所需要的最低 HTTP 请求版本,这里设置为 1.1 。这意味着只有当客户端的 HTTP 请求版本为 1.1 或更高时,才会对响应数据进行 Gzip 压缩。早期的 HTTP 1.0 版本可能对 Gzip 压缩的支持不够完善,通过设置这个参数可以确保兼容性。
  • gzip_vary on;:这个指令会在响应头中添加Vary: Accept-Encoding字段,它的作用是告诉缓存服务器(如 CDN),不同的客户端可能支持不同的编码方式(如是否支持 Gzip 压缩),缓存服务器应该根据客户端的Accept-Encoding头信息来存储不同版本的缓存内容,以便正确地为不同客户端提供服务。
  • gzip_disable "MSIE[1-6]\.";:用于禁止对特定浏览器进行 Gzip 压缩,这里使用正则表达式匹配 IE6 及以下版本的浏览器。因为这些早期的浏览器在处理 Gzip 压缩数据时可能存在兼容性问题,禁止对它们进行压缩可以避免出现乱码或其他错误。

6.2 压缩策略调整

在实际应用中,根据服务器的 CPU 能力、网络条件和资源类型来调整压缩策略是实现最佳性能和用户体验的关键。

服务器的 CPU 能力是调整压缩策略时需要重点考虑的因素之一。Gzip 压缩是一个 CPU 密集型的操作,压缩级别越高,对 CPU 的消耗就越大。如果服务器的 CPU 性能较弱,而设置了过高的压缩级别,可能会导致 CPU 负载过高,影响服务器的整体性能,甚至导致服务器响应缓慢或无法正常工作。在这种情况下,应该适当降低压缩级别,如将压缩级别设置为 3 或 4,以减少 CPU 的负担,确保服务器能够稳定运行。相反,如果服务器配备了高性能的 CPU,有足够的计算资源来处理压缩任务,那么可以适当提高压缩级别,如设置为 7 或 8,以获得更高的压缩比,进一步减少数据传输量,提高用户访问速度。

网络条件也是影响压缩策略的重要因素。在网络带宽充足的情况下,数据传输速度较快,此时可以适当降低压缩级别,因为即使不进行高度压缩,数据也能较快地传输到客户端。这样可以减少服务器的 CPU 消耗,将资源更多地用于其他业务处理。而在网络带宽有限的情况下,为了减少数据传输量,提高传输效率,就需要提高压缩级别,以尽可能地减小数据的大小。例如,对于一些移动网络用户,由于其网络带宽相对较低,信号稳定性也较差,提高压缩级别可以显著改善用户的访问体验,确保网页能够快速加载。

不同类型的资源对压缩的需求和效果也各不相同。对于文本类型的资源,如 HTML、CSS、JavaScript 和 JSON 等,它们通常具有较高的可压缩性,因为其中包含大量的重复字符和冗余信息,适合进行较高程度的压缩。可以将这些资源的压缩级别设置得相对较高,如 6 - 8 ,以有效减小文件大小,提高传输速度。而对于已经经过压缩的资源,如图片(JPEG、PNG 等)、视频(MP4、AVI 等)和音频(MP3、WAV 等)文件,再次进行 Gzip 压缩的效果往往不明显,甚至可能会因为压缩算法的特性,导致压缩后的文件大小反而增加。因此,对于这些资源,通常不建议进行 Gzip 压缩,可以通过其他方式,如选择合适的图片格式、优化视频编码等,来减少文件大小,提高传输效率。

通过综合考虑服务器的 CPU 能力、网络条件和资源类型,灵活调整 Gzip 压缩策略,能够在保证服务器性能稳定的前提下,为用户提供最佳的访问体验,实现高效、快速的 Web 服务。

七、性能优化之实战案例

7.1 案例背景

本次案例聚焦于一个大型电商网站,该网站拥有海量的商品种类和庞大的用户群体,涵盖了各类时尚服饰、电子产品、家居用品等。在日常运营中,网站已经积累了稳定的用户流量,但每逢重要促销活动,如 “双 11”“618” 等,网站的访问量会呈现爆发式增长,并发请求数在短时间内急剧攀升。在这些高并发场景下,网站的性能问题逐渐凸显。

7.2 优化前的状况

优化前,Nginx 采用默认的配置参数,工作进程数设置为 2,单个工作进程的最大连接数为 1024。在服务器资源使用方面,CPU 利用率在高并发时经常达到 90% 以上,内存使用率也接近 80%,磁盘 I/O 繁忙。业务系统的性能指标表现不佳,平均响应时间长达 5 秒以上,吞吐量仅为 5000 请求 / 秒,并发连接数只能维持在 2000 左右。在高并发时段,用户访问网站时页面加载缓慢,商品搜索、下单等操作响应迟钝,甚至出现页面无法加载、请求超时等情况,严重影响了用户体验和业务的正常开展。

7.3 优化措施实施

针对上述问题,采取了一系列 Nginx 性能优化措施。在配置参数调整方面,根据服务器的 8 核 CPU,将worker_processes设置为 8 ,充分利用 CPU 多核优势;将worker_connections增加到 10240,以提高并发连接处理能力;设置worker_cpu_affinity,将工作进程绑定到指定的 CPU 核心,减少 CPU 切换开销,即worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; 。同时,将worker_rlimit_nofile设置为 65536,并在/etc/security/limits.conf文件中相应调整,确保系统层面的文件描述符限制满足需求。

在事件处理模型上,启用epoll模型,修改配置为events { use epoll; worker_connections 10240; } ,以提升事件处理效率。连接与超时设置方面,将keepalive_timeout设置为 60 秒,及时关闭空闲连接;启用tcp_nodelay,确保数据实时发送;将client_header_timeout和client_body_timeout均设置为 15 秒,send_timeout设置为 25 秒,防止无效请求占用资源。

缓存优化上,开启文件缓存,配置如下:

 

http {

open_file_cache max=10000 inactive=30s;

open_file_cache_valid 60s;

open_file_cache_min_uses 3;

open_file_cache_errors on;

}

代理缓存配置为:

 

http {

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:20m max_size=20g inactive=120m use_temp_path=off;

server {

listen 80;

server_name example.com;

location / {

proxy_pass http://backend_server;

proxy_cache my_cache;

proxy_cache_key "$request_method$host$request_uri";

proxy_cache_valid 200 302 2h;

proxy_cache_valid 404 15m;

proxy_cache_bypass $cookie_no_cache $arg_no_cache $http_pragma $http_authorization;

proxy_no_cache $cookie_no_cache $arg_no_cache $http_pragma $http_authorization;

}

}

}

根据资源类型调整缓存策略,对于静态资源,如图片、CSS、JavaScript 文件,设置较长的缓存时间,如location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 14d; } ;对于动态资源,根据业务需求进行部分缓存或调整缓存时间。

负载均衡方面,由于后端服务器性能存在差异,采用加权轮询算法,为性能较强的服务器分配较高的权重,配置如下:

 

http {

upstream backend {

server backend1.example.com weight=3;

server backend2.example.com weight=2;

server backend3.example.com weight=1;

}

server {

listen 80;

server_name example.com;

location / {

proxy_pass http://backend;

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;

}

}

}

压缩优化上,开启 Gzip 压缩,配置如下:

 

http {

gzip on;

gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/json;

gzip_comp_level 6;

gzip_min_length 1024;

gzip_buffers 4 16k;

gzip_http_version 1.1;

gzip_vary on;

gzip_disable "MSIE[1-6]\.";

}

根据服务器 CPU 能力和网络条件,对于文本类型资源保持较高的压缩级别,对于已压缩资源不进行重复压缩。

7.4 优化后的效果

优化后,服务器资源使用情况得到显著改善。CPU 利用率在高并发时稳定在 60% 左右,内存使用率降低到 60% 以下,磁盘 I/O 负载明显减轻。业务系统性能指标大幅提升,平均响应时间缩短至 1 秒以内,吞吐量提升到 15000 请求 / 秒以上,并发连接数提高到 8000 以上。用户访问网站时,页面加载迅速,商品搜索、下单等操作响应流畅,有效提升了用户体验,保障了业务在高并发场景下的稳定运行,促进了业务的增长和发展。

八、总结与展望

通过对 Nginx 性能优化的多方面探索,我们深入了解了其在 Web 服务中的关键作用以及优化的重要性。从配置参数的精细调整,如合理设置 Worker 进程相关参数、选择高效的事件处理模型和优化连接与超时设置,到缓存策略的巧妙运用,包括开启文件缓存、配置代理缓存和根据资源类型调整缓存策略,再到负载均衡算法的精准选择和配置,以及 Gzip 压缩的有效实施,每一个环节都对 Nginx 的性能提升起着至关重要的作用。

在实际应用中,没有一种通用的优化方案适用于所有场景。不同的业务场景,如电商网站、社交平台、新闻资讯网站等,具有各自独特的业务特点和性能需求。电商网站在促销活动期间对并发处理能力和响应速度要求极高,需要重点优化负载均衡和缓存策略;社交平台则更注重用户会话的保持和实时通信的稳定性,源地址哈希算法和长连接处理的优化就显得尤为重要。因此,我们必须根据具体的业务场景进行针对性的优化,深入分析业务的流量特点、数据更新频率、用户行为等因素,制定出最适合的优化策略,才能充分发挥 Nginx 的性能优势,为用户提供高效、稳定的服务。

展望未来,随着互联网技术的飞速发展,Web 服务面临的挑战也将不断升级。用户对服务的响应速度和稳定性要求越来越高,业务的复杂性和数据量也在持续增长。Nginx 作为 Web 服务的核心组件,其性能优化也将不断演进。未来,Nginx 可能会在以下几个方面取得突破和发展:在算法优化方面,不断研发更智能、高效的负载均衡算法和缓存算法,以适应日益复杂的业务场景和海量的数据处理需求;在功能扩展上,与新兴技术如容器编排工具(如 Kubernetes)、服务网格(如 Istio)等深度融合,为云原生应用提供更强大的支持;在性能监测和自动化优化方面,借助人工智能和机器学习技术,实现对 Nginx 性能的实时监测和自动优化,及时发现并解决性能瓶颈问题,进一步提升服务的可靠性和稳定性。我们需要持续关注 Nginx 的发展动态,不断学习和探索新的优化技术和方法,以应对未来 Web 服务领域的各种挑战。

相关文章:

Nginx 性能优化技巧与实践(二)

五、性能优化之负载均衡篇 5.1 负载均衡算法介绍 Nginx 作为一款强大的 Web 服务器和反向代理服务器,其负载均衡功能是提升 Web 服务性能和可靠性的关键。Nginx 支持多种负载均衡算法,每种算法都有其独特的原理和特点,适用于不同的业务场景…...

解密AIGC三大核心算法:GAN、Transformer、Diffusion Models原理与应用

在当今数字化时代,人工智能生成内容(AIGC)技术正以前所未有的速度改变着我们的生活和工作方式。从创意无限的文本生成,到栩栩如生的图像创作,再到动听的音乐旋律,AIGC的魔力无处不在。而这一切的背后&#…...

qml Dialog详解

1、概述 Dialog是QML(Qt Modeling Language)中用于显示对话框的组件,它提供了一个模态窗口,通常用于与用户进行重要交互,如确认操作、输入信息或显示警告等。Dialog组件具有灵活的布局和样式选项,可以轻松…...

GL C++显示相机YUV视频数据使用帧缓冲FBO后期处理,实现滤镜功能。

一.前言: GitHub地址:GitHub - wangyongyao1989/WyFFmpeg: 音视频相关基础实现 系列文章: 1. OpenGL Texture C 预览Camera视频; 2. OpenGL Texture C Camera Filter滤镜; 3. OpenGL 自定义SurfaceView Texture C预览Camera视…...

一文了解树与森林基础

文章目录 树和森林1树的存储结构1.1双亲表示法1.2孩子表示法1.3孩子兄弟表示法 2树、森林与二叉树的转换2.1森林与二叉树的转换2.2 树与二叉树的转换 3树和森林的遍历3.1树的遍历3.2森林的遍历3.3 树和森林的遍历与二叉树的遍历关系 4树的应用——并查集4.1并查集及其相关操作4…...

在Docker 容器中安装 Oracle 19c

在 Docker 容器中安装 Oracle 19c 是可行的,但它相较于其他数据库(如 MySQL、PostgreSQL 等)会复杂一些,因为 Oracle 数据库有一些特定的要求,如操作系统和库的依赖,以及许可证问题。 不过,Ora…...

Java TCP协议(2)

TCP可靠传输 五. 流量控制 用来控制发送方的窗口大小,通过接收方返回来的ACK进行反制。 接收方把自己能够处理的数据量主动告诉发送方,从而让发送方动态调整窗口大小。 如果窗口大小为0表示没有空间去接收数据了,主机A就不发数据了&#xf…...

JS基础-操作数组(7)

一.增删改查 1.改 重新赋值 2.增 arr.puch() 末尾追加 arr.unshift() 开头追加 a)案例:数组筛选 3.删除 arr.pop() 删除最后一个元素 arr.shift() 删除第一个元素 splice() 删除指定元素...

(长期更新)《零基础入门 ArcGIS(ArcScene) 》实验七----城市三维建模与分析(超超超详细!!!)

城市三维建模与分析 三维城市模型已经成为一种非常普遍的地理空间数据资源,成为城市的必需品,对城市能化管理至关重要。语义信息丰富的三维城市模型可以有效实现不同领域数据与IS相信息的高层次集成及互操作,从而在城市规划、环境模拟、应急响应和辅助决策等众多领域公挥作用、…...

大数据技术笔记

大数据技术概述 本章初步介绍大数据领域技术涉及的一些基础理论,如分布式、存储、网络等知识。 分布式理论 大数据意味数据量大,那么存储和计算数据的节点就不大可能只有一个,而是采用分而治之的思想在多个节点中存储和计算,提…...

【JAVA 基础 第(20)课】JDBC JAVA 连接 MySql 数据库

pom.xml 导入 MySql jar 包 <!-- 导入Mysql数据库链接jar包 --> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.30</version> </dependency> 数据库驱动、连接封装成…...

如何将使用unsloth微调的模型部署到ollama?

目录 一、将模型保存为gguf格式 二、下载llama.cpp 三、生成 llama-quantize 可执行文件 四、使用llama-quantize 五、训练模型 六、将模型部署到ollama 一、将模型保存为gguf格式 在你的训练代码 trainer.train() 之后添加&#xff1a; model.save_pretrained_gguf(&q…...

Go语言中的值类型和引用类型特点

一、值类型 值类型的数据直接包含值&#xff0c;当它们被赋值给一个新的变量或者作为参数传递给函数时&#xff0c;实际上是创建了原值的一个副本。这意味着对新变量的修改不会影响原始变量的值。 Go中的值类型包括&#xff1a; 基础类型&#xff1a;int&#xff0c;float64…...

grafana新增email告警

选择一个面板 比如cpu 新增一个临界点表达式 input选A 就是A的值达到某个临界点 触发告警 我这边IS ABOVE0.15就是cpu大于0.15%就触发报警&#xff0c;这个值怎么填看指标的值显示 这里要设置一下报警条件 这边随便配置下 配置标签和通知&#xff0c;选择你的邮件 看下告警…...

基于Spring Security 6的OAuth2 系列之六 - 授权服务器--自定义授权页面

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…...

MyBatis-Plus的插件

一、分页插件 1.自带的 启动类 在启动类里配置分页相关内容 package com.qcby;import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inne…...

基于Redis实现短信验证码登录

目录 1 基于Session实现短信验证码登录 2 配置登录拦截器 3 配置完拦截器还需将自定义拦截器添加到SpringMVC的拦截器列表中 才能生效 4 Session集群共享问题 5 基于Redis实现短信验证码登录 6 Hash 结构与 String 结构类型的比较 7 Redis替代Session需要考虑的问题 8 …...

HarmonyOS Next构建工具 lycium 原理介绍

HarmonyOS Next构建工具 lycium 原理介绍 背景介绍 HarmonyOS Next中很多系统API是以C接口提供&#xff0c;如果要使用C接口&#xff0c;必须要使用NAPI在ArkTS与C间交互&#xff0c;这种场景在使用DevEco-Studio中集成的交叉编译工具&#xff0c;以及cmake构建工具就完全够用…...

蓝桥杯例题一

不管遇到多大的困难&#xff0c;我们都要坚持下去。每一次挫折都是我们成长的机会&#xff0c;每一次失败都是我们前进的动力。路漫漫其修远兮&#xff0c;吾将上下而求索。只有不断努力奋斗&#xff0c;才能追逐到自己的梦想。不要害怕失败&#xff0c;害怕的是不敢去尝试。只…...

MySQL可直接使用的查询表的列信息

文章目录 背景实现方案模板SQL如何查询列如何转大写如何获取字符位置如何拼接字段 SQL适用场景 背景 最近产品找来&#xff0c;想让帮忙出下表的信息&#xff0c;字段驼峰展示&#xff0c;每张表信息show create table全部展示&#xff0c;再逐个粘贴&#xff0c;有点太耗费时…...

输入网址到网页显示,发生了什么--讲述

输入www.baidu.com作为网址&#xff0c; 孤身的人-HTTP 浏览器要做的第一步就是 解析URL&#xff0c;根据url里面的资源路径&#xff0c;确认服务器资源和路径&#xff0c;生成http请求消息&#xff0c;包括请求消息&#xff08;请求行 消息头 请求体&#xff09; 举例&am…...

npm install 报错:Command failed: git checkout 2.2.0-c

[TOC](npm install 报错&#xff1a;Command failed: git checkout 2.2.0-c) npm install 报错&#xff1a;Command failed: git checkout 2.2.0-c export NODE_HOME/usr/local/node-v14.14.0-linux-x64 npm config set registry https://registry.npmmirror.com 使用如上环…...

[Day 15]54.螺旋矩阵(简单易懂 有画图)

今天我们来看这道螺旋矩阵&#xff0c;和昨天发的题很类似。没有技巧&#xff0c;全是循环。小白也能懂~ 力扣54.螺旋矩阵 题目描述&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; …...

react antd点击table单元格文字下载指定的excel路径

在使用 Ant Design (antd) 的 Table 组件时&#xff0c;如果想点击表格单元格中的文字来触发下载指定路径的 Excel 文件&#xff0c;可以通过以下步骤实现&#xff1a; 1. 确保有一个可供下载的 Excel 文件&#xff1a;需要有一个服务器端点或者一个可以直接访问的 URL&#xf…...

什么是数据结构

数据结构 如何有效的存储数据。 数据存储方式 物理结构又称存储结构 在内存中存储状态&#xff0c;数据可以选择集中存放&#xff08;顺序存储结构&#xff09;&#xff0c;也可以选择分散存放&#xff08;链式存储结构&#xff09;。 逻辑结构 数据之间的逻辑关系&#…...

把 PVE 下的机械硬盘(非SSD系统盘)分配给虚拟机使用

PVE 挂在硬盘 参考 Ubuntu 24.04 LTS 空闲硬盘挂载到 文件管理器的 other locations。 在 PVE shell 中根据上面教程挂在硬盘 新建分享目录 参考 Proxmox VE&#xff08;PVE&#xff09;添加硬盘做存储 虚拟机新增硬盘 虚拟机 关机&#xff0c;按下图新增硬盘 新增硬盘…...

HTML5 Web Worker 的使用与实践

引言 在现代 Web 开发中&#xff0c;用户体验是至关重要的。如果页面在执行复杂计算或处理大量数据时变得卡顿或无响应&#xff0c;用户很可能会流失。HTML5 引入了 Web Worker&#xff0c;它允许我们在后台运行 JavaScript 代码&#xff0c;从而避免阻塞主线程&#xff0c;保…...

把网站程序数据上传到服务器的方法和注意事项

将网站程序数据上传到服务器是一个常见的网站开发和部署流程。主要涉及到FTP上传、FileZilla、rsync(在Linux下)、或其他相关的文件同步工具。以下是一般步骤和方法&#xff1a; 使用FTP&#xff1a; 1. 选择FTP客户端软件&#xff1a; - 常见的FTP客户端包括FileZilla(开源)、…...

YOLOv5训练自己的数据及rknn部署

YOLOv5训练自己的数据及rknn部署 一、下载源码二、准备自己的数据集2.1 标注图像2.2 数据集结构 三、配置YOLOv5训练3.1 修改配置文件3.2 模型选择 四、训练五、测试六、部署6.1 pt转onnx6.2 onnx转rknn 七、常见错误7.1 训练过程中的错误7.1.1 cuda: out of memory7.1.2 train…...

李沐vscode配置+github管理+FFmpeg视频搬运+百度API添加翻译字幕

终端输入nvidia-smi查看cuda版本 我的是12.5&#xff0c;在网上没有找到12.5的torch&#xff0c;就安装12.1的。torch&#xff0c;torchvision&#xff0c;torchaudio版本以及python版本要对应 参考&#xff1a;https://blog.csdn.net/FengHanI/article/details/135116114 创…...

Python 在Word中添加、或删除超链接

在Word文档中&#xff0c;超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超链接&#xff0c;用户可以轻松地导航到相关信息&#xff0c;从而增强文档的互动性和可读性。本文将介绍如何使用Python在Word中添加超链接、或删除Word文档中的超…...

在K8S中使用Values文件定制不同环境下的应用配置详解

在Kubernetes&#xff08;简称K8s&#xff09;环境中&#xff0c;应用程序的配置管理是一项关键任务。为了确保应用程序在不同环境&#xff08;如开发、测试、预发布和生产&#xff09;中都能稳定运行&#xff0c;我们需要为每个环境定制相应的配置。Values文件是在使用Helm管理…...

elementUI Table组件实现表头吸顶效果

需求描述 当 table 内容过多的时候&#xff0c;页面上滑滚动&#xff0c;表头的信息也会随着被遮挡&#xff0c;无法将表头信息和表格内容对应起来&#xff0c;需要进行表头吸顶 开始编码&#x1f4aa; 环境&#xff1a;vue2.6、element UI step1&#xff1a; 给el-table__h…...

JS-Web API -day06

一、正则表达式 正则表达式测试工具: http://tool.oschina.net/regex 1.1 正则表达式介绍与语法 正则表达式&#xff1a; 正则表达式&#xff08;Regular Expression&#xff09;是用于匹配字符串中字符组合的模式。在 JavaScript中&#xff0c;正则表达式也是对象。通常用来查…...

qml MenuItem详解

1、概述 MenuItem 是 QML&#xff08;Qt Modeling Language&#xff09;中用于表示菜单项的组件。它通常作为 Menu 组件的子项出现&#xff0c;用于提供用户可点击的菜单选项。MenuItem 可以包含文本、图标&#xff0c;甚至可以是其他 MenuItem 或 Menu 的容器&#xff0c;从而…...

汇编实验·系统调用

一、实验目的: 1.掌握基于特定操作系统中调用API或者SYSTEMCALL的基本方法。 2.进一步理解高级语言中函数调用的相关规定和约定(stdcall,cdec,fastcall等) 3.IA-32架构下API参数在汇编中的实现方式和约定。 二、实验内容 1.在课程设定的VS2022社区版的汇编开发环境下,完…...

ubuntu调用图形化网络测试工具

在 Ubuntu 中&#xff0c;除了命令行工具外&#xff0c;还有一些图形化的网络测试工具可以帮助你更直观地测试和分析网络性能。以下是几款常用的图形化网络测试工具及其使用方法&#xff1a; 1. gnome-nettool gnome-nettool 是一个简单的图形化网络工具集&#xff0c;包含 pi…...

【Qt】05-菜单栏

做菜单 前言一、创建文件二、菜单栏 QMenuBar2.1 示例代码2.2 运行结果 三、工具栏 QToolBar3.1 运行代码3.2 结果分析 四、状态栏 QStatusBar4.1 运行代码4.2 运行结果 五、文本编辑框 QTextEdit5.1 运行代码5.2 运行结果 六、浮动窗口 addDockWidget6.1 运行代码6.2 运行结果…...

Git知识分享

一、理解git首先要理清楚下面五个概念&#xff1a; 1、工作区(git add 命令之前的样子) 2、stash 暂存(暂存工作区和暂存区的更改) 3、暂存区(git add 命令之后的存储区, 4、本地仓库(git commit提交的位置) 5、远程仓库(git push提交的位置) 二、git常用命令&#xff1a; 1、g…...

细说STM32F407单片机电源低功耗StandbyMode待机模式及应用示例

目录 一、待机模式基础知识 1、进入待机模式 2、待机模式的状态 3、退出待机模式 二、待机模式应用示例 1、示例功能和CubeMX项目设置 &#xff08;1&#xff09; 时钟 &#xff08;2&#xff09; DEBUG、LED1、KeyRight、USART6、CodeGenerator &#xff08;3&#x…...

独立站运营新突破:Clock斗篷技术助力商家降本增效

一、引言 在当今竞争激烈的电商市场中&#xff0c;独立站运营已成为众多商家拓展业务、打造品牌的重要途径。然而&#xff0c;推广成本高企一直是困扰独立站商家的难题。许多商家在推广过程中&#xff0c;由于缺乏有效的策略&#xff0c;往往面临高昂的费用和有限的回报。但事实…...

【python】subprocess.Popen执行adb shell指令进入linux系统后连续使用指令,出现cmd窗口阻塞问题

问题描述 subprocess.Popen执行adb shell指令进入linux系统后出现cmd窗口阻塞问题&#xff0c;需要手动关闭cmd才会继续执行其他指令。 解决方案 1、cmd指令后面加入exit\n关闭exe进程 2、subprocess.Popen()添加内置参数creationflagssubprocess.CREATE_NO_WINDOW隐藏窗口弹…...

10天学会flutter DAY2 玩转dart 类

print(point.y); * 使用 ?. 代替. 可以避免因为左边表达式为null 而导致的问题 (这个是flutter 2.0 之后新增的空认证功能)print(point?.x); print(point?.y); * 如下代码所示p1.y 6; **setter** 写入方法, print(p1.y); **getter** 读取方法p1.y 6; print(p1.y); […...

【C++】string类模拟实现

目录 &#x1f495;1.模拟string类构造函数 &#x1f495;2.模拟构造函数实现 &#x1f495;3.拷贝构造函数模拟实现 &#x1f495;4.析构函数模拟实现 &#x1f495;5.size函数&#xff0c;capacity函数模拟实现 &#x1f495;6.begin函数,end函数&#xff0c;模拟实…...

2025发文新方向:AI+量化 人工智能与金融完美融合!

2025深度学习发论文&模型涨点之——AI量化 人工智能的融入&#xff0c;使量化交易实现了质的突破。借助机器学习、深度学习等先进技术&#xff0c;人工智能可高效处理并剖析海量市场数据&#xff0c;挖掘出数据背后错综复杂的模式与趋势&#xff0c;从而不仅提升了数据分析…...

eniops库中reduce函数使用方法

reduce 是 eniops 中的一个常用函数&#xff0c;用于对张量进行降维操作。它允许你通过指定维度名称和操作类型&#xff08;如求和、均值等&#xff09;来简化张量的形状。 import eniops import torch# 创建一个示例张量 x torch.randn(2, 3, 4)# 使用 reduce 进行降维操作 …...

第03章 02 VTK中的智能指针

在VTK&#xff08;Visualization Toolkit&#xff09;中&#xff0c;智能指针用于管理对象的生命周期&#xff0c;避免内存泄漏和悬空指针等问题。VTK提供了几种不同类型的智能指针&#xff0c;包括vtkNew、vtkSmartPointer和vtkWeakPtr。以下是它们的区别和作用&#xff1a; …...

03垃圾回收篇(D4_彻底理解GC)

目录 一、浅析大促备战过程中出现的 fullGc&#xff0c;我们能做什么&#xff1f; 1. 什么是 JVM 的 GC? 2. 写代码的时候能做什么&#xff1f; 3. 测试能做啥 4. 知识小结 二、MinorGC、MajorGC、FullGC垃圾回收介绍 1. MinorGC &#xff08;新生代垃圾回收&#xff09…...

C语言小项目——通讯录

功能介绍&#xff1a; 1.联系人信息&#xff1a;姓名年龄性别地址电话 2.通讯录中可以存放100个人的信息 3.功能&#xff1a; 1>增加联系人 2>删除指定联系人 3>查找指定联系人的信息 4>修改指定联系人的信息 5显示所有联系人的信息 6>排序&#xff08;名字&…...

MyBatis和JPA区别详解

文章目录 MyBatis和JPA区别详解一、引言二、设计理念与使用方式1、MyBatis&#xff1a;半自动化的ORM框架1.1、代码示例 2、JPA&#xff1a;全自动的ORM框架2.1、代码示例 三、性能优化与适用场景1、MyBatis&#xff1a;灵活的SQL控制1.1、适用场景 2、JPA&#xff1a;开发效率…...