基於Nginx的中間件架構
一、環境調試確認
四項確認
1、確認系統網絡
2、確認yum可用
3、確認關閉iptables規則
4、確認停用selinux
兩項安裝 yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake yum -y install wget httpd-tools vim
一次初始化 cd /opt;mkdir app download logs work backup 在opt裏新建幾個目錄
自己的Linux系統中(可以自己的模擬環境,也可以是服務器或者雲服務器):
首先: ping www.baidu.com ------------確認系統網絡 若有信息,則證明公網連通性是沒問題的
yum list|grep gcc ------------確認yum可用
查找並列出gcc樣源的軟件包
關閉iptables規則 ------------確認關閉iptables規則
iptables -L 查看是否有iptables規則
iptables -F 關閉iptables規則
iptables -t nat -F 一次性關閉nat裏的iptables規則
selinux命令 ------------確認停用selinux
getenforce 查看
setenforce 0 關閉
然後執行: 兩項安裝 + 一次初始化
基礎篇
Nginx的中間件架構
一、中間件
web請求 --> 中間件 --> 應用A --> 操作系統/硬件
web請求 --> 中間件 --> 應用A --> 中間件 --> 應用C
二、Nginx簡述
Nginx是一個開源的且高性能、可靠的HTTP中間件、代理服務。 1、高性能是支持海量併發的websever服務 2、可靠是說明服務穩定性良好,不會出現本身代碼問題而導致一些不可靠的因素,運行起來是穩定的 3、hppt中間件是企業裏應用最多的
三、常見的HTTP服務
HTTPD-Apache基金會 IIS-微軟 GWS-Google
四、爲什麼選擇nginx
原因1:IO多路複用epoll
io複用:解決的是併發性的問題,當多個用戶訪問網站,向服務器後臺而言會發起多個請求,處理多個併發的請求對於中間件會產生多個io流對應系統的讀寫,那麼多餘io流請求系統內核就會有並行處理和串行驅動的概念。 (如果用串行處理的方式的話會出現請求堵塞,因而採用並行處理方式,來完成io流的請求,以實現最大的併發和吞吐,這時候就用到了io複用技術。) io複用就是讓一個socket來完成整個io流的請求,如多線程的io複用方式。其他的io複用方式:
1、什麼是IO多路複用
對於io流,要獲取一組文件的描述符:application發起一個信號告訴系統內核要進行系統調用,當描述符還沒就緒的時候,內核會進入等待,當描述符就緒了之後,內核會返回一個信號給應用程序,告訴應用程序已經準備就緒了你可以進行系統調用了。
定義:多個描述符的I/O操作都能在一個縣城內併發交替地順序完成,這就叫做IO多路複用。
2、什麼是epoll
IO多路複用的實現方式select、poll、epoll 最早出現的是select 1)什麼是select?
前面說了,IO多路複用其實就是內核態當應用所需要文件對象就緒時,主動向應用發送文件就緒信息。而在應用第一次向系統發送系統調用之後到文件就緒之前的這段時間裏,在應用端都是堵塞(block)住對應的socket請求的,從而維護一個fd的列表。當內核發送就緒信息之後,應用端會不斷遍歷fd的列表以喚醒對應的進程完成對應的數據拷貝。在整個過程中select這種方式採用的是一個線性遍歷的方式。這種方式存在的一個問題是他會不斷的遍歷隊列裏的內容,因此效率很低。
缺點:1.能夠監視文件描述的數量存在最大限制(1024個) 2.線性掃描效率低
2)epoll模型 a)每當FD就緒,採用系統的回調函數之間將fd放入就緒的列表,效率更高 b)沒有最大連接數的限制
原因2:輕量級
一般說輕量級是指功能模塊少、代碼模塊化
功能模塊少:對於一些可以作爲插件的功能,一般不會繼承在nginx裏的。
代碼模塊化:可以對代碼的二次改進,對於開發人員友好。
原因3:cpu的親和(affinity)
nginx利用到cpu的親和從而來提升它的併發處理能力和對於cpu的工作執行效率、減少不必要的額外性能損耗。
1)爲什麼需要CPU親和?
首先說一下服務器配置,對於24、32、64核的服務器已經見怪不怪了,nginx作爲接入層的中間件,它對於CPU的親和尤爲重要。
如上圖,假如我Nginx有兩個CPU,而且每個CPU有四核,現在有worker1、worker2 ... worker8這樣的進程分別均勻地分配到不同的CPU核心上,減少額外的性能損耗。
CPU親和的含義:是一種把CPU核心和Nginx工作進程綁定方式,把每個worker進程固定在一個cpu上執行,從而減少切換cpu的cache miss,獲得更好的性能。
原因4:sendfile
nginx採用sendfile系統的工作機制處理靜態文件。
如圖,是一個http sever 文件傳輸圖。當我們請求一個文件的時候,文件要經過操作系統的內核空間,然後再到用戶空間,最後到達socket。然後纔到達用戶的客戶端。我們都知道靜態文件不會過多經過用戶空間的邏輯處理,直接進過內核空間。所以sendfile應用這一點,Linux2.2之後推出零拷貝的文件傳輸模式。
安裝Nginx(www.nginx.org/en/download.html)
一、Nginx快速搭建與基本參數使用
Mainline version-開發版 用於學習
Stable version-穩定版本
Legacy version-歷史版本
Source Code是Nginx的源代碼
Pre-Built Packages是包安裝的方式
pcp 源代碼的安全校驗
二、利用yum進行安裝
cd nginx/etc/yum
vim /etc/yum.repos.d/nginx.repo
內容:(注意更改操作系統是centos還是ubuntu,以及操作系統的版本號) [nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/7/$basearch/ gpgcheck=0 enabled=1 保存
列出nginx版本列表 yum list |grep nginx 如果有想要的版本就yum install nginx 然後一路確認 nginx -v 查看版本 nginx -V 查看一系列參數
三、基本參數使用
安裝目錄:
命令:
rpm -ql nginx 列出安裝nginx服務的哪些文件
路徑 | 類型 | 作用 |
---|---|---|
/etc/logrotate.d/nginx | 配置文件 | Nginx日誌輪轉,用於logrotate服務的日誌切割 |
/etc/nginx/nginx.conf | 主要起作用的配置文件 | |
/etc/nginx/conf.d | ||
/etc/nginx/conf.d/default.conf | 在沒有做變更的情況下,安裝後沒有.conf情況下起作用的文件,默認加載 | |
/etc/nginx/fastcgi_params | 配置文件 | cgi配置相關,fastcgi配置 |
/etc/nginx/uwsgi_params | ||
/etc/nginx/scgi_params | ||
/etc/nginx/koi-utf | 配置文件 | 編碼轉換映射文件 |
/etc/nginx/mine.types | 配置文件 | 設置http協議的Content—Type與擴展名對應關係,當nginx遇到不能識別的文件類型或者不能識別的擴展名的時候,就要配置這個文件,進行相應的添加 |
/usr/lib/systemd/system/nginx-debug.service | 配置文件 | 用於配置出系統守護進程管理器管理方式 |
/usr/lib/systemd/system/nginx.service | ||
/etc/sysconfig/nginx | ||
/usr/lib64/nginx/modules | 目錄 | Nginx模塊目錄 |
/etc/nginx/modules | ||
/usr/sbin/nginx | 命令 | Nginx服務的啓動管理的終端命令,用於Nginx的啓動關閉配置管理 |
/usr/sbin/nginx-debug /usr/share/doc/nginx-1.12.0 | 文件、目錄 | Nginx的手冊和幫助文件 /usr/share/doc/nginx-1.12.0/COPYRIGHT | |
/usr/share/man/man8/nginx.8.gz | | /var/cache/nginx | 目錄 | Nginx的緩存目錄。Nginx除了做代理服務,還可以做緩存服務 /var/log/nginx | 目錄 | Nginx的日誌目錄
logrotate:nginx實際上是對log進行服務的,logrotate實際上是對於nginx產生的日誌進行處理的,處理包括:1)對日誌進行輪轉 :如定義一個週期,按天進行輪轉,把一個日誌按天生成,說白了就是個日誌切割的系統服務 2)
Content-Type:是response中返回的數據的類型
編譯參數: 命令: nginx -V 查看編譯的參數,有哪些模塊
編譯選項 | 作用 |
---|---|
--prefix=/etc/nginx | 安裝目的目錄或路徑 |
--sbin-path=/usr/sbin/nginx | |
--modules-path=/usr/lin64/nginx/modules | |
--conf-path=/etc/nginx/nginx.conf | |
--error-log-pat=/var/log/nginx/error.log | |
--http-log-path=/var/log/nginx/access.log | |
--pid-path=/var/run/nginx.pid | |
--lock-path=/var/run/nginx.lock | |
--http-client-body-temp-path=/var/cache/nginx/client_temp | 執行對應模塊時,Nginx所保留的臨時性文件 |
--http-proxy-temp-path=/var/cache/nginx/proxy_temp | |
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp | |
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp | |
--http-scgi-temp-path=/var/cache/nginx/scgi_temp | |
--user=nginx | 設定Nginx進程啓動的用戶和組用戶 |
--group=nginx | |
--with-cc-opt=parameters | 設置額外的參數將被添加到CFLAGS變量 |
--with-ld-opt=parameters | 設置附加的參數,鏈接系統庫 |
Nginx基礎配置語法
nginx重啓命令:
systemctl restart nginx.service
systemctl reload nginx.service 柔和的重啓
nginx.conf:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request"'
'$status $body_bytes_sent "$http_refer"'
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/acess.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
<!-- 它包含了這個目錄下的以.conf結尾的文件,它的意思是把這個目錄下的*.conf的文件讀下來-->
include /etc/nginx/conf.d/*.conf;
}
default.conf:
server {
listen 80;
<!-- 域名 -->
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
<!-- 一個server裏面當沒有其他的訪問路徑的時候就採用/
訪問首頁或者子網頁-->
location / {
<!-- 設置root訪問的路徑爲這個-->
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 404 /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
#
}
HTTP請求
http 請求建立在tcp請求的基礎之上,每一個http請求包括:一個是客戶端發起的request請求,另一個是服務端發起的response相應,它們都會發送http報文:
request-包括請求行、請求頭部、請求數據
response-包括狀態行、消息報頭、響應正文
下面模擬一個請求:
登陸到Linux的服務器上
curl # 理解爲瀏覽器
輸入curl http://www.baidu.com
返回的是html頁面的代碼
加一個-v可以返回具體請求詳細信息內容,重定向到Linux的空設備裏:curl -v http://www.baidu.com > /dev/null
Nginx日誌類型
包括:
error.log 主要記錄處理http請求錯誤的狀態以及Nginx本身服務的運行狀態,按照不同的級別記錄到error.log裏。
access_log 記錄每一次http請求的訪問狀態,主要用於去分析每一次訪問的請求和客戶的交互,以及對行爲的進行一些分析。
Nginx怎麼實現的?
主要依賴於一個log_format的配置。Nginx.log裏面記錄了很多信息,而每一個信息可以理解爲一個變量,log_format就是將這些變量記錄到access_log裏面去
log_format語法:
Syntax:log_format name [escape=default|json] string ...;
Default:log_format combined "...";
Context:http
在Linux服務器上,vim nginx.conf
user nginx;
worker_process 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
........
http{
include /etc/nginx/mime.types;
......
<!--以下面這種格式打入到access_log裏面-->
log_format **main** '$remote_addr - $remote_user [$time_local] "$request'
......
access_log /var/log/nginx/access.log **main**;
<!-- main:表示以main的格式要求記錄到這個裏面 -->
.......
}
在服務器上輸入tail -f /var/log/nginx/error.log 查看nginx日誌文件
這就是error_log中打印的錯誤日誌信息的格式: 時間 錯誤級別 對應的錯誤代碼 :錯誤的描述以及用戶請求的信息
在服務器上輸入tail -f /var/log/nginx/access.log 查看nginx日誌文件
Nginx可以記錄的變量
** HTTP請求變量** - arg_PARAMERER、http_HEADER(request)、sent_http_HEADER(response)
舉例:
在服務器輸入 curl -v www.baidu.com
把內容輸入到dev/null之前先清理,已有的/etc/nginx/.nginx.conf.swp
然後vim /etc/nginx/nginx.conf
將log_format main 後$符號後的名字改爲需要日誌記錄的名字,大寫變小寫,-變_,如:
'$http_user_agent'
然後保存並退出(:wq)
輸入命令 nginx -t -c /etc/nginx/nginx.conf對配置文件進行前期的一個檢查,如果出現successful表示成功了
<!--nginx -t 表示文件的正確與否,-c表示配置文件的路徑-->
重載配置文件,輸入命令:nginx -s reload -c /etc/nginx/nginx.conf
查看nginx的進程:ps -aux|grep nginx
curl http://127.0.0.1:80
tail -n 200 /var/log/nginx/access.log
可以看到日誌的最前面是剛纔在nginx.conf裏配置log_format的$http-user-agent信息
**內置變量 - Nginx內置的**
nginx.org裏查詢,logging to syslog ->access_log ->log_format
對於log_format中簡要說明:
remote_addr 客戶端的地址
remote_user 客戶端請求nginx認證的用戶名,默認沒有開啓的話,那麼是不可進入的
time_local 表示是nginx的時間
status表示response返回的狀態
body_bytes_sent 服務端返回給客戶端,body中信息的大小
http_referer 是一個比較重要的記錄信息,在防盜鏈裏或者對用戶進行行爲分析的時候經常用到,表示上一級頁面的訪問地址
http_x_forwarded_for 每一級請求裏的對應的http信息
Nginx模塊
Nginx官方模塊
編譯選項 | 作用 |
---|---|
--with-http_stub_status_module | Nginx的客戶端狀態:連接狀態 |
Syntax:stub_status
Default:--
Context:server,location # 要配置在server/location下
vim /conf.d/default.conf
server {
listen 80;
sercer_name localhost;
#charser koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
定義自己的客戶端連接狀態
location /mystatus {
stub_status;
}
location / {
root /usr/share
}
}
然後檢查語法是否正確,然後重載服務:
nginx -tc /etc/nginx/nginx.conf
nginx -s reload -c /etc/nginx/nginx.conf
訪問 "你服務器的ip/mystatus",頁面會顯示
Active connections:2
server accepts handled requests
數字a 數字b 數字c
# a表示nginx總的握手次數 b表示處理的連接數 c表示總的連接數 正常的情況下握手數和連接數是要相等的,這表示它沒有丟失
Reading: 0 Writing:1 Waiting: 1
第三方模塊(未完待續)