Nginx快速上手

安装Nginx

包管理器安装

Linux:

$sudo apt update 
$sudo apt install nginx

Mac:

$brew install nginx

Win:

$scoop install nginx
$choco install nginx
安装完成后提示:
Docroot is: /opt/homebrew/var/www
The default port has been set in /opt/homebrew/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.
nginx will load all files in /opt/homebrew/etc/nginx/servers/.
To start nginx now and restart at login:
  brew services start nginx
Or, if you don't want/need a background service you can just run:
  /opt/homebrew/opt/nginx/bin/nginx -g daemon\ off\;
查看是否安装成功
$ nginx -V (注意是大写的V)

可以查看Nginx安装目录编译参数,以及配置文件和日志的位置等各种信息

Nginx的配置文件nginx.conf (它的路径和操作系统,安装方式有关)

$ nginx -t    //查看安装位置
--conf-path= /opt/homebrew/etc/nginx/nginx.conf (这个位置就是配置文件位置)

常见位置:

/etc/nginx/conf
/usr/local/etc/nginx
/opt/homebrew/etc/nginx
根据提供的信息,你可以按照以下步骤启动Nginx服务器:
  1. 打开终端或命令行界面。

  2. 输入以下命令来启动Nginx:

$ brew services start nginx

这将会启动nginx并且在登录时自动重启

如果你不需要在后台运行Nginx作为服务,你也可以使用以下命令来启动Nginx:

$ /opt/homebrew/opt/nginx/bin/nginx -g "daemon off;"

这将会启动nginx,但它不会作为后台服务运行

方法二:编译安装

Nginx基于C语言开发的,所以可以通过以下安装

$ ./configure     													预编译
	--sbin-path=/usr/local/nginx/nginx
	--conf-path=/usr/local/nginx/nginx.conf
	--pif-path=/usr/local/nginx/nginx.pid
	--with-http_ssl_module
	--with-pcre=../pcre2-10.39
	--with-zlib=../zlib-1.2.11
$ make																			编译
$ make install															安装

方法三:Docker安装

$ docker pull nginx

启动服务

终端中输入

$ nginx

回车后无任何提示消息表示Nginx启动成功

(这是Linux系统的一个设计思想,没有消息就是最好的消息,启动失败会有提示)

然后浏览器中输入

localhost
或者
localhost:8080

提示Welcome to nginx表示服务已经启动成功

Nginx启动后会作为一个后台程序一直运行

ps -ef|grep nginx      查看Nginx进程
501 36824     1   0 11:24上午 ??         0:00.00 nginx: master process nginx
501 36825 36824   0 11:24上午 ??         0:00.00 nginx: worker process
501 36868 35873   0 11:28上午 ttys001    0:00.01 grep nginx

(我们只关心master和worker进程)

master:Nginx主进程,负责读取和验证配置文件以及管理worker进程(只有一个)

woker:Nginx工作进程,负责处理实际的请求(可以有多个)

Nginx操作命令

$ nginx -s quit				(优雅停止)
$ nginx -s stop				(立即停止)
$ nginx -s reload			(重载配置文件)
$ nginx -s reopen			(重新打开日志文件)

报错信息:

(base) hanxuxian@hanxuxiandeMacBook-Air ~ % nginx
nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already in use)
nginx: [emerg] still could not bind()

nginx在启动时遇到了一个错误:bind()函数无法绑定到0.0.0.0:8080,错误代码是48,表示地址已经被占用。

这个错误通常是因为端口8080已经被其他进程占用了。要解决这个问题,你可以尝试以下几种方法:

  1. 检查是否已经运行了其他程序或服务在使用端口8080。可以使用以下命令查看占用端口8080的进程:
$ lsof -i :8080

命令执行后会显示占用该端口的进程及其进程号。

  1. 如果找到了占用8080端口的进程,你可以选择终止该进程或者更改nginx的默认端口。
  2. 如果没有找到占用8080端口的进程,可能是之前的nginx进程没有正确停止导致该端口仍然被保留。你可以尝试使用以下命令来停止nginx进程:
sudo nginx -s stop

然后再尝试重新启动nginx。

如果以上方法都无法解决问题,你可以尝试修改nginx配置文件中的端口号,将其更改为其他未被占用的端口。

网站搭建

使用Hexo生成一个简单的静态博客网站(Hexo基于Node.js的博客框架)

优点:可以将Markdown格式的文档转换成静态页面

