為什麼選擇 Nginx
- 更快: 1)單次請求更快響應 2) 在高峰期比其他服務器更快響應
- 高擴展性: 1)由耦合度極低模塊組成 2)模塊皆嵌入到2進制文件中執行
- 高可靠性: 1)模塊穩定 2)進程相對獨立 3)worker出錯可快速輪替
- 低內存消耗: 1)10,000個非活躍 HTTP Keep-Alive 連接僅消耗 2.5 MB
- 高併發: 1)單機支援 100,000 以上連接
- 熱部署: 1)基於 master 與 worker 進程分離 2)服務不間斷下,進行升級可執行元件、配置及更換日誌
- BSD 許可協議
開發準備工作
必要
- Linux 內核版本 2.6 以上 (須靠 epoll 處理高併發)
- GCC 編譯器編譯 C 語言
非必要
- G++,用來編譯 C++ 以編寫 HTTP 模塊
- PCRE(Perl 兼容正則表達式),用來在配置文件中使用正則表達式,pcre-devel 是使用 PCRE 做二次開發所需
- zlib, 用來對 HTTP 內容做 gzip 壓縮,減少網路傳輸量
- OpenSSL,支持 SSL 協議,或想使用 MD5 或 SHA 雜湊
目錄結構
- 源代碼目錄
- 編譯中間文件(置於源碼目錄底下,命名為objs)
- 部署目錄(莫認為 /usr/local/nginx)
- 日誌目錄
Linux 內核參數優化
- 須要修改內核參數,使得 Nginx 可以擁有更高的性能
- 通常根據業務特性進行調整,作為內容服務器、反向代理,或是提供縮圖用的服務器,會做不同調整
通用高併發 /etc/sysctl.cnf 設置如下,執行 systcl -p 套用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
fs.file-max = 999999 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_max_tw_bucket = 5000 net.ipv4.ip_local_port_range = 1024 61000 net.ipv4.tcp_rmem = 4096 32768 262142 net.ipv4.tcp_wmem = 4096 32768 262142 net.core.netdev_max_back = 8096 net.core.rmem_default = 262144 net.core.wmem_default = 262144 net.core.rmem_max = 2097152 net.core.wmem_max = 2097152 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn.backlog = 1024 |
每個TCP連接都會為了維持滑動窗口而消耗內存(滑動窗口,接收方通過通告發送方自己的窗口大小,從而控制發送方的發送速度),參數 rmem_default
/wmem_default
/rmem_max
/wmem_max
須要衡量物理內存的總大小及最大連接數量 (worker_process
* worker_connections
) 來決定,滑動窗口過大可能導致 OOM,過小會影響大數據量的傳輸速度
編譯安裝 Nginx
下載源碼後,最簡單的安裝方式為執行以下3行指令:
./configure
: 1) 檢測系統內核及軟件 2) 解析參數 3) 生成中間目錄 4) 根據參數生成 C 源碼文件及 Makefile 文件make
: 1)使用生成的 Makefile 進行編譯 2) 生成目標文件及最終2進制文件make install
: 1) 根據參數將 nginx 部署到指定的安裝目錄 2) 複製二進制文件及配置文件
補充
以下是我練習使用的 dockerfile,按照書上指式的步驟在 centos 系統上安裝 nginx:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# ~/mynginx-dev/Dockerfile FROM centos:centos7 # Install requires RUN yum install -y gcc && \ yum install -y gcc-c++ && \ yum install -y pcre pcre-devel && \ yum install -y zlib zlib-devel && \ yum install -y openssl openssl-devel # Download source code RUN yum install -y wget && \ wget https://nginx.org/download/nginx-1.0.15.tar.gz && \ tar -zxvf nginx-1.0.15.tar.gz WORKDIR /nginx-1.0.15 # Compile Nginx RUN yum install -y make && \ ./configure && \ make && \ make install CMD ['bash'] |
你可以在目錄下執行以下指令來進入安裝 nginx 後的環境
1 2 3 4 |
$ docker build -t mynginx-dev . $ docker run -it mynginx-dev bash [root@de646f5219ee nginx-1.0.15]# |
編譯完後檢視編譯中間文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
[root@db37b79e9661 nginx-1.0.15]# tree /nginx-1.0.15/objs objs |-- Makefile |-- autoconf.err |-- nginx |-- nginx.8 |-- ngx_auto_config.h |-- ngx_auto_headers.h |-- ngx_modules.c # 定義運行時所有模組的優先順序,非常重要 |-- ngx_modules.o `-- src # 編譯產生的目標文件 |-- core | |-- nginx.o | |-- ngx_array.o | |-- ngx_buf.o | |-- ngx_conf_file.o | |-- ngx_connection.o | |-- ngx_cpuinfo.o | |-- ngx_crc32.o | |-- ngx_crypt.o | |-- ngx_cycle.o | |-- ngx_file.o | |-- ngx_hash.o | |-- ngx_inet.o | |-- ngx_list.o | |-- ngx_log.o | |-- ngx_md5.o | |-- ngx_murmurhash.o | |-- ngx_open_file_cache.o | |-- ngx_output_chain.o | |-- ngx_palloc.o | |-- ngx_parse.o | |-- ngx_queue.o | |-- ngx_radix_tree.o | |-- ngx_rbtree.o | |-- ngx_regex.o | |-- ngx_resolver.o | |-- ngx_shmtx.o | |-- ngx_slab.o | |-- ngx_spinlock.o | |-- ngx_string.o | `-- ngx_times.o |-- event | |-- modules | | `-- ngx_epoll_module.o | |-- ngx_event.o | |-- ngx_event_accept.o | |-- ngx_event_busy_lock.o | |-- ngx_event_connect.o | |-- ngx_event_pipe.o | |-- ngx_event_posted.o | `-- ngx_event_timer.o |-- http | |-- modules | | |-- ngx_http_access_module.o | | |-- ngx_http_auth_basic_module.o | | |-- ngx_http_autoindex_module.o | | |-- ngx_http_browser_module.o | | |-- ngx_http_charset_filter_module.o | | |-- ngx_http_chunked_filter_module.o | | |-- ngx_http_empty_gif_module.o | | |-- ngx_http_fastcgi_module.o | | |-- ngx_http_geo_module.o | | |-- ngx_http_gzip_filter_module.o | | |-- ngx_http_headers_filter_module.o | | |-- ngx_http_index_module.o | | |-- ngx_http_limit_req_module.o | | |-- ngx_http_limit_zone_module.o | | |-- ngx_http_log_module.o | | |-- ngx_http_map_module.o | | |-- ngx_http_memcached_module.o | | |-- ngx_http_not_modified_filter_module.o | | |-- ngx_http_proxy_module.o | | |-- ngx_http_range_filter_module.o | | |-- ngx_http_referer_module.o | | |-- ngx_http_rewrite_module.o | | |-- ngx_http_scgi_module.o | | |-- ngx_http_split_clients_module.o | | |-- ngx_http_ssi_filter_module.o | | |-- ngx_http_static_module.o | | |-- ngx_http_upstream_ip_hash_module.o | | |-- ngx_http_userid_filter_module.o | | |-- ngx_http_uwsgi_module.o | | `-- perl | |-- ngx_http.o | |-- ngx_http_busy_lock.o | |-- ngx_http_copy_filter_module.o | |-- ngx_http_core_module.o | |-- ngx_http_file_cache.o | |-- ngx_http_header_filter_module.o | |-- ngx_http_parse.o | |-- ngx_http_parse_time.o | |-- ngx_http_postpone_filter_module.o | |-- ngx_http_request.o | |-- ngx_http_request_body.o | |-- ngx_http_script.o | |-- ngx_http_special_response.o | |-- ngx_http_upstream.o | |-- ngx_http_upstream_round_robin.o | |-- ngx_http_variables.o | `-- ngx_http_write_filter_module.o |-- mail |-- misc `-- os |-- unix | |-- ngx_alloc.o | |-- ngx_channel.o | |-- ngx_daemon.o | |-- ngx_errno.o | |-- ngx_files.o | |-- ngx_linux_init.o | |-- ngx_linux_sendfile_chain.o | |-- ngx_posix_init.o | |-- ngx_process.o | |-- ngx_process_cycle.o | |-- ngx_readv_chain.o | |-- ngx_recv.o | |-- ngx_send.o | |-- ngx_setproctitle.o | |-- ngx_shmem.o | |-- ngx_socket.o | |-- ngx_time.o | |-- ngx_udp_recv.o | |-- ngx_user.o | `-- ngx_writev_chain.o `-- win32 |
安裝完後檢視部署目錄
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[root@db37b79e9661 nginx-1.0.15]# tree /usr/local/nginx /usr/local/nginx |-- conf | |-- fastcgi.conf | |-- fastcgi.conf.default | |-- fastcgi_params | |-- fastcgi_params.default | |-- koi-utf | |-- koi-win | |-- mime.types | |-- mime.types.default | |-- nginx.conf # 配置文件 | |-- nginx.conf.default | |-- scgi_params | |-- scgi_params.default | |-- uwsgi_params | |-- uwsgi_params.default | `-- win-utf |-- html | |-- 50x.html | `-- index.html |-- logs `-- sbin # 可執行文件 `-- nginx |
命令行控制
默認方式啟動二進制程序,不指定 -c
路徑的情況下,會套用默認的配置文件
1 2 |
/usr/local/nginx/sbin/nginx |
檢視程序
1 2 3 4 |
[root@db37b79e9661 nginx-1.0.15]# ps -ef | grep nginx root 31 1 0 12:41 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx nobody 32 31 0 12:41 ? 00:00:00 nginx: worker process |
關閉服務,使用 quit
參數則等待當前請求處理完畢才停止
1 2 3 4 5 6 |
/usr/local/nginx/sbin/nginx -s stop # equals kill -s SIGTERM <master pid> # equals kill -s SIGINT <master pid> |
1 2 3 4 |
/usr/local/nginx/sbin/nginx -s quit # equals kill -s SIGQUIT <master pid> |
運行中重新加載配置,指令會先檢查配置是否有誤,若通過則以 quit 方式重啟
1 2 3 4 |
/usr/local/nginx/sbin/nginx -s reload # equals kill -s SIGHUP <master pid> |
滾動升級 Nginx
- 發送訊號通知舊版服務
12kill -s SIGUSR2 <master pid> - 啟動新版本服務
- 以 quit 方式結束舊服務