nginx 简单实践:静态资源部署、URL 重写【nginx 实践系列之一】

〇、前言

本文为 nginx 简单实践系列文章之一,主要简单实践了两个内容:静态资源部署、重写,仅供参考。

关于 Nginx 基础,以及安装和配置详解,可以参考博主过往文章:

https://www.cnblogs.com/hnzhengfy/p/Nginx.html 

一、静态资源部署

当前项目的结构基本上都是前后端分离,前端的相关资源,如 html,js,css 或者图片,变更频率比较低但访问量比较大,若想保证系统性能,可以将这些文件放在指定目录下,通过 nginx 的 root 或 alias 配置方式来指定静态资源的路径。

基于高并发高性能的 ningx,用户就可以通过域名加路径的方式,高效快速的进行页面访问。

下面是一个简单的示例。

nginx 配置示例(部分):

server {listen       8080;  # 绑定端口server_name  localhost;charset utf-8;  # 指定字符集,不然 html 文件中的汉字会乱码location /test {  # 路径匹配规则alias  /usr/tmp/test; # 别名,将当期路径对应到新的目录中index  index.html index.htm;}location /test_2 {  # 路径匹配规则alias  /usr/tmp/test/test_2; # 别名,将当期路径对应到新的目录中index index.html index.htm;}
}

示例文件示例,文件位置为 /usr/tmp:

/usr/tmp/test/test_page.html

/usr/tmp/test/test_2/test_2_page.html

/usr/tmp/test/test_2/westlage.jpg

测试结果如下图:

参考:https://www.cnblogs.com/qingshan-tang/p/12763522.html

二、Rewrite:URL 重写

2.1 简介

rewrite 就是 URL 重写,是一个将传入的 web 重定向到其他 URL 的过程。

上一部分静态资源部署,主要用的是 location 相关配置来实现静态资源的直接访问,下面先看下 rewrite 和 location 的区别。

  • rewrite 和 location 比较

rewrite 更侧重于 URL 路径的重写和跳转,而 location 则侧重于请求路径的匹配和处理。在实际使用中,两者往往结合使用,以实现复杂的请求处理逻辑。

功能目的

rewrite 主要用于重写 URL 路径,可以实现内部跳转(不改变浏览器地址栏的URL)或外部跳转(使用 redirect 标志时),通常用于在同一域名内更改获取资源的路径

location 用于匹配请求的 URL 路径,本身不实现跳转,而是对匹配到的路径进行相应的处理,如访问控制、反向代理或静态资源服务。

配置位置

rewrite 只能放在 server {}, location {}, if {} 中,并且只能对域名后边的除去传递的参数外的字符串起作用。

location 作为 server {} 块中的一个指令,可以基于请求字符串、虚拟主机名称(IP或域名)和URL进行匹配。

执行顺序

rewrite 在 server 块中的 rewrite 指令会首先执行,然后是 location 匹配,最后是 location 块中的 rewrite 指令。

location 直接根据请求的 URL 路径进行匹配,一旦匹配成功,就会执行对应的处理逻辑。

2.2 rewrite 的优势

  • 隐藏真实目录结构:通过隐藏服务器上的真实文件路径和目录结构,防止攻击者通过直接访问文件路径来获取敏感信息。
  • 规范化 URL:强制规范化 URL 格式既可以避免一些常见的安全漏洞,如路径遍历攻击(Directory Traversal)或路径参数欺骗等等,又可以保证 URL 格式的一致性。
  • 防止盗链:通过 Rewrite 可以实施防盗链策略,防止其他网站直接链接到本站的资源。这有助于减轻服务器负载,防止不法分子盗用网站的带宽,并提高资源的安全性。
  • HTTP 到 HTTPS 的强制重定向:可以确保数据在传输过程中的安全性。这是保障通信安全的一种有效手段,尤其对于涉及用户敏感信息的网站至关重要
  • 条件性重写:可以根据请求中的条件来选择是否进行重写,有助于实现访问控制和强化安全性。例如,只有特定 IP 范围的请求才允许进行某种操作。
  • 跨站点脚本(XSS)防护:Rewrite 可以对请求参数进行过滤或修改,防止恶意用户通过注入脚本来进行 XSS 攻击。对 URL 和参数进行适当的重写可以减轻 XSS 攻击的风险。
  • 统一资源标识符(URI)规范化:通过强制规范化 URI,可以防止攻击者尝试混淆或绕过安全策略。规范化的URI有助于提高应用程序的安全性,防范一些常见的攻击手法。
  • 避免敏感信息泄露:Rewrite 可以限制对某些敏感信息或文件的访问,确保只有授权用户能够获取特定内容。这有助于防止敏感信息泄露和未授权访问。

