nginx 编译

moudels

https://nginx.org/en/download.html

-v 显示 nginx 的版本。

-V 显示 nginx 的版本,编译器版本和配置参数。

1
echo "加快编译: make -j$(cat /proc/stat | grep cpu[0-9] -c)"

openssl

ssl 功能需要 openssl 库

https://www.openssl.org/source/

1
2
3
 ./config 
make
make install>& LOG_install &

zlib

gzip 模块需要 zlib 库

https://www.zlib.net/current/zlib.tar.gz

1
2
3
./configure 
make
make install>& LOG_install &

pcre

rewrite 模块需要 pcre 库 nginx 1.21.5 开始,使用pcre2

pcre2 https://github.com/PCRE2Project/pcre2/releases

pcre https://sourceforge.net/projects/pcre/files/

install

nginx

1
2
3
src=/home/cs/other/modules/nginx/src/

./configure --prefix=/opt/nginx --with-pcre=$src/pcre2-10.42 --with-zlib=$src/zlib-1.3 --with-openssl=$src/openssl-3.2.0-alpha2 --with-stream --with-http_ssl_module

-add-dynamic-module=opt/nginx/moudels/nginx-accesskey-2.0.3

openresty

The first part of the OpenResty release version numbers is the version of the bundled NGINX core. For instance, OpenResty 1.7.10.2 bundles NGINX 1.7.10 while OpenResty 1.9.1.1 bundles NGINX 1.9.1.

1
2
3
4
5
6
src=/home/cs/other/modules/nginx/src/

./configure --prefix=/opt/proxy/openresty --without-http_memcached_module --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_v2_module --with-luajit --with-pcre-jit --with-stream=dynamic --with-http_geoip_module=dynamic --with-stream_geoip_module=dynamic --with-pcre=$src/pcre-8.45 --with-zlib=$src/zlib-1.3 --with-openssl=$src/openssl-3.2.0-alpha2 --with-http_random_index_module --add-dynamic-module=/opt/proxy/modules/nginx-accesskey-2.0.3 \

make -j6
make install

❯ tree ../openresty -L 1
 ../openresty
├──  bin
├──  COPYRIGHT
├──  luajit
├──  lualib
├──  nginx
├──  pod
├──  resty.index
└──  site

–with-http_random_index_module

https://github.com/openresty/headers-more-nginx-module?tab=readme-ov-file#installation

1
2
3
4
5
6
load_module  modules/ngx_http_headers_more_filter_module.so;

语法:
syntax:   random_index on | off
Default:   readom_index off;
Contenxt:  location

https://github.com/cjheath/geoip

1
2
3
4
5
sudo apt-get install libgeoip-dev

# CentOS
sudo yum install geoip-devel
sudo yum install nginx-module-geoip

https://blog.csdn.net/leiwuhen92/article/details/131379717

geoip https://www.miyuru.lk/geoiplegacy

1
2
3
4
5
6
7
8
9
# 国家数据库
wget https://dl.miyuru.lk/geoip/maxmind/country/maxmind.dat.gz -O GeoCountry.dat.gz
gzip -d -k GeoCountry.dat.gz
mv country.dat ./geoip/GeoCountry.dat

# 城市数据库
wget https://dl.miyuru.lk/geoip/maxmind/city/maxmind.dat.gz -O GeoCity.dat.gz
gzip -d GeoCity.dat.gz
mv GeoCity.dat ./geoip/GeoCity.dat

#引入地域ip文件

geoip_country /opt/proxy/modules/geoip/GeoCountry.dat;
geoip_city /opt/proxy/modules/geoip/GeoCity.dat;

-t 检测conf

1
❯ sudo /opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf -t

nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful

-s 重启

1
sudo /opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf -s reload

