本文為看視頻《Nginx入門到實(shí)踐》總結(jié)的學(xué)習(xí)筆記。
一、服務(wù)器基礎(chǔ)配置
遠(yuǎn)程鏈接服務(wù)器
ssh 用戶名@公網(wǎng)ip
默認(rèn)的用戶名是root,假如公網(wǎng) ip 是 a.b.c.d, 那鏈接命名就是
ssh root@a.b.c.d
下載安裝基礎(chǔ)庫(kù)
yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
yum -y install wget httpd-tools vim
關(guān)閉 iptables
查看iptables規(guī)則
iptables -L
或
iptables -t nat -L
關(guān)閉 iptables 規(guī)則
iptables -F
或
iptables -t nat -F
關(guān)閉 SELinux
查看是否打開
getenforce
關(guān)閉
setenforce 0
二、Nginx 簡(jiǎn)介及安裝
Nginx 是一個(gè)開源且高性能、高可靠的 HTTP 中間件、代理服務(wù)。
安裝Nginx
打開官網(wǎng) https://nginx.org/en/linux_packages.html#stable
To set up the yum repository for RHEL/CentOS, create the file named /etc/yum.repos.d/nginx.repo with the following contents:
[nginx] name=nginx repo baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/ gpgcheck=0 enabled=1
Replace “OS” with “rhel” or “centos”, depending on the distribution used, and “OSRELEASE” with “6” or “7”, for 6.x or 7.x versions, respectively.
三、安裝目錄及配置講解
3.1 安裝目錄講解
查看nginx的所有安裝目錄
rpm -ql nginx
然后得到如下配置
[root@ ~]# rpm -ql nginx
nginx日志輪轉(zhuǎn),用于logrotate服務(wù)的日志切割
/etc/logrotate.d/nginx
nginx主配置文件
/etc/nginx/nginx.conf
/etc/nginx
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
cgi配置相關(guān),fastcgi配置
/etc/nginx/fastcgi_params
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
編碼轉(zhuǎn)換映射轉(zhuǎn)化文件
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/win-utf
設(shè)置http協(xié)議的 Content-Type 與擴(kuò)展名對(duì)應(yīng)關(guān)系
/etc/nginx/mime.types
用于配置出系統(tǒng)守護(hù)進(jìn)程管理器管理方式
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug
/usr/lib/systemd/system/nginx-debug.service
/usr/lib/systemd/system/nginx.service
nginx模塊目錄
/etc/nginx/modules
/usr/lib64/nginx/modules
/usr/lib64/nginx
/usr/libexec/initscripts/legacy-actions/nginx
/usr/libexec/initscripts/legacy-actions/nginx/check-reload
/usr/libexec/initscripts/legacy-actions/nginx/upgrade
nginx服務(wù)的啟動(dòng)管理的終端命令
/usr/sbin/nginx
/usr/sbin/nginx-debug
nginx的手冊(cè)和幫助文件
/usr/share/doc/nginx-1.14.0
/usr/share/doc/nginx-1.14.0/COPYRIGHT
/usr/share/man/man8/nginx.8.gz
/usr/share/nginx
/usr/share/nginx/html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html
nginx 的緩存目錄
/var/cache/nginx
nginx日志目錄
/var/log/nginx
3.2 安裝編譯參數(shù)
命令 nginx -V 查看所有編譯參數(shù)
3.3 Nginx 默認(rèn)配置語(yǔ)法
| 參數(shù) | 說明 |
|---|---|
| user | 設(shè)置nginx服務(wù)的系統(tǒng)使用用戶 |
| worker_processes | 工作進(jìn)程數(shù)(一般與服務(wù)器核數(shù)保持一致) |
| rror_log | nginx的錯(cuò)誤日志 |
| pid | nginx服務(wù)啟動(dòng)時(shí)候pid |
| events -> worker_connections | 每個(gè)進(jìn)程允許最大連接數(shù) |
| events -> use | 工作進(jìn)程數(shù) |
nginx 的默認(rèn)配置文件
文件路徑 /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
可以去 /usr/share/nginx/html/index.html 修改默認(rèn)的展示頁(yè)面,也可以去 /usr/share/nginx/html/50x.html 修改錯(cuò)誤頁(yè)面。
修改后重啟 nginx
systemctl reload nginx.service
或
systemctl restart nginx.service
檢查 nginx 配置,結(jié)果出現(xiàn) successful 表示成功
nginx -t -c /etc/nginx/nginx.conf
重新加載配置
nginx -s reload -c /etc/nginx/nginx.conf
四、常見 Nginx 中間架構(gòu)
- 靜態(tài)資源WEB服務(wù)
- 代理服務(wù)
- 負(fù)載均衡調(diào)度器 SLB
- 動(dòng)態(tài)緩存
4.1 靜態(tài)資源WEB服務(wù)
配置語(yǔ)法-文件讀取
Syntax: sendfile on|off;
Default: sendfile off;
Context: http,server,location,if in location
引讀:--with-file-aio 異步文件讀取
配置語(yǔ)法- tcp_nopush
Syntax: tcp_nopush on|off;
Default: tcp_nopush off;
Context: http,server,location
配置語(yǔ)法- tcp_nodelay
Syntax: tcp_nodelay on|off;
Default: tcp_nodelay on;
Context: http,server,location
配置語(yǔ)法- 壓縮
Syntax: gzip_comp_level level;
Default: gzip_comp_level 1;
Context: http,server,location
Syntax: gzip_http_version 1.0|1.1;
Default: gzip_http_version 1.1;
Context: http,server,location
擴(kuò)展 Nginx 壓縮模塊
預(yù)讀 gzip 功能
http_gzip_static_module
應(yīng)用支持 gunzip 的壓縮方式
http_gunzip_module
瀏覽器緩存設(shè)置
配置語(yǔ)法 - expires
添加 Cache-Control、Expires 頭
Syntax:expires [modified] time;
expires epoch | max | off
Default: expires off;
Context: http, server, location, if in location
跨域
*表示允許所有的網(wǎng)站跨域,為了安全起見可以設(shè)置僅需要的網(wǎng)址
location ~ .*\.(htm|html)$ {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
root /opt/app/code
}
基于 http_refer 防盜鏈配置模塊
Syntax: valid_referers none | blocked | server_names | string...;
Default: -
Context: server, location,
4.2 代理服務(wù)
正向代理與反向代理的區(qū)別在于代理的對(duì)象不一樣
正向代理代理的對(duì)象是客戶端
反向代理代理的對(duì)象是服務(wù)端
配置語(yǔ)法
Syntax: proxy_pass URL
Default: -
Context: location,if in location,limit_except
URL 一般是以下三種
http://localhost:8080/uri/
https://192.168.1.1:8000/uri/
http://unix:/tmp/backend.socket:/uri/;
4.3 負(fù)載均衡
HttpIndex模塊
這個(gè)模塊提供一個(gè)簡(jiǎn)單方法來實(shí)現(xiàn)在輪詢和客戶端IP之間的后端服務(wù)器負(fù)荷平衡。
配置范例:
resolver 10.0.0.1;
upstream dynamic {
zone upstream_dynamic 64k;
hash $request_uri; #按照url的hash值來分配,同一個(gè)url分配到同一個(gè)服務(wù)器
server backend1.example.com weight=5;
server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
server 192.0.2.1 max_fails=3;
server backend3.example.com resolve;
server backend4.example.com service=http resolve;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
location / {
proxy_pass http://dynamic;
health_check;
}
}
狀態(tài)解釋
| 配置 | 說明 |
|---|---|
| down | 當(dāng)前的server暫時(shí)不參與負(fù)載均衡 |
| backup | 預(yù)留的備份服務(wù)器 |
| max_fails | 允許請(qǐng)求失敗的次數(shù) |
| fail_timeout | 經(jīng)過max_fails 失敗后,服務(wù)暫停的時(shí)間 |
| max_conns | 限制最大的接收的連接數(shù) |
調(diào)度算法
| 配置 | 說明 |
|---|---|
| 輪詢 | 按時(shí)間順序逐一分配到不停的后端服務(wù)器 |
| 加權(quán)輪詢 | weight值越大,分配到的訪問幾率越高 |
| ip_hash | 每個(gè)請(qǐng)求按照訪問IP的hash結(jié)果分配,這樣來自同一個(gè)ip固定訪問一個(gè)后端服務(wù)器 |
| url_hash | 按照訪問的URL的hash結(jié)果來分配請(qǐng)求,使每個(gè)URL定向到同一個(gè)后端服務(wù)器 |
| least_conn | 最少連接數(shù),哪個(gè)機(jī)器連接數(shù)少就分發(fā) |
| hash關(guān)鍵數(shù)值 | hash自定義的key |
4.4 緩存
緩存類型分類:客戶端緩存,代理緩存,服務(wù)端緩存
proxy_cache
Syntax: proxy_cache zone | off;
Default:
proxy_cache off;
Context: http, server, location
proxy_cache_path
Syntax: proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=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];
Default: —
Context: http
實(shí)例
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=cache_zone:10m max_size=10g inactive=60m use_temp_path=off;
map $request_method $purge_method {
PURGE 1;
default 0;
}
server {
...
location / {
proxy_pass http://backend;
proxy_cache cache_zone;
proxy_cache_key $uri;
proxy_cache_purge $purge_method;
# 當(dāng)分配的服務(wù)器出現(xiàn)50X 錯(cuò)誤時(shí)分配另一臺(tái)服務(wù)器
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504
}
}
五、Nginx深度學(xué)習(xí)
5.1 動(dòng)靜分離
upstream java_api{
server 127.0.0.1:8080;
}
server {
...
#匹配到j(luò)sp結(jié)尾的請(qǐng)求去請(qǐng)求服務(wù)器
location ~ \.jsp$ {
proxy_pass http://java_api;
index index.html index.htm;
}
#匹配到圖片資源返回本地的內(nèi)容
location ~ \.(jpg|png|gif)$ {
expires 1h;
gzip on;
}
}
5.2 Nginx 的 rewrite規(guī)則
作用:實(shí)現(xiàn) url 重寫以及重定向
使用場(chǎng)景:
-
URL 訪問跳轉(zhuǎn),支持開發(fā)設(shè)計(jì)
? 頁(yè)面跳轉(zhuǎn)、兼容性支持、展示效果等
SEO優(yōu)化
維護(hù)。后臺(tái)維護(hù)、流量轉(zhuǎn)發(fā)等
安全
語(yǔ)法
Syntax: rewrite regex replacement [flag];
Default: —
Context: server, location, if
If the specified regular expression matches a request URI, URI is changed as specified in the *replacement* string. The rewrite directives are executed sequentially in order of their appearance in the configuration file. It is possible to terminate further processing of the directives using flags. If a replacement string starts with “http://”, “https://”, or “$scheme”, the processing stops and the redirect is returned to a client.
An optional *flag* parameter can be one of:
-
last停止rewrite檢測(cè)
stops processing the current set of
ngx_http_rewrite_moduledirectives and starts a search for a new location matching the changed URI; -
break停止rewrite檢測(cè)
stops processing the current set of
ngx_http_rewrite_moduledirectives as with the break directive; -
redirect返回302臨時(shí)重定向,地址欄會(huì)顯示跳轉(zhuǎn)后的地址
returns a temporary redirect with the 302 code; used if a replacement string does not start with “
http://”, “https://”, or “$scheme”; -
permanent返回302永久重定向,地址欄會(huì)顯示跳轉(zhuǎn)后的地址
returns a permanent redirect with the 301 code.
The full redirect URL is formed according to the request scheme ($scheme) and theserver_name_in_redirect and port_in_redirect directives.
Example:
server { ... rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last; rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last; return 403; ... }
But if these directives are put inside the “/download/” location, the last flag should be replaced bybreak, or otherwise nginx will make 10 cycles and return the 500 error:
location /download/ { rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break; rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break; return 403; }
If a *replacement* string includes the new request arguments, the previous request arguments are appended after them. If this is undesired, putting a question mark at the end of a replacement string avoids having them appended, for example:
rewrite ^/users/(.*)$ /show?user=$1? last;
If a regular expression includes the “}” or “;” characters, the whole expressions should be enclosed in single or double quotes.
5.3 安全校驗(yàn) secure_link
指定并允許檢查請(qǐng)求的鏈接的真實(shí)性以及保護(hù)資源免遭未授權(quán)的訪問
限制鏈接生效周期
Syntax: secure_link expression;
Default: —
Context: http, server, location
Syntax: secure_link_md5 expression;
Default: —
Context: http, server, location
Example:
location /s/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri$remote_addr secret";
if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410;
}
...
}
5.3 geoip_module 模塊
基于 IP 地址匹配 MaxMind GeoIP 二進(jìn)制文件,讀取 IP 所在地域信息
安裝: yum install nginx-module-geoip
使用場(chǎng)景
- 區(qū)別國(guó)內(nèi)外做HTTP 訪問規(guī)則
- 區(qū)別國(guó)內(nèi)城市地域做 HTTP 訪問規(guī)則
5.4 配置 HTTPS
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
...
}
HTTPS 服務(wù)優(yōu)化
- 激活 keepalive 長(zhǎng)連接
- 設(shè)置 ssl session 緩存
server{
listen 443;
server_name 116.62.103.228 jeson.t.imooc.io;
keepalive_timeout 100;
ssl on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
index index.html index.htm;
location / {
root /opt/app/code;
}
}
5.5 Nginx 與 Lua 開發(fā)
Lua 是一個(gè)簡(jiǎn)潔、輕量、可擴(kuò)展的腳本語(yǔ)言
Nginx + Lua 優(yōu)勢(shì):充分的結(jié)合 Nginx 的并發(fā)處理 epoll 優(yōu)勢(shì)和 Lua 的輕量實(shí)現(xiàn)簡(jiǎn)單的功能且高并發(fā)的場(chǎng)景。
安裝
yum install lua
運(yùn)行 lua 有兩種方式:命令行和腳本
-
命令行模式
在命令行輸入 lua 開啟命令行交互模式 -
腳本模式
編寫
test.lua文件,執(zhí)行lua test.lua運(yùn)行
注釋
-- 行注釋
--[[
塊注釋
--]]
六、Nginx 常見問題
多個(gè) server_name 的優(yōu)先級(jí)
如果多個(gè)文件配置有相同的 server_name ,根據(jù)文件名先讀取到哪個(gè)文件就加載哪個(gè)文件的配置
location 匹配優(yōu)先級(jí)
= 進(jìn)行普通字符精確匹配,也就是完全匹配
^~ 表示普通字符匹配,使用前綴匹配
~ \~* 表示執(zhí)行一個(gè)正則匹配()
前兩種匹配到之后就不往下繼續(xù)匹配了,最后一種會(huì)繼續(xù)往下匹配,如果沒有匹配到,就用它的匹配。也就是前兩種優(yōu)先級(jí)比第三種高。
try_files 的使用
按順序檢查文件是否存在
location / {
try_files $uri $uri/ /index.php;
}
七、Nginx 性能優(yōu)化
7.1 文件句柄
文件句柄:linux\Unix 一切皆文件,文件句柄就是一個(gè)索引
設(shè)置方式:系統(tǒng)全局性修改,用戶局部性修改,進(jìn)程局部性修改
修改方法:
系統(tǒng)全局修改和針對(duì)用戶修改
vim /etc/security/limits.conf
加入以下代碼
# 給root用戶設(shè)置
root soft nofile 10000
root hard nofile 10000
# 給所有用戶全局設(shè)置
* soft nofile 10000
* hard nofile 10000
soft 不是強(qiáng)制性的,超過設(shè)置的值會(huì)提醒但不強(qiáng)制執(zhí)行;hard 會(huì)強(qiáng)制執(zhí)行
針對(duì)進(jìn)程修改
vim /etc/nginx/nginx.conf
添加以下代碼
worker_rlimit_nofile 20000
7.2 CPU 親和
查看當(dāng)前服務(wù)器的 CPU 個(gè)數(shù)
cat /proc/cpuinfo | grep "physical id"|sort|uniq|wc -l
查看 CPU 核數(shù)
cat /proc/cpuinfo | grep "cpu cores"|uniq
worker_processes = CPU 個(gè)數(shù) * CPU 核數(shù)
假如有 2 個(gè) CPU,每個(gè) CPU 有 8 核,那 worker_processes 應(yīng)該是16
打開 nginx 配置文件 vim /etc/nginx/nginx.conf
worker_processes 16;
worker_cpu_affinity auto;
然后刷新nginx配置 nginx -s reload -c /etc/nginx/nginx.conf
7.3 Nginx 的通用配置
user nginx;
worker_processes 1;
worker_cpu_affinity auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_rlimit_nofile 10000;
events {
use epoll;
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
charset utf-8;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
gzip_disable "MSIE [1-6]\.";
gzip_http_version 1.1;
include /etc/nginx/conf.d/*.conf;
}
八、基于 Nginx 架構(gòu)的安全
8.1 常見的惡意行為及防范手段
常見惡意行為:爬蟲行為和惡意抓取、資源盜用
常用防范手段:
基礎(chǔ)防盜鏈功能:目的不讓惡意用戶輕易爬取網(wǎng)站數(shù)據(jù)
secure_link_module: 提高數(shù)據(jù)安全性,對(duì)數(shù)據(jù)增加加密驗(yàn)證和失效性,適合核心重要數(shù)據(jù)
access_module: 對(duì)后臺(tái)、部分用戶服務(wù)的數(shù)據(jù)提供 IP 防控
8.2 常見的攻擊手段
后臺(tái)密碼撞庫(kù)
通過猜測(cè)密碼字段不斷對(duì)后臺(tái)系統(tǒng)登錄性嘗試,獲取后臺(tái)登錄密碼
防范手段:
- 后臺(tái)登錄密碼復(fù)雜度
- access_module 對(duì)后臺(tái)提供 IP 防控
- 預(yù)警機(jī)制
文件上傳漏洞
location ^~ /upload{
root /opt/app/images;
if($requst_filename ~*(.*)\.php){
return 403;
}
}
SQL 注入
利用未過濾/未審核用戶輸入的攻擊方法,讓應(yīng)用運(yùn)行本不應(yīng)該運(yùn)行的 SQL 代碼
Nginx + Lua 防火墻實(shí)現(xiàn):https://github.com/loveshell/ngx_lua_waf
以上就是 Nginx 學(xué)習(xí)筆記的全部?jī)?nèi)容。
作者正在組織寫一個(gè)有趣的開源項(xiàng)目 coderiver,致力于打造全平臺(tái)型全棧精品開源項(xiàng)目。
coderiver 中文名 河碼,是一個(gè)為程序員和設(shè)計(jì)師提供項(xiàng)目協(xié)作的平臺(tái)。無論你是前端、后端、移動(dòng)端開發(fā)人員,或是設(shè)計(jì)師、產(chǎn)品經(jīng)理,都可以在平臺(tái)上發(fā)布項(xiàng)目,與志同道合的小伙伴一起協(xié)作完成項(xiàng)目。
coderiver 河碼 類似程序員客棧,但主要目的是方便各細(xì)分領(lǐng)域人才之間技術(shù)交流,共同成長(zhǎng),多人協(xié)作完成項(xiàng)目。暫不涉及金錢交易。
計(jì)劃做成包含 pc端(Vue、React)、移動(dòng)H5(Vue、React)、ReactNative混合開發(fā)、Android原生、微信小程序、Angular、Node、Flutter、java后端的全平臺(tái)型全棧項(xiàng)目,歡迎關(guān)注。
目前已經(jīng)組建了幾十人的研發(fā)團(tuán)隊(duì),將致力于為大家提供最優(yōu)質(zhì)的開源項(xiàng)目。
項(xiàng)目地址:https://github.com/cachecats/coderiver
您的鼓勵(lì)是我前行最大的動(dòng)力,歡迎點(diǎn)贊,歡迎送小星星? ~