2.3 Rewrite 相关指令

Rewrite 相关指令有 if、rewrite、set、return。

2.3.1 if 语句

Nginx 中的 if 语句常用于实现精细的访问控制策略。例如,可以设置只有特定IP或内网IP可以访问某些资源,其他IP则被重定向到停服更新页面,也可以通过 if 语句实现 URL 重写、限制访问速度等功能。

# 基本语法
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        用于表示客户端请求的完整 URI,也就是请求地址,它记录了客户端发起的请求地址
$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.3.2 rewrite flag 简介:redirect、permanent、break、last

Nginx 中的 rewrite 指令可以包含一个可选的 flag(标志),用于控制重写操作后的行为

这个 flag 的类型总共有四种,如下:

  • redirect:这是一种临时重定向,状态码为 302。当重写完成后,Nginx 会以临时重定向的方式返回重写后生成的新 URL 给客户端。浏览器地址栏会显示跳转后的 URL 地址,但爬虫不会更新 URL。
  • permanent:这是一种永久重定向,状态码为301。与 redirect 类似,permanent 也会直接对 URL 地址进行重定向,并显示跳转后的 URL 地址。从实现功能的角度看,redirect 和 permanent 是一样的,不存在好坏和性能上的问题。然而,对于 SEO(搜索引擎优化)来说,使用 permanent 更为友好,因为它告诉搜索引擎这是一个永久性的移动,把原始页面的所有排名信号都传递到新的URL上,无需再请求到原地址,也避免了地址栏的重复跳转,更友好。
  • break:在重写完成后,break 会停止处理当前 URL 在当前 location 以及其他 location 中后续的其他重写操作。它不会跳出 location 作用域,也不会重新搜索与更改后的 URI 相匹配的 location适用于一个 URL 只需要一次重写的场景。2
  • last:重写完成后,last 会停止处理当前 URI 在当前 location 中后续的其他重写操作。但它会对新的 URL 启动新一轮重写检查,并可能跳出当前 location 作用域搜索与更改后的 URI 相匹配的 location适用于一个 URL 可能需要多次重写的场景。

2.3.3 permanent 简单示例

注意:可以使用测试域名,但前提是要修改 hosts 文件。

路径和重启:Linux(/etc/hosts)(重启命令:/etc/init.d/network restart);Windows(C:\Windows\System32\drivers\etc\hosts)。

  • 实例:变更整个资源路径

示例:从 http://www.testczzj.com:8080/test/test_page.html

——> http://www.testczzj.com:8080/test2/test2.html

示例文件夹结构:

/usr/tmp/test/test_page.html

/usr/tmp/test2/test2_page.html

