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

【Nginx20】Nginx学习:FastCGI模块(二)缓存配置

Nginx学习:FastCGI模块(二)缓存配置

通过上篇文章的学习,普通的 PHP 与 Nginx 的连接就已经没啥大问题了。一般的网站直接那套配置就够了,这也是 Nginx 非常友好的一面。很多在默认的配置文件中注释掉的内容,只要打开就是可以直接使用的。不过,FastCGI 可不是一个小模块,还有很多的配置指令,要想深入,要想调优,这些指令还是多少要了解一下的。

今天学习的内容基本上也都是可以设置在 http、server、location 中的,有特殊情况的我会单独说。

FastCGI缓存配置

是的,你没看错,FastCGI 也有缓存系统,但它走的是文件缓存。通过之前的学习,我们知道 Nginx 对静态文件的优化还是相当强悍的,因此,文件缓存的效率并不低。

对于动态网站来说,如果走 UnixSocket ,其实网络开销不大,而且即使是走端口请求的 FastCGI ,通常也是本地部署,对于动态语言来说不会有太大的性能影响。当然,如果你使用的是 Laravel 这种重型框架,即使啥都不做,也是有一些性能损耗的。如果再加上数据库读写或者其它 IO 操作的话,性能还会进一步下降。通常来说我们会怎么做呢?上 Redis 做缓存。是的,这没问题,不过 Nginx 的 FastCGI 缓存也值得一试,起码不用再装第三方组件了。

我们先来看一套配置。

首先,需要在 http 模块下定义缓存路径。

// http 下面,不能放在 server 或者 location 下
fastcgi_cache_path cache levels=1:2 keys_zone=fcgi:10m;

先不用管参数是啥意思,现在你只要知道第一个参数是指定缓存文件存放的路径就好了。这个路径可以是相对也可以是绝对路径,现在我们配的是相对路径,默认就会是程序运行目录下新建一个 cache 目录。我这里就是 /usr/local/nginx/cache 。

然后进行缓存相关的配置。

location ^~ /fastcgi2/ {alias html/fastcgi1/;fastcgi_pass unix:/var/sock/php-fpm/www.sock;fastcgi_index  index.php;fastcgi_param  SCRIPT_FILENAME $request_filename;include        fastcgi_params;fastcgi_cache fcgi;fastcgi_cache_valid 200 302 301 5m;fastcgi_cache_valid any 1m;fastcgi_cache_key fgi$request_method://$host$request_uri;
}

上半部分没什么新鲜的,不过有一点,我们使用了 alias ,并且将 SCRIPT_FILENAME 设置为 $request_filename 了,其实就是想使用文章中的 fastcgi1 这个目录。

然后加了三个 fastcgi_cache 相关的配置,暂时也不用管它,我们后面会一个一个地介绍,先看效果。

现在重载配置,并且访问 /fastcgi2/1.php?c=1 。结果正常,不急,先看下目录情况。

ll /usr/local/nginx/cache/7/31/
total 4
-rw------- 1 www www 1598 Aug 24 10:36 72116ad9a0fa863d35002f652d3b2317

目录生成了,还有一个缓存文件也出现了。接着,查看一下文件内容。