service

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
#!/bin/bash
#
# chkconfig: - 85 15
# description: Nginx is a World Wide Web server.
# processname: nginx
### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-De.ion: starts the nginx web server
# De.ion: starts nginx using start-stop-daemon
### END INIT INFO
nginx=/opt/nginx/sbin/nginx
conf=/opt/nginx/conf/nginx.conf
case $1 in
start)
echo -n "Starting Nginx"
$nginx -c $conf
echo " done"
;;
stop)
echo -n "Stopping Nginx"
killall -9 nginx
echo " done"
;;
test)
$nginx -t -c $conf
;;
reload)
echo -n "Reloading Nginx"
ps auxww | grep nginx | grep master | awk '{print $2}' | xargs kill -HUP
echo " done"
;;
restart)
$0 stop
$0 start
;;
show)
ps -aux|grep nginx
;;
*)
echo -n "Usage: $0 {start|restart|reload|stop|test|show}"
;;
esac

sudo cp /usr/local/nginx/nginx /etc/init.d/nginx

1
2
3
4
5
6
$>sudo chmod +x /etc/init.d/nginx

#初始化脚本
$> sudo /usr/sbin/update-rc.d -f nginx defaults
$> service nginx start
$> cat /usr/local/nginx/logs/nginx.pid

限流

ngx_http_limit_conn_module

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
http {

... ...#同一时刻只能一个请求连接会成功进行资源下载
limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
location /download/ {
limit_conn addr 1;
}
... ...#对某ip网段进行连接数限制

limit_conn_zone $ip_segment zone=network_segment:10m;

server {
... ...
set $ip_segment $remote_addr;

if ( $ip_segment ~ ^(\d+)\.(\d+)\.(\d+)\.(\d+) ) {
set $ip_segment $1.$2.$3;
}

location /download/ {
limit_conn network_segment 10;
#limit_rate 200k;
}

}
}
1
2
3
4
5
6
7
8
9
10
limit_conn_zone $binary_remote_addr zone=myip:10m;
limit_conn_zone $server_name zone=myServerName:10m;
}

server {
location / {
limit_conn myip 10;
limit_conn myServerName 100;
rewrite / http://xxxx permanent;
}

单个IP同时并发连接数最多只能10个连接,并且设置了整个虚拟服务器同时最大并发数最多只能100个链接。当然,只有当请求的header被服务器处理后,虚拟服务器的连接数才会计数

ngx_http_limit_req_module

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#定义限流维度,一个用户一分钟一个请求进来,多余的全部漏掉   1r/s代表1秒一个,1r/m一分钟接收一个请求
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/m;

#绑定限流维度
server{
.....
location /xx {
limit_req zone=zone;
##一个用户的请求会立即处理前五个,多余的就慢慢来落,没有其他用户的请求我就处理你的,有其他的请求的话我Nginx就漏掉不接受你的请求。
# limit_req zone=zone burst=5 nodelay;
proxy_pass http://xxxxx;
}

}

limit_req_zone #表示引用这个模块

$binary_remote_addr #是$remote_addr(客户端 IP)的二进制格式,也可以使用 $remote_addr,看了有好几种解释,都是说$binary_remote_addr 可以减少存储空间,所以尽量使用$binary_remote_addr

zone=index:10m #缓存区名称为 index(可随意定义)的占用空间大小为 10m

rate=1r/s #每秒执行一次

limit_req #表示引用上面配置的模块

zone=index #必须和上面第一句定义的名字一致,不然会出问题,

burst=2 #缓冲队列的长度,如果不加这个参数,同一时刻同一个 IP 进来了 2 个请求,有一个请求会马上回被 nginx 返回 503 报错

nodelay #意思是不延迟, 加了这个参数后,比如在同一个 IP 在同一个时间点进来了三个一样的请求,nginx 就会把这三个请求都立即处理掉。比如在下两秒中,这个 IP 又进来一个相同的请求,那就对不起了,nginx 就会立马返回错误,因为 nginx 在这三秒内已经处理了三次这个请求了。如果没加这个参数,nginx 就会严格执行 1 秒一次规则。在同一个时间点进来三个请求,nginx 在第一秒内先处理其中一个,接下来每秒处理一次请求。

漏桶算法

恒定速率的限流算法,不管请求量是多少,服务端的处理效率是恒定的(无法应对突发流量的来袭)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
long timeStamp = getNowTime(); 
int capacity = 10000;// 桶的容量
int rate = 1;//水漏出的速度
int water = 100;//当前水量

public static bool control() {
//先执行漏水,因为rate是固定的,所以可以认为“时间间隔*rate”即为漏出的水量
long now = getNowTime();
water = Math.max(0, water - (now - timeStamp) * rate);
timeStamp = now;

if (water < capacity) { // 水还未满,加水
water ++;
return true;
} else {
return false;//水满,拒绝加水
}
}

Sentinel 中的匀速排队限流策略,就采用了漏桶算法

令牌桶算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
long timeStamp=getNowTime(); 
int capacity; // 桶的容量
int rate ;//令牌放入速度
int tokens;//当前水量

bool control() {
//先执行添加令牌的操作
long now = getNowTime();
tokens = Math.max(capacity, tokens+ (now - timeStamp)*rate);
timeStamp = now; //令牌已用完,拒绝访问

if(tokens<1){
return false;
}else{//还有令牌,领取令牌
tokens--;
retun true;
}
}

限制外的数据包可以以不同的方式处理:
1)它们可以被丢弃;
2)它们可以排放在队列中以便当令牌桶中累积了足够多的令牌时再传输;
3)它们可以继续发送,但需要做特殊标记,网络过载的时候将这些特殊标记的包丢弃。