安装 : npm install hexo-cli -g		 
初始化 :	hexo init blog
cd进入初始化的文件夹内
生成静态站点 : hexo g  (这个命令是将Markdown格式转换成静态页面放在public文件夹下)
安装依赖 : cd blog; npm install
本地运行 : hexo server / hexo s (启动本地服务器)
一键部署 : hexo d

部署网站

将public目录下的所有内容复制到html目录下

html目录位置

1. nginx -V (找到 --prefix=后面的内容)
2. cd public
3. cp -rf * /opt/homebrew/Cellar/nginx/1.25.4/html
or cp -rf * /opt/homebrew/var/www/

配置文件

打开nginx配置文件,找到worker_processes 1;

$ code nginx.conf

将参数改为10(数字代表worker进程数量。)

$ nginx -t

检查配置文件内容是否正确

$ nginx -s reload  (修改配置文件后重新加载)

查看进程

$ ps -ef |grep nginx

一般来说:worker进程数量保持同服务器CPU内核的数量相同是比较合适的。也可以设置为worker_processes auto;,会根据内核数自动设置worker进程数。

配置文件结构:

Nginx的配置⽂件是由⼀系列的指令组成的,每个指令都是由⼀个指令名和⼀个或者多个参数组成的。指令和参数之间使⽤空格来分隔,指令以分号 ; 结尾,参数可以使⽤单引号或者双引号来包裹。

配置⽂件分为以下⼏个部分:

# 全局块
worker_processes 1;
events {
	# events块
}
http {
	# http块
 	server {
		# server块
 		location / {
			# location块
 		}
 	}
}

全局块

全局块是配置⽂件的第⼀个块,也是配置⽂件的主体部分,主要⽤来设置⼀些影响Nginx服务器整体运⾏的配置指令,主要包括配置运⾏Nginx服务器的⽤户(组)、允许⽣成的workerprocess数、进程PID存放路径、⽇志存放路径和类型以及配置⽂件引⼊等。

# 指定运⾏Nginx服务器的⽤户,只能在全局块配置
# 将user指令注释掉,或者配置成nobody的话所有⽤户都可以运⾏
# user [user] [group]
# user nobody nobody;
user nginx;

# 指定⽣成的worker进程的数量,也可使⽤⾃动模式,只能在全局块配置
worker_processes 1;

# 错误⽇志存放路径和类型
error_log 	/var/log/nginx/error.log warn;

# 进程PID存放路径
pid 	/var/run/nginx.pid;

events块

events {
	# 指定使⽤哪种⽹络IO模型,只能在events块中进⾏配置
	# use epoll
	
	# 每个worker process允许的最⼤连接数
 	worker_connections 1024;
}

http块

http块是配置⽂件的主要部分,包括http全局块和server块。

 http {
	# nginx 可以使⽤include指令引⼊其他配置⽂件
 	include /etc/nginx/mime.types;
 	
	# 默认类型,如果请求的URL没有包含⽂件类型,会使⽤默认类型
 	default_type application/octet-stream; # 默认类型
	
	# 开启⾼效⽂件传输模式
 	sendfile on;
	
	# 连接超时时间
 	keepalive_timeout 65;
	
	# access_log ⽇志存放路径和类型
	# 格式为:access_log <path> [format [buffer=size] [gzip[=level]][flush=time] [if=condition]];
 	access_log /var/log/nginx/access.log main;
	
	# 定义⽇志格式
  #	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
	
	# 设置sendfile最⼤传输⽚段⼤⼩,默认为0,表示不限制
	# sendfile_max_chunk 1m;
	
	# 每个连接的请求次数
	# keepalive_requests 100;
	
	# keepalive超时时间
 	keepalive_timeout 65;
	# 开启gzip压缩
	# gzip on;
	
	# 开启gzip压缩的最⼩⽂件⼤⼩
	# gzip_min_length 1k;
	
	# gzip压缩级别,1-9,级别越⾼压缩率越⾼,但是消耗CPU资源也越多
	# gzip_comp_level 2;
	
	# gzip压缩⽂件类型
	# gzip_types text/plain application/javascript application/x-javascript text/css application/xml 	 text/javascript application/x-httpd-php image/jpeg image/gif image/png;
	
	# upstream指令⽤于定义⼀组服务器,⼀般⽤来配置反向代理和负载均衡
 	upstream www.example.com {
	
		# ip_hash指令⽤于设置负载均衡的⽅式,ip_hash表示使⽤客户端的IP进⾏hash,这样可以保证同⼀个客户端的请求每次都会分配到同		⼀个服务器,解决了session共享的问题
 		ip_hash;
		# weight ⽤于设置权重,权重越⾼被分配到的⼏率越⼤
 		server 192.168.50.11:80 weight=3;
 		server 192.168.50.12:80;
 		server 192.168.50.13:80;
 	}
 	server {
		# 参考server块的配置
 	}
}