^E^@^@^@^@^@^@^@??^Ec^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@????????N^Ec^@^@^@^@?y7?^@^@?^A?^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
KEY: fcgiGET://192.168.56.88/fastcgi2/1.php?c=1
^A^F^@^A^D?^C^@X-Powered-By: PHP/7.2.24^M
Content-type: text/html; charset=UTF-8^M
^M
Array
([USER] => www[HOME] => /home/www[HTTP_COOKIE] => a=123; b=321[HTTP_CONNECTION] => keep-alive[HTTP_ACCEPT_ENCODING] => gzip, deflate, br[HTTP_HOST] => 192.168.56.88[HTTP_POSTMAN_TOKEN] => 09d5caca-7903-458e-b181-9f8c5b3e2520[HTTP_ACCEPT] => */*[HTTP_USER_AGENT] => PostmanRuntime/7.29.2[REDIRECT_STATUS] => 200[SERVER_NAME] => core.nginx.test[SERVER_PORT] => 80
……………………
……………………

上面一堆乱码,下面有个 Key 信息,然后是响应头信息,最后是正常返回的响应体内容。没错,就是我们所请求的页面的内容。

接下来,尝试修改 /fastcgi1/1.php 文件,然后再次请求,你会发现返回的结果不会有什么变动了,这就是缓存生效了。啥时候失效呢?等 5 分钟,也就是 fastcgi_cache_valid 配置项定义的时间,或者添加一个条件可以不走缓存,比如:

fastcgi_cache_bypass $arg_nocache;

$arg_[name] 变量还记得是啥吧,这样我们再次访问页面,添加一个 GET 参数 nocache ,随便给一个非 0 值,就不会走缓存了。想要清除缓存怎么办?抱歉,这是商业版的功能,也就是 fastcgi_cache_purge指令提供的功能,我们没法用,要想像 Redis 一样可以删除,要么手动去删除缓存目录,要么使用第三方模块比如 ngx_cache_purge

好了,一套简单的配置就完成了。不过 FastCGI 的缓存模块所拥有的配置指令远不止这些,我们接下来就一个一个详细地学习一下。

fastcgi_cache_path

设置缓存的路径和其他参数,只能配置在 http 模块中。

fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [min_free=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];

缓存数据会存储在这个配置所指定的目录的文件中。缓存中的键名和文件名都是将 MD5 函数应用于代理 URL 的结果。 levels 参数定义缓存的层次级别:从 1 到 3,每个级别接受值 1 或 2。它和后面我们会学到的 log_format 比较像,都必须在 http 中定义,而且可以通过不同的名字定义多个,后面要用的时候指定名称就行了。在这个配置中就是 keys_zone 这个参数,表示共享内存区域。所有活动密钥和有关数据的信息都存储在共享内存区域中,其名称和大小由 keys_zone 参数配置。一兆字节的区域可以存储大约 8000 个密钥。如果是商业版本,共享内存区域还存储扩展缓存信息,因此,需要为相同数量的键指定更大的区域大小。例如,一兆字节的区域可以存储大约 4000 个密钥。

第一个参数 path 就是路径,这个是需要我们指定的,这个配置项没有默认值,不配置 fastcgi_cache_path ,后面的 fastcgi_cache 就没法用,整个缓存功能也就无法使用。缓存中最终存储的完整文件名就像是我们上面看到的:

/usr/local/nginx/cache/7/31/72116ad9a0fa863d35002f652d3b2317

缓存的响应会首先写入临时文件,然后重命名该文件到指定的缓存目录。从 0.8.9 版本开始,临时文件和缓存可以放在不同的文件系统上。但是,请注意,在这种情况下,文件是跨两个文件系统复制的,而不是廉价的重命名操作。因此,建议对于任何给定位置,缓存和保存临时文件的目录都放在同一个文件系统上。根据 use_temp_path 参数 (1.7.10) 设置临时文件的目录。如果此参数被省略或设置为值 on,将使用由 fastcgi_temp_path 指令为给定位置设置的目录。如果该值设置为 off,则临时文件将直接放在缓存目录中。 这个指令我们将在下篇文章中学习到。

在 inactive 参数指定的时间内未访问的缓存数据将从缓存中删除,无论其新鲜度如何。默认情况下,非活动设置为 10 分钟。

特殊的“缓存管理器”进程监控由 max_size 参数设置的最大缓存大小,以及由 min_free (1.19.1) 参数设置的带缓存文件系统上的最小可用空间量来决定。当超出大小或没有足够的可用空间时,它会删除最近最少使用的数据。数据在 manager_files、manager_threshold 和 manager_sleep 参数 (1.11.5) 配置的迭代中被删除。在一次迭代中,最多删除 manager_files 个项目(默认为 100)。一次迭代的持续时间受 manager_threshold 参数的限制(默认为 200 毫秒)。在迭代之间,由 manager_sleep 参数配置的暂停(默认为 50 毫秒)。

启动后一分钟,特殊的“缓存加载器”进程被激活。它将有关存储在文件系统上的先前缓存数据的信息加载到缓存区域中。加载也是在迭代中完成的。在一次迭代中,最多加载 loader_files 个项目(默认情况下,100 个)。此外,一次迭代的持续时间受 loader_threshold 参数的限制(默认为 200 毫秒)。在迭代之间,由 loader_sleep 参数配置的暂停(默认为 50 毫秒)。

最后,其它的一些参数都是商业版的,没法用,也没法测,不讨论了。我们直接来看看多配置一个,然后将前面的例子换成新的路径配置。

// http下
fastcgi_cache_path cache1 use_temp_path=on levels=1 keys_zone=fff:1m;// fastcgi2 的 location 下
fastcgi_cache fff;
fastcgi_cache_key fff$request_method://$host$request_uri;

重载配置后,看看新的缓存文件是不是生成到了 cache1 目录下了。这里有两个小问题需要注意下:

  • 原来那个 fastcgi_cache_path 不用删,和 log_format 一样,同时配置多个,只要名称不同就行了

  • fastcgi_cache_key 需要稍做修改,它是决定缓存 key 的,如果不改,还会走原来的缓存

fastcgi_cache

定义用于缓存的共享内存区域。

fastcgi_cache zone | off;

默认值是 off ,就是上面那个配置中 keys_zone 所定义的共享区域名称。同一个区域可以在多个地方使用。参数值可以包含变量 (1.7.9)。 off 参数禁用从先前配置级别继承的缓存。

最主要的作用就是表明当前的 server 或 location 使用哪个缓存路径配置,或者在 http 下定义一个全局的也可以。

fastcgi_cache_background_update

允许启动后台子请求以更新过期的缓存项,同时将过时的缓存响应返回给客户端。

fastcgi_cache_background_update on | off;

默认是关闭的,请注意,有必要在更新时允许使用陈旧的缓存响应。

fastcgi_cache_bypass

定义不从缓存中获取响应的条件。

fastcgi_cache_bypass string ...;

没有默认值,上面我们已经用过啦,其实它的意思是如果字符串参数中至少有一个值不为空且不等于“0”,则不会从缓存中获取响应:

fastcgi_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
fastcgi_cache_bypass $http_pragma    $http_authorization;

这两行有点复杂了吧,其实是一样的意思,cookie 或请求参数中有 nocache 字段,或者请求头有 Pragma 或 Authoriaztion ,并且这些字段都不是空或0的时候,就不走缓存,前面我们演示过效果啦。它可以与 fastcgi_no_cache 指令一起使用。

fastcgi_cache_key

定义一个用于缓存的键。

fastcgi_cache_key string;

上面也已经用过了,并且还提到注意的地方了,一般来说,请求地址加 URI 就够了,不过最好再加上请求方法以及你可能需要的字段拼接成一个字符串就好了。

fastcgi_cache_lock

启用后,一次只允许一个请求通过将请求传递给 FastCGI 服务器来填充根据 fastcgi_cache_key 指令标识的新缓存元素。

fastcgi_cache_lock on | off;

默认值 off ,其实就是缓存过期后,如果有多个相同缓存元素的请求同时到达,要怎么处理,就像更新 Redis 时如果多个请求到达会产生击穿问题一样,这里也是加锁来解决。相同缓存元素的其他请求要么等待响应出现在缓存中,要么等待释放该元素的缓存锁,直到由 fastcgi_cache_lock_timeout 指令设置的时间。

fastcgi_cache_lock_age

如果传递给 FastCGI 服务器以填充新缓存元素的最后一个请求在指定时间内未完成,则可以将另一个请求传递给 FastCGI 服务器。

fastcgi_cache_lock_age time;

默认值 5s 。

fastcgi_cache_lock_timeout

为 fastcgi_cache_lock 设置超时。

fastcgi_cache_lock_timeout time;

默认值 5s ,当时间到期时,请求将被传递到 FastCGI 服务器,但是,响应不会被缓存。在 1.7.8 之前,可以缓存响应。

fastcgi_cache_max_range_offset

为字节范围请求设置字节偏移量。

fastcgi_cache_max_range_offset number;

如果范围超出偏移量,范围请求将被传递到 FastCGI 服务器,并且响应不会被缓存。

fastcgi_cache_methods

如果此指令中列出了客户端请求方法,则响应将被缓存。

fastcgi_cache_methods GET | HEAD | POST ...;

“GET”和“HEAD”方法总是添加到列表中,但建议明确指定它们。另请参见 fastcgi_no_cache 指令。

这个好测,可以先删了缓存文件,然后使用 POST 请求我们之前的测试文件,就会发现没有缓存文件产生。这时配置一条这个指令加上 POST ,缓存就正常生效了。

fastcgi_cache_min_uses

设置将缓存响应的请求数。

fastcgi_cache_min_uses number;

默认值 1 ,意思就是,只要有一条请求来了,就缓存,一般不用改它。

fastcgi_cache_purge

定义将请求视为缓存清除请求的条件。

fastcgi_cache_purge string ...;

商业版本提供的,咱们没有。

fastcgi_cache_revalidate

使用带有“If-Modified-Since”和“If-None-Match”标头字段的条件请求启用过期缓存项的重新验证。

fastcgi_cache_revalidate on | off;

默认值 off ,就是通过请求头中的 HTTP 缓存相关字段来做为缓存的更新依据,需要我们 PHP 代码中添加响应头及处理,我没测试也没写了,如果哪天有需要再试试。

fastcgi_cache_use_stale

确定在与 FastCGI 服务器通信期间发生错误时可以使用陈旧缓存响应的情况。

fastcgi_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_503 | http_403 | http_404 | http_429 | off ...;

默认值是 off ,这个指令的参数与 fastcgi_next_upstream 指令的参数相匹配。如果无法选择用于处理请求的 FastCGI 服务器,则错误参数还允许使用过时的缓存响应。此外,如果当前正在更新,更新参数允许使用陈旧的缓存响应。这允许在更新缓存数据时最大限度地减少对 FastCGI 服务器的访问次数。

在响应过时 (1.11.10) 后的指定秒数内,也可以直接在响应标头中启用使用过时的缓存响应。这比使用指令参数的优先级低。

  • 如果当前正在更新,则“Cache-Control”标头字段的“stale-while-revalidate”扩展允许使用过时的缓存响应。

  • “Cache-Control”标头字段的“stale-if-error”扩展允许在发生错误时使用过时的缓存响应。

为了在填充新缓存元素时尽量减少对 FastCGI 服务器的访问次数,可以使用 fastcgi_cache_lock 指令。

看明白了吗?是不是一脸懵B?其实我们只需要设置一个 fastcgi_cache_use_stale http_500 来进行测试,首先正常访问页面生成缓存后,修改测试用的 PHP 文件,throw 一个异常,这样就会返回 500 了,然后等缓存时间过了,会发现页面依然还可以正常打开。这就是它的作用,当然,并不是说不报错了,错误信息会显示在日志中,但前台依然会返回缓存中的正常内容。

2022/08/25 08:42:13 [error] 1419#0: *7 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Exception

fastcgi_cache_valid

为不同的响应代码设置缓存时间。

fastcgi_cache_valid [code ...] time;

这个命令我们已经使用过了,例如,以下指令

fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 404      1m;

表示的就是为代码为 200 和 302 的响应设置 10 分钟的缓存时间,为代码为 404 的响应设置 1 分钟的缓存时间。

如果只指定缓存时间

fastcgi_cache_valid 5m;

那么只有 200、301 和 302 响应被缓存。

此外,可以指定 any 参数来缓存任何响应:

fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 301      1h;
fastcgi_cache_valid any      1m;

缓存的参数也可以直接在响应头中设置。这比使用指令设置缓存时间具有更高的优先级。

  • “X-Accel-Expires”标头字段设置响应的缓存时间(以秒为单位)。零值禁用响应缓存。如果该值以 @ 前缀开头,则它设置自 Epoch 以来的绝对时间(以秒为单位),直到可以缓存响应。

  • 如果头部不包含“X-Accel-Expires”字段,可以在头部字段“Expires”或“Cache-Control”中设置缓存参数。

  • 如果标头包含“Set-Cookie”字段,则不会缓存此类响应。

  • 如果标头包含具有特殊值“*”的“Vary”字段,则不会缓存此类响应(1.7.7)。如果标头包含具有另一个值的“Vary”字段,则将考虑相应的请求标头字段(1.7.7)缓存此类响应。

可以使用 fastcgi_ignore_headers 指令禁用对这些响应头字段中的一个或多个的处理。

最后这个响应头的设置我们可以单独测试一下,在 PHP 文件中,设置一个头 header("X-Accel-Expires: 60"); ,设置之前缓存键的 fastcgi_cache_valid 对于 200 是使用 any ,并且缓存 15s ,在添加了响应头后,可以测试 15秒后不会更新缓存,而是要等到 1分钟 后才更新的。响应头的优先级确实更高。

fastcgi_no_cache

定义不将响应保存到缓存的条件。

fastcgi_no_cache string ...;

如果字符串参数中至少有一个值不为空且不等于“0”,则不会保存响应,和 fastcgi_cache_bypass 配置方式类似的,那个是即使有缓存文件也不走缓存,这个是完全不生成缓存文件。

总结

又是涨姿势的一天吧,原来我还真不知道有这个功能,很多东西在系统学习之前确实都不会了解得太深入。特别是现在各种方便的工具帮我们配置网站之后,更是很少人会去仔细查看文档中的内容。

不过话说回来,真正在使用动态语言进行缓存时,其实让动态语言自身去处理还是更方便一些,比如我们在这里就看到更新缓存或者删除缓存还是比较费劲的,不像 Redis 之类的非常简单,而且 Redis 走内存,速度比硬盘缓存可能还更占优势。使用 Nginx 缓存最大的好处还是减少一次内部的 CGI 调用。因此,如何使用,什么场景,还是要看具体的业务情况了。

参考文档:

http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html

相关文章:

【Nginx20】Nginx学习:FastCGI模块(二)缓存配置

Nginx学习:FastCGI模块(二)缓存配置 通过上篇文章的学习,普通的 PHP 与 Nginx 的连接就已经没啥大问题了。一般的网站直接那套配置就够了,这也是 Nginx 非常友好的一面。很多在默认的配置文件中注释掉的内容&#xff0…...

苹果支付外包开发流程

苹果支付的实现流程主要涉及集成苹果的支付系统——Apple Pay,以及在你的应用中处理支付交易。以下是一个简要的实现流程概述,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.开发者账号…...

银河麒麟V10(Tercel)服务器版安装 Docker

一、服务器环境 ## 查看系统版本,确认版本 cat /etc/kylin-release Kylin Linux Advanced Server release V10 (Tercel)## 操作系统 uname -p aarch64## 内核版本(≥ 3.10) uname -r 4.19.90-21.2.ky10.aarch64## iptables 版本(…...

web、HTTP协议

目录 一、Web基础 1.1 HTML概述 1.1.1 HTML的文件结构 1.2 HTML中的部分基本标签 1.3 URI 和 URL 二.HTTP协议 2.1.HTTP概念 2.2.HTTP协议版本 2.3.HTTP请求方法 2.4.HTTP请求访问的完整过程 2.5.HTTP状态码 2.6.HTTP请求报文和响应报文 2.7.HTTP连接优化 三.HTT…...

达梦SQL书写注意事项

模糊查询 模糊查询like后面的字段要求用单引号引用,不能使用双引号 select * from user where name like %小组 分组查询 select查询的列字段必须在分组中的字段存在 正确: select name,age from user group by name,age 错误: select * f…...

博途1200脉冲输出控制速度轴(轴工艺对象基本配置)

这里的1200脉冲轴,主要用来完成线缆包材绕包时的重叠率控制。关于重叠率的具体概念,这里不再阐述,大家可以看下面的文章链接, 重叠率控制 重叠率控制(算法详细介绍含SCL和梯形图源代码)_RXXW_Dor的博客-CSDN博客产品包装和线缆保护材料的包覆都需要进行材料包装重叠率的控…...

微信小程序 通过setData 给两个变量设置同一个数组时,为什么修改一个变量,另一个会也被修改?

在微信小程序中,使用 setData 方法更新数据时,如果给两个变量设置同一个数组,修改其中一个变量的值会导致另一个变量也被修改的原因是,数组是引用类型的数据,在内存中的存储方式是按引用地址存储。 当你将一个数组赋值…...

保障Web安全:构建可靠的网络防御体系

在当今数字化时代,Web安全已成为互联网世界中至关重要的议题。随着网络攻击手段的不断演进和网络犯罪的增加,保护用户数据和确保系统安全性已成为任何Web应用程序的首要任务。本文将深入探讨Web安全的重要性以及构建可靠的网络防御体系的关键要素。我们将…...

LeetCode--HOT100题(44)

目录 题目描述:230. 二叉搜索树中第K小的元素(中等)题目接口解题思路代码 PS: 题目描述:230. 二叉搜索树中第K小的元素(中等) 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你…...

大模型调试debug记录

环境:Linux , cuda 11.7 RuntimeError: Distributed package doesnt have NCCL built in 原因:pytorch安装的是cpu版本,需要安装支持gpu版本的 RuntimeError: Distributed package doesnt have NCCL built in - #3 by bdabykov - distrib…...

对话谷歌首席技术官肖恩,搜索引擎的里程碑,来看看搜索引擎界的大哥Algolia的“快、准、狠”突围关键

原创 | 文 BFT机器人 人物背景 Character Background Sean Mullaney是Algolia(端到端人工智能搜索和发现平台)的首席技术官,也是前 Stripe和谷歌高管,拥有扩展工程组织、开发人工智能驱动的搜索和发现工具以及在全球范围内发展A…...

DP读书:鲲鹏处理器 架构与编程(十二)鲲鹏软件实战案例

10min速通了解鲲鹏软件实战案例 云服务器源码移植与编译配置云服务器Porting Advisor代码移植搭建交叉编译环境x86云服务器交叉编译 OpenSSL鲲鹏云服务器上编译 OpenSSL Docker的安装与应用安装DockerDocker运行与验证Docker常用命令卸载Docker安装适配鲲鹏架构的Docker镜像 KV…...

前端 -- 基础 VSCode 工具生成骨架标签新增代码 解释详解

目录 文档类型声明标签 Lang 语言种类 字符集 文档类型声明标签 <!DOCTYPE> 文档类型声明&#xff0c;作用就是告诉浏览器 当前的页面是 使用哪种 HTML 版本 来显示的网页 HTML 版本也很多呀 &#xff0c;比如 &#xff1a; HTML5 ,HTML4&#xff0c;XHTML 等…...

爬虫逆向实战(二十三)--某准网数据

一、数据接口分析 主页地址&#xff1a;某准网 1、抓包 通过抓包可以发现数据接口是api_to/search/company_v2.json 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过查看“载荷”模块可以发现b参数和kiv参数是加密参数 请求头是否加密&#xff1f; 无响应是否加…...

ruoyi--数据权限

这篇文章我先和大家分析一下 RuoYi-Vue 脚手架中 DataScope 注解的实现原理&#xff0c;在 TienChin 项目视频中到时候还会有深入讲解。 1. 思路分析 首先我们先来捋一捋这里的权限实现的思路。 DataScope 注解处理的内容叫做数据权限&#xff0c;就是说你这个用户登录后能够…...

快速开发平台是什么?和传统开发平台相比有哪些区别?

本文可以从【快速开发平台的价值、和传统平台的区别、使用感受】三个方面来说明。 首先&#xff0c;我们要清楚快速开发平台是什么&#xff1a; 快速开发平台也称为低代码或无代码平台&#xff0c;旨在通过可视化工具、拖放式界面和预构建组件&#xff0c;使应用程序的开发过…...

Android基于JNI的Java与C++互调

java调用C++: #include <jni.h> //导出c函数格式 extern "C" JNIEXPORT //供JNI调用 JNICALL 函数名格式 Java_包名_类名_函数名(包名.替换为_) Java_com_example_getapplist_MainActivity_stringFromJNI 包名:com_example_getapplist 类名:MainActi…...

【算法与数据结构】513、LeetCode找树左下角的值

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;这道题用层序遍历来做比较简单&#xff0c;最底层最左边节点就是层序遍历当中最底层元素容器的第一个值…...

React——组件缓存 react-activation

1、安装依赖 npm i -S react-activation 2、包裹根组件 import { AliveScope } from "react-activation"<AliveScope><App /> </AliveScope> 3、缓存组件 import { KeepAlive } from "react-activation"export default () > {co…...

EV代码签名证书是什么?

在数字世界中&#xff0c;很多软件和应用都需要进行代码签名&#xff0c;以确保其来源可靠和安全&#xff0c;EV代码签名证书恰好都能做到&#xff0c;那么EV代码签名证书是什么&#xff1f;它有什么功能特点呢&#xff1f;下面的内容可以给到答案。 EV代码签名证书是什么&…...

融媒行业落地客户旅程编排,详解数字化用户运营实战

移动互联网时代是流量红利的时代&#xff0c;企业常用低成本的方式进行获客&#xff0c;“增长黑客”的概念大范围传播。与此同时&#xff0c;机构媒体受到传播环境的影响&#xff0c;也开始启动全行业的媒体融合转型。在此背景下&#xff0c;2015 年神策数据成立&#xff0c;核…...

PDF制作成翻页电子书

在日常工作中&#xff0c;大部分人使用的都是PDF文档发送给客户&#xff0c;但是PDF文档通常是静态的&#xff0c;缺乏交互性和视觉吸引力。那你有没有想过把它转换成翻页的电子书呢&#xff1f; 小编将告诉你操作步骤&#xff0c;非常简单 1.搜索FLBOOK在线制作电子杂志平台 …...

多线程

1. 线程池 1.1 线程状态介绍 当线程被创建并启动以后&#xff0c;它既不是一启动就进入了执行状态&#xff0c;也不是一直处于执行状态。线程对象在不同的时期有不同的状态。那么Java中的线程存在哪几种状态呢&#xff1f;Java中的线程 状态被定义在了java.lang.Thread.Stat…...

BingChat与ChatGPT比较,哪个聊天机器人能让你获益更多?

人工智能领域的最新进展为普通人创造新的收入来源提供了更多机会。今年早些时候&#xff0c;微软对OpenAI进行了大量投资。此后&#xff0c;微软在Microsoft Edge浏览器中推出了自家的聊天机器人Bing Chat。 在论坛和社交媒体上&#xff0c;你可以发现这两个AI工具都吸引了很…...

Qt读写ini配置文件(QSettings)、XML

1、ini相关的 总结&#xff1a;Qt读写ini配置文件(QSettings) - 布丁Plus - 博客园 (cnblogs.com) Qt读写ini文件&#xff08;含源码注释&#xff09;_qt ini文件读写_lw向北.的博客-CSDN博客 2、XML相关的 Qt读写XML文件&#xff08;含源码注释&#xff09;_qt写xml_lw向北…...

JVM知识点(二)

1、G1垃圾收集器 -XX:MaxGCPauseMillis10&#xff0c;G1的参数&#xff0c;表示在任意1s时间内&#xff0c;停顿时间不能超过10ms&#xff1b;G1将堆切分成很多小堆区&#xff08;Region&#xff09;&#xff0c;每一个Region可以是Eden、Survivor或Old区&#xff1b;这些区在…...

代码随想录算法训练营day44 | LeetCode 518. 零钱兑换 II 377. 组合总和 Ⅳ

今晚学习了完全背包的做法&#xff0c;和01背包的差别具体来说就是一个可以重复&#xff0c;一个不可以重复。体现在数组的遍历中来说就是完全背包不能用二维数组做法&#xff08;因为二维dp数组一定不会重复&#xff0c;但是还没验证过&#xff09;&#xff0c;只能用一维dp数…...

Vue2向Vue3过度核心技术工程化开发和脚手架

目录 1 工程化开发和脚手架1.1 开发Vue的两种方式1.2.脚手架Vue CLI 2 项目目录介绍和运行流程2.1 项目目录介绍2.2 运行流程 3 组件化开发4 根组件 App.vue4.1 根组件介绍4.2 组件是由三部分构成4.3 总结 5 普通组件的注册使用-局部注册5.1 特点&#xff1a;5.2 步骤&#xff…...

Expected all tensors to be on the same device, but found at least two devices

Expected all tensors to be on the same device, but found at least two devices, 原因是计算的过程中&#xff0c;两个不同类型的变量在一起进行运算&#xff0c;即一个变量存储在gpu中&#xff0c;一个变量存储在cpu中&#xff0c;两个变量的存储位置冲突&#xff0c;导致无…...

Mysql备份命令Mysqldump导入、导出以及压缩成zip、gz格式

1、导出 命令&#xff1a;mysqldump -u用户名 -p数据库密码 数据库名 > 文件名 如果用户名需要密码&#xff0c;则需要在此命令执行后输入一次密码核对&#xff1b;如果数据库用户名不需要密码&#xff0c;则不要加“-p”参数&#xff0c;导入的时候相同。注意输入的用户名…...