google开源工具包guava提供了限流工具类RateLimiter,该类基于“令牌桶算法

降级

nginx+lua+redis实现服务降级

目的是保证核心服务的高可用。过程就是丢卒保帅,有些服务是无法降级的,比如支付。

降级的种类

1.设置开关位置实现降级

根据降级的开关位置:分为服务代码降级和开关前置降级。
代码降级就是利用代码控制,这种方式比前置降级要low并不推荐;
前置降级是把降级开关放到http请求链路层的上游,降低链路层消耗。
比如提升到nginx,甚至可以提升到前端,当提升到前端,后端访问压力接近于0
拓展:【如何提升到前端】可以通过一个从服务器获取的js脚本进行控制。

2.读写降级

根据读写:分为读降级和写降级。
读降级,比如,读取动态数据,降级为读取静态数据。
写降级,比如,写入mysql,降级为写入消息队列, 等高峰期过后,再从队列写入mysql。

3.返回内容、限流、限速降级

根据降级的性质:分为返回内容降级,限流降级,限速降级。
返回内容降级,比如,返回实时数据,降级为返回静态缓存数据
限流降级,比如,1000个请求,我只接受500个。 这么做也是无奈之下选择,要不然系统崩了,谁都访问不了
限速降级,比如,对于那些访问过于频繁的ip进行限速
拓展:【限流限速】
nginx 自带限流限速模块,比如ngx_http_limit_req_module和ngx_http_limit_conn_module 。
但是这类模块只是提供了在nginx配置文件中进行简单的参数配置。
如果想更加灵活和功能更多,可以编写自己的lua代码进行控制,而不是用现成的模块进行配置文件修改。

4.手动和自动降级

手动降级,是人为看到系统负载异常后,手动调整降级;
自动降级,是系统监测到异常后自动降级,自动降级虽然更智能,但有时候自动脚本可能会干一些超乎预料的事情。

原文https://www.faxwo.com/active-script/linux/service-level-down.html#menu_index_3

点击打赏
文章目录
  1. 1. moudels
    1. 1.1. openssl
    2. 1.2. zlib
    3. 1.3. pcre
  2. 2. install
    1. 2.1. nginx
    2. 2.2. openresty
    3. 2.3. -t 检测conf
    4. 2.4. -s 重启
  3. 3. service
  4. 4. 限流
    1. 4.1. ngx_http_limit_conn_module
    2. 4.2. ngx_http_limit_req_module
    3. 4.3. 漏桶算法
    4. 4.4. 令牌桶算法
  5. 5. 降级
    1. 5.1. 降级的种类
      1. 5.1.1. 1.设置开关位置实现降级
      2. 5.1.2. 2.读写降级
      3. 5.1.3. 3.返回内容、限流、限速降级
      4. 5.1.4. 4.手动和自动降级
载入天数...载入时分秒... ,