server块

server块是配置虚拟主机的,⼀个http块可以包含多个server块,每个server块就是⼀个虚拟主机。

server {
	# 监听IP和端⼝
	# listen的格式为:
	# listen [ip]:port [default_server] [ssl] [http2] [spdy][proxy_protocol] [setfib=number] 	[fastopen=number] [backlog=number];
	# listen指令⾮常灵活,可以指定多个IP和端⼝,也可以使⽤通配符
	# 下⾯是⼏个实际的例⼦:
	# listen 127.0.0.1:80; # 监听来⾃127.0.0.1的80端⼝的请求
	# listen 80; # 监听来⾃所有IP的80端⼝的请求
	# listen *:80; # 监听来⾃所有IP的80端⼝的请求,同上
	# listen 127.0.0.1; # 监听来⾃来⾃127.0.0.1的80端⼝,默认端⼝为80

	listen 80;

	# server_name ⽤来指定虚拟主机的域名,可以使⽤精确匹配、通配符匹配和正则匹配等⽅式
	# server_name example.org www.example.org; # 精确匹配
	# server_name *.example.org; # 通配符匹配
	# server_name ~^www\d+\.example\.net$; # 正则匹配
 
	server_name localhost;
	# location块⽤来配置请求的路由,⼀个server块可以包含多个location块,每个location块就是⼀个请求路由
	# location块的格式是:
	# location [=|~|~*|^~] /uri/ { ... }
	# = 表示精确匹配,只有完全匹配上才能⽣效
	# ~ 表示区分⼤⼩写的正则匹配
	# ~* 表示不区分⼤⼩写的正则匹配
	# ^~ 表示普通字符匹配,如果匹配成功,则不再匹配其他location
	# /uri/ 表示请求的URI,可以是字符串,也可以是正则表达式
	# { ... } 表示location块的配置内容
	location / {
		# root指令⽤于指定请求的根⽬录,可以是绝对路径,也可以是相对路径
 		root /usr/share/nginx/html; # 根⽬录
		# index指令⽤于指定默认⽂件,如果请求的是⽬录,则会在⽬录下查找默认⽂件
		index index.html index.htm; # 默认⽂件
	}
	# 下⾯是⼀些location的示例:
	location = / { # 精确匹配请求
 		root /usr/share/nginx/html;
 		index index.html index.htm;
	}
	location ^~ /images/ { # 匹配以/images/开头的请求
 		root /usr/share/nginx/html;
	}
	location ~* \.(gif|jpg|jpeg)$ { # 匹配以gif、jpg或者jpeg结尾的请求
	 	root /usr/share/nginx/html;
	}
	location !~ \.(gif|jpg|jpeg)$ { # 不匹配以gif、jpg或者jpeg结尾的请求
	 	root /usr/share/nginx/html;
	}
	location !~* \.(gif|jpg|jpeg)$ { # 不匹配以gif、jpg或者jpeg结尾的请求
 		root /usr/share/nginx/html;
	}
	# error_page ⽤于指定错误⻚⾯,可以指定多个,按照优先级从⾼到低依次查找
	error_page 500 502 503 504 /50x.html; # 错误⻚⾯
	location = /50x.html {
		root /usr/share/nginx/html;
	}
}

正反向代理

正向代理客户端:

例如VPN:让代理服务器作为客户端代理我们去访问网站,将结果返回

反向代理服务端:

例如:访问google时我们只有一个域名,但背后有成千上万服务器,我们的请求会被转发到后面的服务器上。隐藏了服务器真实的ip地址,端口信息。

在nginx.conf文件中添加upstream backend配置反向代理