<div id="div1"><h1>这是test2_page页面</h1>
</div>
server {listen       8080;server_name  www.testczzj.com;charset utf-8;location /test {index  index.html index.htm;# 匹配成功之后的全部路径,全部替换成指定的地址rewrite  .*  /test2/test2_page.html  permanent;}location /test2 {alias  /usr/tmp/test2;index index.html index.htm;}
}

自动跳转:(输入第一行地址回车自动跳转到新地址)

  • 实例:变更路径中的一部分

示例:http://www.testczzj.com:8080/2024/test/test_page.html

——> http://www.testczzj.com:8080/2025/test/test_page.html 

目的就是将 URL 中的 /2024/ 自动换成 /2025/,当然,实际业务中可以一般没有这么简单。

示例文件夹结构:

/usr/tmp/2025/test/test_page.html

<div id="div1"><h1>这是test_page页面</h1>
</div>
server {listen       8080;server_name  www.testczzj.com;charset utf-8;location /2024/test {index  index.html index.htm;# 先匹配 2024 之后的全部路径,再拼接到 2025 之后rewrite  ^/2024/(.*)  /2025/$1  permanent; #  (.*):表示以任意结尾,全部匹配取到}location /2025/test2 {alias  /usr/tmp/test2;index index.html index.htm;}
}

自动跳转:(输入第一行地址回车自动跳转到新地址)

  • 实例:将旧域名永久重定向到新域名

示例:http://www.testczzj.com/2024/test/test_page.html

——> http://www.testczzj_new.com

根据路径中的标识:/2024,来拦截,将全部请求直接跳转到新的地址主页。

server {listen       8080;server_name  www.testczzj.com www.testczzj_new.com;charset utf-8;location /2024 {root /usr/tmp/2024index  index.html index.htm;if  ($host ~* www.testczzj.com){ # 将 testczzj 转到 testczzj_newrewrite .* http://www.testczzj_new.com permanent;}}
}

自动跳转:

  • 实例:只更新协议和域名,url 路径不变

示例目标:http://www.testczzj.com/2024/test/test_page.html

——> https://cn.bing.com/2024/test/test_page.html

配置如下:

server {listen       80;server_name  www.testczzj.com;charset utf-8;location /2024 {root /usr/tmp/2024;index  test_page.html  index.html  index.htm;if  ($host ~* www.testczzj.com){ # $request_uri 用于表示客户端请求的完整 URI,也就是请求地址rewrite .* http://cn.bing.com$request_uri permanent;}}
}

自动跳转:(由于 bing 后路径没有资源,因此页面会加载失败)

  • 实例:在 URL 地址末尾没有 / 时,默认添加

示例目标:http://www.testczzj.com/2024/test

——> http://www.testczzj.com/2024/test/

注:示例文件路径:/usr/tmp/2024/test/test_page.html。

为什么要添加这个斜线?

搜索引擎对带有和不带有斜杠的 URL 有着不同的处理方式。通常,带有斜杠的 URL 被视为目录,而不带斜杠的 URL 被视为文件或特定资源。

当 URL 的斜杠使用不一致时,可能会导致不必要的重定向,从而影响页面加载速度和用户体验。一致的 URL 结构有助于提高用户体验。用户期望目录级别的 URL 以斜杠结尾,而文件级别的 URL 则不带斜杠。

server {listen       80;server_name  www.testczzj.com;charset utf-8;location /2024/test {root /usr/tmp;index  test_page.html  index.html  index.htm;if  (-d  $request_filename){ # 用于检查请求的文件名是否是一个目录。如果是目录,则执行大括号内的指令# (.*):捕获任意字符(除了换行符)零次或多次,并将其存储在第一个捕获组中# ([^/]):捕获除斜线(/)之外的任意单个字符,并将其存储在第二个捕获组中# $host:当前请求的主机名rewrite ^(.*)([^/])$ http://$host$1$2/ permanent; }}
}

自动补上斜线:

  • 实例:重定向后,在 URL 末尾添加 Query 参数

示例目标:http://www.testczzj.com/login/czzj.html

——> http://www.testczzj.com/2024/test/login.html?name=czzj

示例文件路径:/usr/tmp/2024/test/login.html。

把功能隐藏到 URL 路径中去。

server {listen       80;server_name   www.testczzj.com;charset utf-8;location /login {root /usr/tmp/2024;index  login.html  index.html  index.htm;# 正则表达式的目的:匹配以 /login/ 开头并以 .html 结尾的内容为第一捕获组:$1rewrite ^/login/(.*)\.html$ http://$host/test/login.html?name=$1;}location /test { # 处理重写后的请求:/testalias  /usr/tmp/2024/test;index  login.html  index.htm;}
}

如下图自动跳转:

  • 实例:将固定格式 /2025-01-02/ 重定向为 /2025/01/02/

示例目标:http://www.testczzj.com/test/2025-01-03/test_page.html

——> http://www.testczzj.com/test/2025/01/03/test_page.html

示例文件路径:/usr/tmp/test/2025/01/03/test_page.html

server {listen       80;server_name   www.testczzj.com;charset utf-8;location /test {root /usr/tmp;index  test_page.html  index.html  index.htm;# ([0-9]+): 这是一个捕获组,用于匹配一个或多个数字(即至少一个数字)# (.*): 这是第四个捕获组,用于匹配任意数量的任意字符(包括空字符)rewrite ^/test/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /test/$1/$2/$3$4 permanent;}
}

如下图自动跳转:

2.4 set 指令

set 指令用于设置一个变量的值。这个指令可以在多个上下文中使用,例如 http、server、location 和 if 块中。

# 基本语法
set $variable_name value;
# $variable_name:要设置的变量名,必须以 $ 符号开头
# value:要赋予变量的值,可以是字符串、数字或由其他变量组成的表达式
  • 实例:将域名转换为路径参数

示例目标:

http://username1.testczzj.com/test/userPage1.html

——> http://www.testczzj.com/username1/userPage1.html

http://username2.testczzj.com/test/userPage2.html

——> http://www.testczzj.com/username2/userPage2.html

示例文件:

/usr/tmp/username1/userPage1.html

/usr/tmp/username2/userPage2.html

# hosts 添加配置,注意请将‘服务器IP地址’替换为自己真实的服务器 IP
测试机IP地址 www.testczzj.com
测试机IP地址 username1.testczzj.com
测试机IP地址 username2.testczzj.com
# Linux(编辑:/etc/hosts)(重启命令:/etc/init.d/network restart)
# Windows(编辑:C:\Windows\System32\drivers\etc\hosts)

nginx 配置如下:

server {listen       80;server_name   www.testczzj.com;charset utf-8;location /test {root /usr/tmp;index index.html  index.htm;if ( $host ~* ^www.testczzj.com$ ){break; # 终止 nginx 在当前请求中的所有后续 location 的匹配}if ( $host ~* "^(.*)\.testczzj\.com$" ) {set $user $1; # 将正则表达式中第一个捕获组的值赋给变量 $userrewrite .* http://www.testczzj.com/$user permanent;}}location /username1 {alias  /usr/tmp/username1;# root /usr/tmp;index  userPage1.html index.html  index.htm;}location /username2 {alias /usr/tmp/username2;# root /usr/tmp;index userPage2.html index.html index.htm;}
}

效果如下图:

2.5 return 指令

return 指令是 nginx 配置中用于立即返回指定状态码可选的响应体的指令。它通常用于处理特定的请求,并立即终止进一步的处理。

# 语法
return code [text];
# code: 要返回的 HTTP 状态码,例如 200, 404, 500 等
# [text]: 可选的响应体文本。如果省略,Nginx 将使用默认的响应体# 简单示例
location / {return 200; # 对所有匹配 / 路径的请求返回 HTTP 200 状态码
}
# 返回状态码和自定义响应体
location /custom {return 403 "Access Denied"; # 对所有匹配 /custom 路径的请求返回 HTTP 403 状态码,并在响应体中包含 "Access Denied" 文本
}
# 重定向到另一个 URL
location /redirect {return 301 http://example.com; # 将所有匹配 /redirect 路径的请求重定向到 http://example.com,并返回 HTTP 301 状态码
}

return 指令会立即终止当前请求的处理,不会继续执行后续的配置指令。因此,它通常放在 location 块的开头。

如果需要返回带有复杂内容的响应体,建议使用 add_header 和 echo 模块,或者通过内部重定向到一个专门处理这些内容的 location。

  • 实例:若 URL 中有调用 .sh 脚本文件,直接返回 403 拒绝操作

示例目标:

http://www.testczzj.com/test/

——>正常加载指定页面:http://www.testczzj.com/test/test_page.html

http://www.testczzj.com/test/ts.sh

——> 返回禁止访问:403 Forbidden

nginx 配置如下:

server {listen       80;server_name   www.testczzj.com;charset utf-8;location ~*  \.sh$ { # 写在最前边return  403;}location /test {alias  /usr/tmp/test;index  test_page.html index.html  index.htm;}
}

效果如下图:

  • 实例:http 转 https(端口 80 转 443)

注意,这个测试需要有 SSL 证书。

如下配置项供参考:(未经实际验证)

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;   #返回301永久重定向
}
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;}
}

可以通过 curl 命令进行检验:

# 使用 curl 命令行工具发送 HTTP 请求的命令
# -I 或 --head 选项告诉 curl 只获取 HTTP 响应的头部信息,而不下载整个内容
# 这对于检查服务器响应头信息非常有用
# 当你运行这个命令时,curl 会向目标服务发送一个 HTTP HEAD 请求,并返回该请求的响应头信息
# 响应头信息通常包括状态码、内容类型、服务器信息、日期等。
[root@localhost ~]# 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/

2.6 last(重新进行匹配)、break(终止) 指令

last 和 break 指令是用于控制 rewrite 模块的行为,它们在处理重写规则时有不同的作用

last 指令在当前的 rewrite 规则执行完后,会停止处理后续的 rewrite 规则,并根据重写后的新 URI 重新发起一次请求并从服务器配置的顶部开始重新匹配 location 块。

  示例:假设有一个 location 块/old_path,使用rewrite ^/old_path(.*)$ /new_path$1 last;,当访问/old_path/something时,nginx 会将其重写为/new_path/something重新匹配 location 块

break 指令在当前的 rewrite 规则匹配成功后,会停止处理后续的 rewrite 规则,但不会重新开始匹配 location 块,即在满足特定条件后终止重写过程

  示例:同样的 location 块/old_path,如果使用rewrite ^/old_path(.*)$ /new_path$1 break;,当访问/old_path/something时,nginx 会将其重写为/new_path/something,但不会重新匹配 location 块,而是继续处理当前请求的其他阶段。

参考:https://blog.csdn.net/m0_62396418/article/details/135747521

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

题解:AT_abc353_f [ABC353F] Tile Distance

[ABC353F] Tile Distance 题解 cnblogs 题目传送门:洛谷,Atcoder Solution 很恶心人的分类讨论题。 很显然走大格子大概率比走小格子快。 对终点和起点向上下左右枚举大格子,我们就把问题转化为给两个大格子 \((a,b)\)、\((c,d)\),求怎样走最快。 对角的大格子可以通过 \(2…

数字化转型中的项目管理优化:协作工具的优势与应用

一、企业数字化转型的背景与挑战 1.1 数字化转型的驱动力数字化转型是指企业通过采用数字技术、创新流程和业务模式,提升运营效率、创造新价值并优化客户体验。随着云计算、大数据、人工智能和物联网等技术的不断发展,数字化转型已成为企业实现长期竞争力和持续增长的重要战略…

rk3568屏幕抖动问题

问题描述:有时候操作屏幕界面,发现屏幕有抖动的情况。经跟RK原厂沟通,此问题跟给ddr供电的vdd_logic有关系。vdd_logic默认定义:vdd_logic: DCDC_REG1 {regulator-always-on;regulator-boot-on;regulator-min-microvolt = <500000>;regulator-max-microvolt = <13…

B@se-还原错误字母表转码的base64编码

题目: 密文:MyLkTaP3FaA7KOWjTmKkVjWjVzKjdeNvTnAjoH9iZOIvTeHbvD== JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOefghq56rs****kxyz012789+/oh holy shit, something is missing... 第一行是密文,有明显的Base64编码特征(等号结尾) 第二行是大小写字母、数字、+、/,有明显的…

打开浏览器Chrome跳转指定页面并全屏打开

办法来源于https://blog.csdn.net/shaofengzong/article/details/119928096 主要用于大屏数据可视化的项目,设置电脑自启动后,打开浏览器的同时默认跳转指定页面并全屏打开。、 办法通过增加谷歌浏览器的启动参数进行实现。 两种方式实现,需要根据需求进行选择默认全屏打开指…

板栗看板:让供应商全生命周期管理变得如此简单

供应商全生命周期管理(Supplier Lifecycle Management,SLM)是一个结构化、全流程的供应商闭环管理过程,旨在优化供应商关系,提高供应链的整体效率和可持续性。以下是对供应商全生命周期管理的详细阐述供应商全生命周期管理(Supplier Lifecycle Management,SLM)是一个结…

协作管理工具在多部门协作中的优势与应用

一、跨职能团队协作的挑战 跨职能团队的协作面临多个方面的挑战,这些挑战往往会影响团队的工作效率、项目的推进速度以及最终的项目质量。 1.1 信息传递不畅在跨职能团队中,成员来自不同的部门,各自拥有不同的背景、职责和目标。因此,团队成员之间的沟通可能不够顺畅,信息…

side channel

‌Side Channel‌,中文称为“边信道”,是指通过加密软件或硬件运行时产生的各种泄漏信息来获取密文信息的攻击方式。在狭义上,边信道攻击特指针对密码算法的非侵入式攻击,通过分析加密电子设备在运行过程中的边信道信息泄露来破解密码算法。常见的边信道攻击包括计时攻击、…

RocketMQ工具的使用方法

RocketMQ简介 启动rocketmq-Dashboard项目 输入 http://localhost:8888/#/ 即可到rocketmq界面 整体横向菜单分为八个部分:OPS(运维):主要是设置nameserver和配置vipchannel Dashboard(驾驶舱):控制台的dashboard,可以分别按broker和主题来查看消息的数量和趋势。 Cluster(…

【docker】docker desktop换国内源时 apply按钮为灰色or换源失败 解决方法

配docker环境时复制进去国内镜像源后,发现apply按钮为灰色,点不了,如下图解决方法:往下滑,找到下图圈住的选项打勾再回到Docker Engine界面,发现可以点apply按钮了在文本框中添加"registry-mirrors": ["http://mirrors.ustc.edu.cn","http://mi…

ElasticSearch在Windows环境搭建测试

引子 也持续关注大数据相关内容一段时间,大数据内容很多。想了下还是从目前项目需求侧出发,进行相关学习。Elasticsearch(ES)是位于 Elastic Stack(ELK stack) 核心的分布式搜索和分析引擎。Logstash 和 Beats 有助于收集、聚合和丰富您的数据并将其存储在 Elasticsearch…

科研绘图系列:python语言绘制SCI图合集

介绍 科研绘图系列:python语言绘制SCI图合集 加载python import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.patches as mpatches import seaborn as snsfrom statsmodels.stats.multitest import multipletests# Setup for local r…