LearningNginxadvancedfunctions, 企业级application, moduleDevelopment and containerizationdeployment, MasterNginx advancedusingtechniques
Nginx不仅仅 is a high performance Webserver, 它还providing了许 many advancedfunctions, 可以满足企业级application 各种requirements. 本tutorial将介绍Nginx advancedfunctions, includingmoduleDevelopment, 动态module, 第三方module, containerizationdeploymentetc. in 容, helping您充分发挥Nginx 潜力.
Nginx 1.9.11+ 引入了动态modulesupport, 允许 in 不重 new 编译Nginx circumstances under 加载 and 卸载module.
# 编译动态module
./configure --add-dynamic-module=path/to/module
make modules
# 加载动态module
load_module modules/ngx_http_geoip_module.so;
# 完整 nginx.confconfigurationexample
user nginx;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 加载动态module
load_module modules/ngx_http_geoip_module.so;
load_module modules/ngx_http_image_filter_module.so;
# otherconfiguration
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
server {
listen 80;
server_name example.com;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}
# installationngx_pagespeedmodule
wget https://github.com/apache/incubator-pagespeed-ngx/archive/v1.13.35.2-stable.zip
unzip v1.13.35.2-stable.zip
cd incubator-pagespeed-ngx-1.13.35.2-stable
wget https://dl.google.com/dl/page-speed/psol/1.13.35.2.tar.gz
tar -xzvf 1.13.35.2.tar.gz
# 编译Nginx并添加module
cd /path/to/nginx/source
./configure --add-module=/path/to/incubator-pagespeed-ngx-1.13.35.2-stable
make
make install
# configurationngx_pagespeedmodule
http {
pagespeed on;
pagespeed FileCachePath /var/cache/ngx_pagespeed;
server {
listen 80;
server_name example.com;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}
当Nginx in 置functions and 第三方module无法满足specificrequirements时, 您可以Development自定义module来scaleNginx functions. 自定义module可以implementationspecific 业务逻辑, 集成specific service, optimizationspecific 场景etc..
NginxmoduleDevelopment需要UnderstandClanguage and Nginx in 部structure. 以 under is a simple Hello Worldmoduleexample:
# modulesourcesfile: ngx_http_hello_module.c #include#include #include static char *ngx_http_hello(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r); static ngx_command_t ngx_http_hello_commands[] = { { ngx_string("hello"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, ngx_http_hello, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, ngx_null_command }; static ngx_http_module_t ngx_http_hello_module_ctx = { NULL, /* preconfiguration */ NULL, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ NULL, /* create server configuration */ NULL, /* merge server configuration */ NULL, /* create location configuration */ NULL /* merge location configuration */ }; ngx_module_t ngx_http_hello_module = { NGX_MODULE_V1, &ngx_http_hello_module_ctx, /* module context */ ngx_http_hello_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING }; static char *ngx_http_hello(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *clcf; clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); clcf->handler = ngx_http_hello_handler; return NGX_CONF_OK; } static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r) { if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; } ngx_int_t rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } ngx_str_t type = ngx_string("text/plain"); ngx_str_t response = ngx_string("Hello, Nginx!"); r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_type = type; r->headers_out.content_length_n = response.len; rc = ngx_http_send_header(r); if (rc != NGX_OK) { return rc; } ngx_buf_t *b = ngx_create_temp_buf(r->pool, response.len); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_memcpy(b->pos, response.data, response.len); b->last = b->pos + response.len; b->last_buf = 1; ngx_chain_t out; out.buf = b; out.next = NULL; return ngx_http_output_filter(r, &out); } # 编译module cd /path/to/nginx/source ./configure --add-module=/path/to/hello_module make make install # configurationmodule http { server { listen 80; server_name example.com; location /hello { hello; } } }
# installationOpenResty
sudo apt update
sudo apt install openresty
# OpenRestyconfigurationexample
# /usr/local/openresty/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
# usingLua脚本
location /lua {
content_by_lua_block {
ngx.say("Hello, OpenResty!")
ngx.say("Time: ", ngx.localtime())
}
}
}
}
usingDocker and KubernetesdeploymentNginx可以带来以 under 优势:
# Dockerfile FROM nginx:1.21-alpine # copyconfigurationfile COPY nginx.conf /etc/nginx/nginx.conf COPY default.conf /etc/nginx/conf.d/default.conf # copy静态file COPY html/ /usr/share/nginx/html/ # 暴露端口 EXPOSE 80 443 # 启动Nginx CMD ["nginx", "-g", "daemon off;"] # 构建镜像 docker build -t my-nginx . # runcontainers docker run -d --name nginx -p 80:80 -p 443:443 my-nginx # using卷持久化configuration and log docker run -d --name nginx \ -p 80:80 -p 443:443 \ -v /path/to/nginx.conf:/etc/nginx/nginx.conf \ -v /path/to/conf.d:/etc/nginx/conf.d \ -v /path/to/html:/usr/share/nginx/html \ -v /path/to/logs:/var/log/nginx \ nginx:1.21-alpine
# nginx-deployment.yaml
apiVersion: apps/v1
kind: deploymentment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21-alpine
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
- name: nginx-html
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-config
configMap:
name: nginx-config
- name: nginx-html
persistentVolumeClaim:
claimName: nginx-html-pvc
---
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: LoadBalancer
---
# nginx-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
default.conf: |
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
# applicationconfiguration
kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml
kubectl apply -f nginx-configmap.yaml
# 查看deploymentstatus
kubectl get deployments
kubectl get pods
kubectl get services
in 微servicearchitecturein, Nginx可以serving asAPIgateway, providing以 under functions:
# APIgatewayconfiguration
http {
# on 游service定义
upstream user_service {
server user-service:8080;
server user-service-backup:8080 backup;
}
upstream product_service {
server product-service:8080;
server product-service-backup:8080 backup;
}
upstream order_service {
server order-service:8080;
server order-service-backup:8080 backup;
}
# 速率限制configuration
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
listen 80;
server_name api.example.com;
# healthycheck端点
location /health {
return 200 "OK";
}
# userservicerouting
location /api/users {
limit_req zone=mylimit burst=20 nodelay;
proxy_pass http://user_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 产品servicerouting
location /api/products {
limit_req zone=mylimit burst=20 nodelay;
proxy_pass http://product_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 订单servicerouting
location /api/orders {
limit_req zone=mylimit burst=20 nodelay;
proxy_pass http://order_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
in 微servicearchitecturein, serviceinstance可能会动态添加 or delete, 需要service发现mechanism. Nginx可以 and 以 under service发现system集成:
# installationconsul-template
wget https://releases.hashicorp.com/consul-template/0.29.0/consul-template_0.29.0_linux_amd64.tgz
tar -xzvf consul-template_0.29.0_linux_amd64.tgz
sudo mv consul-template /usr/local/bin/
# Nginxconfiguration模板
# /etc/consul-template/nginx.ctmpl
upstream backend {
{{ range service "backend" }}
server {{ .Address }}:{{ .Port }};
{{ end }}
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# consul-templateconfiguration
# /etc/consul-template/config.hcl
template {
source = "/etc/consul-template/nginx.ctmpl"
destination = "/etc/nginx/conf.d/backend.conf"
command = "nginx -s reload"
}
# 启动consul-template
consul-template -config=/etc/consul-template/config.hcl -consul-addr=consul:8500
monitorNginx runstatus and performance指标 for 于确保service availability and stable 性至关 important . throughmonitor, 可以及时发现 and 解决issues, optimizationperformance, 预测潜 in 瓶颈.
# installationnginx-prometheus-exporter
git clone https://github.com/nginxinc/nginx-prometheus-exporter.git
cd nginx-prometheus-exporter
make build
# configurationNginxstatus页面
http {
server {
listen 80;
server_name localhost;
# status页面configuration
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
}
# 启动exporter
./nginx-prometheus-exporter -nginx.scrape-uri=http://localhost:80/nginx_status
# Prometheusconfiguration
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'nginx'
static_configs:
- targets: ['localhost:9113']
# Grafana仪表板
# importNginx仪表板: https://grafana.com/grafana/dashboards/9614
for 了确保Nginxservice high availability性, 可以adopts以 under solutions:
# installationKeepalived
sudo apt update
sudo apt install keepalived
# 主serverconfiguration
# /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100
}
}
# 备serverconfiguration
# /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100
}
}
# 启动Keepalived
sudo systemctl start keepalived
sudo systemctl enable keepalived
# 查看status
sudo systemctl status keepalived
ip addr show
fake设我们需要构建一个企业级Nginxarchitecture, 要求:
# 1. architecturedesign
# before 端: load balancing器 (such asAWS ELB or 阿里云SLB)
# in间层: Nginxcluster (2-4个instance, usingKeepalivedimplementationhigh availability)
# after 端: applicationservercluster
# 2. Nginxconfiguration
# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# logconfiguration
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time ut=$upstream_response_time';
access_log /var/log/nginx/access.log main buffer=32k flush=1m;
error_log /var/log/nginx/error.log warn;
# performanceoptimization
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# Gzip压缩
gzip on;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# on 游service
upstream backend {
least_conn;
server app1:8080 max_fails=3 fail_timeout=30s;
server app2:8080 max_fails=3 fail_timeout=30s;
server app3:8080 max_fails=3 fail_timeout=30s;
}
# HTTPSserver
server {
listen 443 ssl http2;
server_name example.com;
# SSLconfiguration
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# security头
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https://via.placeholder.com; connect-src 'self';";
# proxyconfiguration
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# healthycheck
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
# cacheconfiguration
proxy_cache_bypass $http_pragma;
proxy_cache_revalidate on;
proxy_cache_min_uses 1;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
}
# 静态file
location /static/ {
alias /usr/share/nginx/html/static/;
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
# healthycheck端点
location /health {
return 200 "OK";
}
}
# HTTP重定向 to HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
}
# 3. monitorconfiguration
# Prometheusconfiguration
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'nginx'
static_configs:
- targets: ['nginx1:9113', 'nginx2:9113']
- job_name: 'node'
static_configs:
- targets: ['nginx1:9100', 'nginx2:9100']
# 4. automationdeployment
# usingAnsibledeploymentNginx
# ansible-playbook.yml
- hosts: nginx_servers
become: yes
tasks:
- name: Install Nginx
apt:
name: nginx
state: present
- name: Copy Nginx configuration
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: restart nginx
- name: Copy SSL certificates
copy:
src: files/ssl/
dest: /etc/nginx/ssl/
notify: restart nginx
- name: Install nginx-prometheus-exporter
get_url:
url: https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v0.11.0/nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz
dest: /tmp/nginx-prometheus-exporter.tar.gz
- name: Extract exporter
unarchive:
src: /tmp/nginx-prometheus-exporter.tar.gz
dest: /usr/local/bin/
remote_src: yes
- name: Start exporter service
systemd:
name: nginx-prometheus-exporter
state: started
enabled: yes
handlers:
- name: restart nginx
systemd:
name: nginx
state: restarted
# 5. high availabilityconfiguration
# Keepalivedconfiguration
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100
}
track_script {
chk_nginx
}
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight 2
}
# healthycheck脚本
# /etc/keepalived/check_nginx.sh
#!/bin/bash
if [ -z "$(ps aux | grep nginx | grep -v grep)" ]; then
exit 1
else
exit 0
fi
这个企业级Nginxarchitecturepackage含以 under 特点:
1. 以 under 哪些 is Nginx advancedfunctions? ( many 选)
2. in 微servicearchitecturein, Nginxserving asAPIgateway可以providing哪些functions? ( many 选)
3. 以 under 哪些tool可以用于monitorNginx? ( many 选)
4. 实践练习: 构建high availabilityNginxarchitecture
请design并implementation一个high availabilityNginxarchitecture, 要求:
through本tutorial, 您已经Learning了Nginx advanced主题, including:
Nginx is a functions强 big , performance优异 Webserver and 反向proxyserver, 它 application场景非常广泛, from simple 静态网站 to complex 企业级application都可以usingNginx. 随着cloud native and 微servicearchitecture 兴起, Nginx important 性将会更加凸显.
希望本tutorialable tohelping您MasterNginx advancedusingtechniques, 充分发挥Nginx 潜力, for 您 applicationproviding high performance, high availability, security reliable service.