http {
	upstream backend{
		server 127.0.0.1:8000;(启动的三个服务)
		server 127.0.0.1:8001;(启动的三个服务)
		server 127.0.0.1:8002;(启动的三个服务)
	}
    server {
  	    location /app{ (让所有以app开头的请求被代理到upstream配置中)
   	    proxy_pass http://backend; (这里的backend必须和upstream后面的名称一样)
    }
}

(修改配置文件后重新加载)

$ nginx -s reload

打开浏览器浏览:localhost/app

(请求被代理到三个服务器上,默认轮询方式代理)

服务器性能配置不同

假如第一台服务器的性能配置优于后两台,我们使用weight(权重)调整负载策略

server 127.0.0.1:8000 weight=3;   (3表示第一个服务器是后面两个权重的三倍,权重越大被分配到的请求次数越多)

使用ip_hash

这个策略会根据客户端的IP地址进行哈希,同一个客户端的请求就会被分配到同一个服务器上,解决了一些session相关问题

http {
	upstream backend{
		ip_hash;
		…………
	}
}

HTTPS配置

HTTP默认端口:80 HTTPS默认端口:443

(HTTP + SSL = HTTPS) (SSL可以在阿里云或者腾讯云申请到免费证书,得到密钥文件证书文件)

生成自签名证书:

如果没有云平台,我们使用openssl生成证书

1.生成私钥文件(private key)

openssl genrsa -out private.key 2048

2.根据私钥生成证书签名请求文件(Certificate Signing Request , 简称CSR文件)

openssl req -new -key private.key -out cert.csr

3.使用私钥对证书申请进行签名从而生成证书文件(pem文件)

openssl x509 -req -in cert.csr -o cacert.pem -signkey private.key

可以将三行命令合一,会提示我们输入国家姓名地址公司(生成证书文件里的信息)

我们需要将生成的private.key.pem结尾文件放到服务器中

4.打开nginx.conf进行配置

server {
	listen    443 ssl;
	server_name localhost;   #填写网站域名
	# 证书文件名称
	ssl_certificate           /opt/homebrew/etc/nginx/cacert.pem;
	# 证书密钥文件名称
	ssl_certificate_key				/opt/homebrew/etc/nginx/private.key;
	# ssl验证设置
	ssl_session_timeout				5m;     #缓存有效期
	# 安全链接可选的加密协议
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
	# 配置加密套件/加密算法,写法遵循 openssl 标准。
	ssl_ciphers ECDHE-RSA_AES128-GCM-SHA256:HIGH:!aNULL:!MD5:RC4:!DHE;
	# 使用服务器端的首选算法
	ssl_prefer_server_ciphers on;
  }

5.配置重定向

HTTP请求自动跳转HTTPS

server {
	listen    80;
	server_name localhost;   #填写网站域名
	return 301 https://$server_name$request_url;     #添加这一行就行
}

Nginx 常用模块

模块名(Module Name) 描述(Description)
http_access_module 接受或者拒绝特定的客户端请求
http_auth_basic_module HTTP基本认证,使⽤⽤户名和密码来限制对资源的访问
http_autoindex_module ⾃动索引,⽤于显示⽬录列表
http_browser_module 从 User-Agent 请求头中获取和识别客户端浏览器
http_charset_module 添加特定的字符集到 Content-Type 响应头中
http_empty_gif_module 返回⼀个1像素的透明GIF图⽚
http_fastcgi_module FastCGI⽀持
http_geo_module 从IP地址中获取地理位置信息
http_gzip_module Gzip压缩⽀持
http_limit_conn_module 限制并发连接数
http_limit_req_module 限制请求速率
http_map_module 从变量中获取值
http_memcached_module Memcached⽀持
http_proxy_module 反向代理⽀持
http_referer_module 防盗链
http_rewrite_module URL重写
http_scgi_module 转发请求到SCGI服务器
http_ssi_module 处理和⽀持SSI(Server Side Includes)
http_split_clients_module 根据客户端IP地址或者其他变量将客户端分配到组中,⼀般⽤于A/B测试
http_upstream_hash_module 启⽤⼀致性哈希负载均衡
http_upstream_ip_hash_module 启⽤IP哈希负载均衡
http_upstream_keepalive_module 启⽤⻓连接负载均衡
http_upstream_least_conn_module 启⽤最少连接负载均衡
http_upstream_zone_module 启⽤共享内存负载均衡
http_userid_module 为客户端设置⼀个唯⼀的ID(UID、cookie)
http_uwsgi_module 转发请求到uWSGI服务器,⼀般⽤于Python应⽤
posted @ 2024-03-07 11:28  韩续贤  阅读(84)  评论(0)    收藏  举报