文章目录
- 一. 在官网下载nignx安装包
- 二.下载依赖
- 三.编译文件
- 四. ss命令和lsof命令的使用
- 五. 配置ngnix.service文件
- 六. 配置完毕后可能出现的问题
- 七. ngnix的功能
- 八. 使用curl对服务器发送请求
- 九. 使用nginx服务器管理多个服务器
- 十. 已经安装好nginx后再添加其他模块的方法
- 十一. systemctl刷新<报错信息>
- 十二. 如何保证ngnix服务器在运行时可以自动生成需要的运行时文件
- 十三. nginx虚拟主机
- 十四. 使用nginx来截取对www.baidu.com的访问不可行的原因
- 十五. 代理循环的错误导致500页面
- 十六. 正确理解server_name模块
- 十七. location的理解
一. 在官网下载nignx安装包
二.下载依赖
在Ubuntu中应该下载:
sudo apt-get install libpcre3-dev:支持正则表达式的模块
sudo apt-get install zlib1g.dev:支持zlib压缩的模块
sudo apt-get install openssl :加密工具
sudo apt-get install libssl-dev
三.编译文件
- 执行./configure生成makefile文件
- make编译makefile
- 使用make install,主要作用是将编译生成的文件正确地复制到系统的适当位置,以便用户可以方便地使用软件
- 添加到系统变量,我们可采用两种方式
(1)通过sudo ln -s /usr/local/nginx/sbin/* /usr/local/bin
(2)通过修改系统文件,可参考cmake的安装
四. ss命令和lsof命令的使用
ss和lsof在网络管理上特别有用
-
1. lsof
lsof会列出当前系统正在使用的所有文件,为了便于我们进行网络管理。我们通常使用
lsof -i -P -n- -i 表示显示所有与网络接口(interface)相关的文件
- -P 直接输出端口号(port),否则将显示端口号对应的服务
- -n 将主机名解析为数字,否则将显示端口所在的主机名
-
2. ss
ss网路套接字统计工具
通常我们使用ss -tuln- -t 显示tcp协议的连接
- -u 显示udp协议的连接
- -l 显示监听状态的套接字
- -n 将端口号和主机名全部解析为数字
-
3. ss -tuln 命令显示各字段的含义
列如:
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 [::]: *State:表示连接的状态,例如 LISTEN 表示该套接字在监听。
Recv-Q:接收队列的长度。
Send-Q:发送队列的长度。
Local Address:Port :本地机器的IP地址和端口号,0.0.0.0表示IPV4的所有ip地址,所以这里表示正在监听当前机器上所有IPV4地址的22端口
Peer Address:Port :远程机器的IP地址和端口号,[::]表示IPV6的所有ip地址,所以这里表示可以接受来自远程机器上所有IPV6地址的所有端口的连接 -
4. lsof命令显示各字段的含义
重点说最后一个name字段,比如现在正在从firefox访问ngnix服务器:
- 网络相关的进程会占用本地的一个端口,firefox进程占用本地port:54716,ngnix占用本地port:80。现在可以看到,箭头表示:原ip端口 -> 目标ip端口
- 图中 *:80表示,nginx可以监听所有ip对80端口的访问
-
5.辨析一下ss和lsof在查询网络接口上的区别
- ss的是查看哪些本地主机哪些ip可以监听该端口,该端口可以接受哪些远程主机的端口连接。所以更多查看的是端口的属性
- lsof查看的是本地有哪些进程正在使用该端口。
五. 配置ngnix.service文件
目的:实现使用systemctl对ngnix进行管理
-
- 在/lib/systemd/system路径下配置ngnix.service文件
(/lib/systemd/system路径下有很多被systemctl管理的.service文件,比如NetworkManager.servie)
- 在/lib/systemd/system路径下配置ngnix.service文件
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginx.pid # 会在启动ngnix服务时会创建并将其进程信息保存到该文件
ExecStart=/usr/local/nignx/sbin/nginx -g 'daemon on; master_process on;
ExecReload=/usr/local/nignx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
AmbientCapabilities=CAP_NET_BIND_SERVICE # 让非root用户也可以访问1024以下的端口
[Install]
WantedBy=multi-user.target
下面是对 Nginx 服务文件的每一行配置的具体解释:
[Unit] 部分
Description=A high performance web server and a reverse proxy server
Description: 描述这个服务的简短信息,通常是一句话。这行描述了 Nginx 是一个高性能的网络服务器和反向代理服务器。
Documentation=man:nginx(8)
Documentation: 提供服务的文档位置,这里指向了 Nginx 的手册页,可以通过 man nginx 查看。
After=network.target
After: 指定这个服务应该在另一个特定的服务之后启动。network.target 表示在网络服务启动之后再启动 Nginx 服务。这确保了网络服务在 Nginx 之前启动。
[Service] 部分
Type=forking
Type: 定义服务的启动类型。forking 表示服务将通过 fork 操作启动,并且主进程会退出,从而形成一个新的守护进程。这种类型适用于传统的 Unix 守护进程。
ExecStart=/usr/sbin/nginx -g ‘daemon on; master_process on;’
ExecStart: 定义启动服务的命令。这里使用 /usr/sbin/nginx 启动 Nginx,并传递了配置参数 -g ‘daemon on; master_process on;’。这些参数告诉 Nginx 以守护进程模式启动,并启用主进程管理。
ExecReload=/usr/sbin/nginx -s reload
ExecReload: 定义重新加载服务的命令。这里使用 /usr/sbin/nginx -s reload 重新加载 Nginx 配置,而不中断正在进行的连接。
ExecStop=/usr/sbin/nginx -s stop
ExecStop: 定义停止服务的命令。这里使用 /usr/sbin/nginx -s stop 停止 Nginx 服务。
PIDFile=/run/nginx.pid
PIDFile: 指定保存服务主进程 ID 的文件路径。这个文件用于跟踪服务的主进程。
PrivateTmp=true
PrivateTmp: 为服务分配一个私有的 /tmp 和 /var/tmp 目录,使其与其他服务的临时文件隔离,提高安全性。
AmbientCapabilities=CAP_NET_BIND_SERVICE
AmbientCapabilities:让非root用户也可以访问1024以下的端口
[Install] 部分
WantedBy=multi-user.target
WantedBy: 指定服务在哪个目标下启动。multi-user.target 是一个常用的系统运行级别,类似于传统的运行级别 3,表示多用户命令行模式。在这个目标下,Nginx 服务会被启动。
-
- 重新加载systemctl的配置
sudo systemctl daemon-reload
- 重新加载systemctl的配置
-
- 使用sudo nginx -c /usr/local/nginx/conf/nginx.conf,让nignx使用该配置文件。注意要设置该配置文件中的pid /run/nginx.pid;保证和service文件中指定的pid文件路径一致
-
- 检查ngnix的设置的bind()端口是否被占用:
我们使用ss命令查看端口开放情况,使用lsof命令查看
-
- sudo ss -tuln | grep :80 (如果是设置的不是80,可修改为其他的端口)
如果有输出说明被占用,查看是哪个进程占用
- sudo ss -tuln | grep :80 (如果是设置的不是80,可修改为其他的端口)
-
- sudo lsof -i :80
(1)如果想关闭80端口的进程,用kill杀死该进程
(2)如果不想关闭,则需切换端口把/usr/local/nginx/conf/nginx.conf
的监听端口改为非80的,比如8080端口,注意/usr/local/nginx/conf/nginx.conf.default文件中也会配置80端口为默认端口。
- sudo lsof -i :80
-
- 查看nginx在监听哪些端口
sudo lsof -i -P -n | grep nginx
- 查看nginx在监听哪些端口
- 检查ngnix的设置的bind()端口是否被占用:
-
- mv /usr/local/nginx/conf/nginx.conf.default /usr/local/nginx/conf/nginx.conf.default.bak
保证ngnix启动时只使用主配置文件nginx.conf,而不使用nginx.conf.default
- mv /usr/local/nginx/conf/nginx.conf.default /usr/local/nginx/conf/nginx.conf.default.bak
-
6. 配置防火墙
-
- 查看防火墙是否开启
sudo firewall-cmd --state
- 查看防火墙是否开启
-
- 打开防火墙
sudo systemctl start firewall
- 打开防火墙
-
- 查看所有开放的端口
sudo firewall-cmd --list-all
- 查看所有开放的端口
-
- 开放需要的端口
sudo firewall-cmd --permanent --add-port=端口号/tcp
(如果需要关闭某个端口则sudo firewall-cmd --permanent --remove-port=端口号/tcp端口号)
- 开放需要的端口
-
- 重启防火墙更新配置
sudo systemctl restart firewalld.service
- 重启防火墙更新配置
-
六. 配置完毕后可能出现的问题
-
如果出现nginx: [emerg] open() “/run/nginx.pid” failed (13: Permission denied),
- 原因:说明当前ngnix监听的是1024以下的端口。1024以下的端口访问必须要root权限。
- 解决方法3种:(1)使用sudo ngnix启动服务(2)使用sudo systemctl start ngnix启动服务
(3)配置nignx.conf文件,设置server监听8080端口
-
** 如果出现sudo systemctl stop ngnix和sudo ngnix -s stop无法停止nginx**
- 原因:pid文件出错,导致系统找不到进程号。pid文件的路径在我们配置的/lib/systemd/system/ngnix.service中
- 解决方法:(1)ps -ef | grep nginx查看进程号,然后用kiil -9 强制停止ngnix的进程。
(2)尝试删除pid文件
(3)重启nginx服务即可
七. ngnix的功能
- 反向代理
- 负载均衡
- 动静分离
-
问题一: 打开nginx之后,在本地浏览器访问http::\localhost:80,出现的网页是什么?
答:访问localhost:80表示连接本机的80端口,80端口是专门用于http协议访问的,现在nginx正在监听80端口,当监听到有连接访问时,会执行nginx.conf文件。
server {
listen 80;
server_name localhost;location / {
root html;
index index.html index.htm;
}
}
文件中的root和index表示,当用户访问 http://localhost:80/ 时,如果location匹配到了/则,Nginx 会默认在root路径即/usr/local/nginx/html 目录中查找 index.html 文件,如果是root /var/www则会在/var/www目录中查找index.html文件。如果找不到 index.html,则会查找 index.htm,并返回找到的第一个文件。所以此时的页面就是这个html文件
还需要注意的是,我们可以在location中添加反向代理,比如:
server {
listen 80;
server_name localhost;
upstream Baidu{
server 168.127.12.4:8080 ;weight = 1;# 168.127.12.4可以是本机ip也可以是其他主机的ip,总之该ip的主机会作为响应服务器
server 168.127.12.4:8081;weight = 2;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
proxy_pass http://Baidu;
}
}
当使用http访问本地主机时,会首先被80端口监听到,然后将请求传给nginx服务器,服务器会根据weight在上游代理服务器里选择一个来响应当前请求。而且可以根据权重weight来决定每个上游服务器响应请求的频率。这样就实现了负载均衡(**需要注意的是:**因为我们这里使用了反向代理,所以响应的结果是返回上游代理服务器的网页。否则会返回当前服务器的欢迎页。)
八. 使用curl对服务器发送请求
- curl -v baidu.com
-v可以检测出请求头和响应头,以便追溯请求的过程。同时302代码表示当前客户端请求正在被从定向(可在location查看从定向位置)。200代码表示请求成功,客户端接收到了最终服务器响应。
九. 使用nginx服务器管理多个服务器
nginx服务器运行时使用的是主配置文件/usr/local/nginx/conf/ngnix.conf。
- 若想新增服务器让ngnix管理
- 方法1:直接在/usr/local/nginx/conf/ngnix.conf添加server块。
- 方法2:
-
- 创建副配置文件
-
- sudo mkdir -p /etc/nginx/sites-available(存在目录则无需新建)
-
- sudo mkdir -p /etc/nginx/sites-enabled
-
- 在/etc/nginx/sites-available中新建副配置文件/example.com.conf
-
- sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
为副配置文件创建符号连接
- sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
-
-
在主配置文件中http中添加
http {include /etc/nginx/sites-enabled/*;
}
-
-
十. 已经安装好nginx后再添加其他模块的方法
-
分为添加外置模块和内部模块
-
1.添加外置模块使用–add-module
1.例如添加ngx_cache_purge 模块的作用是快速清除网页指定缓存
方法:
(1)重新编译ngnix
./configure --add-module=…/ngx_cache_purge
make
注意不要make install,这样会让当前编译好的文件覆盖掉之前的配 置, 我们现在只需要替换exe文件即可,无需替换掉所有的配置(2)然后会在安装包目录下出现一个objs目录,我们需要用obj里的ngnix.exe替换掉之前nginx.exe。
替换前最好先备份一下原来的文件cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
把重新编译好的objs/nginx文件 复制到/usr/local/nginx/sbin/ 下,替换原来的nginx文件
cp objs/nginx /usr/local/nginx/sbin/
-
2.添加内置模块使用–with-
例如添加http_ssl_module加密服务模块
./configure --with-http_ssl_module
添加完加密模块后需要手动生成证书,并和ngnix.conf中的证书路径保持一致
可参考下面两条命令
openssl genpkey -algorithm RSA -out /usr/local/nginx/conf/cert.key
openssl req -new -x509 -key /usr/local/nginx/conf/cert.key -out /usr/local/nginx/conf/cert.pem -days 365
十一. systemctl刷新<报错信息>
刷新信息通常来说在调试时很重要,能够保证我们看到的时最新的status。
两种方法:
-
- 使sudo systemctl reset-failed 服务名,然后sudo systemctl start 服务名
-
- sudo systemctl restart 服务,因为此时服务没有启动,restart可能会找不到进程号。
通常来说两种方法都应该试一下,因为不知道报错时进程是否运行。
- sudo systemctl restart 服务,因为此时服务没有启动,restart可能会找不到进程号。
十二. 如何保证ngnix服务器在运行时可以自动生成需要的运行时文件
nginx服务器在运行时可以自动生成需要的文件,但是不能生成需要的目录,所以我们的关键就是要1. 保证目录是存在的。2. 所有目录的权限要控制好
比如我们在/usr/local/nginx/conf/ngnix.conf文件中设置的 /run/ngnix.pid 进程文件,ngnix在运行时会自动生成/run/ngnix.pid,但前提是需要要/run目录。
还比如我们在server中配置的
access_log /www/wwwlogs/vab.test.com.log;(服务器访问日志)
error_log /www/wwwlogs/vab.test.com.error.log;(服务器错误日志)
** 都必须保证先存在/www/wwwlogs/目录。**
十三. nginx虚拟主机
现在由ngnix配置为:
server {
listen 8080;
server_name example.com;
location / {
root /var/www/example;
index index.html;
}
}
-
当我们在浏览器中输入localhost:8080(等效于http://localhost:8080)时,浏览器会先更具/etc/hosts文件来解析localhost域名找到其ip地址,然后浏览器进程所在端口会向远程主机ip(这里是localhost的8080端口)发送请求。如果远程主机存在那么就会返回对应的网页。但是现在是向localhost本地主机的8080发送请求。本地主机的8080端口正在被ngnix监听,现在就会进入此sever块中 (这里注意ngnix中设置的listen8080是指监听所有网络接口的8080端口,我们使用lsof -i -P -n | grep ngnix也可以看出来),所以现在ngnix就一个虚拟主机来处理该请求(处理的方法之前说过 1.直接返回本地网页 2.进行反向代理。当前server块中是直接返回本地网页) ,然后匹配localhost和example.com(这里要注意localhost不进行域名解析,仅当字符串使用),如果相同则执行location,不同则不进行操作。
-
在浏览器中直接输入域名默认是使用http协议且向80端口发出请求,在虚拟机开启ngnix的情况下,我们甚至可以在实体机浏览器中输入虚拟机的ip比如192.168.10.7(默认访问80端口),此时ngnix就可以从监听的80端口中收到请求,然后选择一个server进行服务。但是我们可以知道,因为server中我们没有配置 server_name为192.168.10.7的server,那么此时ngnix该如何选择呢?
有两种方法
-
(1) 设置默认server如下所示,当匹配不到对应的server_name时,就会使用默认server
server {
listen 80 default_server;
server_name _;
return 404; # 或者其他默认处理逻辑
}
这就会返回404 NOT FOUND了 -
(2)如果没有设置默认的server,那么就会执行第一个定义的server
-
ngnix只监听IPv4的主机端口,不监听IPV6主机的端口,这个通过lsof -i -P -n也可以看到
-
当你在主机浏览器中输入 127.0.0.1,它实际上是指向主机自身的回环地址,而不是虚拟机的 IP 地址,通常用于本地测试使用。
十四. 使用nginx来截取对www.baidu.com的访问不可行的原因
- 解析域名时先使用本地的host文件解析,然后再使用DNS解析
- nginx默认监听的是本地的所有网络接口的80和443端口,但是当浏览器使用DNS对baidu域名解析之后,是向远程网络接口的443端口发送请求,所以ngnix无法监听。
- 想要强制截取只有再本地host中配置127.0.0.1 www.baidu.com强制把域名解析为本地ip。然后ngnix就能监听到请求了。
十五. 代理循环的错误导致500页面
假设有一个反向代理服务器 A(本机ngnix),它接收到一个来自客户端的请求(Firefox),然后将这个请求转发给另一个代理服务器 B(本机ngnix)。这样就会造成代理循环。
解决方法:要避免反向代理到反向代理服务器,这是错误的使用反向代理的方法
十六. 正确理解server_name模块
我们可以设置多个监听80端口的server模块,只需要保证每个server模块的server_name不同即可。这样做可以极大的帮助我们根据请求的域名分配不同业务。但前提是要购买足够多的域名。
十七. location的理解
Nginx 的 location 指令按以下顺序进行匹配:
精确匹配 (=):如 location = /exact_path。
前缀匹配 (^~ 或无修饰符):如 location ^~ /prefix 或 location /prefix。
正则匹配( ~ :区分大小写;~*:不区分大小写)。
优先级:= > ^~ > ~和 ~ *