Nginx通過geo模式實現限速白名單和全域性負載均衡 - 運維筆記

jj1130050965發表於2020-12-11

Nginx通過geo模式實現限速白名單和全域性負載均衡 - 運維筆記

 

Nginx的geo模組不僅可以有限速白名單的作用,還可以做全域性負載均衡,可以要根據客戶端ip訪問到不同的server。比如,可以將電信的使用者訪問定向到電信伺服器,網通的使用者重 定向到網通伺服器”,從而實現智慧DNS的作用。前面介紹過nginx域名訪問的白名單配置梳理,下面對nginx的geo模組使用做一梳理(參考Geo模組-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

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

geo指令是通過ngx_http_geo_module模組提供的。預設情況下,nginx安裝時是會自動載入這個模組,除非安裝時人為的手動新增--without-http_geo_module。

 

ngx_http_geo_module模組可以用來建立變數,其值依賴於客戶端IP地址。

 

geo指令

語法: geo [$address] $variable { ... }

預設值: —

配置段: http

定義從指定的變數獲取客戶端的IP地址。預設情況下,nginx從$remote_addr變數取得客戶端IP地址,但也可以從其他變數獲得。

 

例如:

geo $remote_addr $geo {

default 0;

127.0.0.1 1;

}

geo $arg_ttlsa_com $geo {

default 0;

127.0.0.1 1;

}

 

如果該變數的值不能代表一個合法的IP地址,那麼nginx將使用地址"255.255.255.255"

nginx通過CIDR或者地址段來描述地址,支援下面幾個引數:

1)delete:刪除指定的網路

2)default:如果客戶端地址不能匹配任意一個定義的地址,nginx將使用此值。 如果使用CIDR,可以用"0.0.0.0/0"代替default。

3)include: 包含一個定義地址和值的檔案,可以包含多個。

4)proxy:定義可信地址。 如果請求來自可信地址,nginx將使用其“X-Forwarded-For”頭來獲得地址。 相對於普通地址,可信地址是順序檢測的。

5)proxy_recursive:開啟遞迴查詢地址。 如果關閉遞迴查詢,在客戶端地址與某個可信地址匹配時,nginx將使用"X-Forwarded-For"中的最後一個地址來代替原始客戶端地址。如果開啟遞迴查詢,在客戶端地址與某個可信地址匹配時,nginx將使用"X-Forwarded-For"中最後一個與所有可信地址都不匹配的地址來代替原始客戶端地址。

6)ranges:使用以地址段的形式定義地址,這個引數必須放在首位。為了加速裝載地址庫,地址應按升序定義。

 

geo $country {

default ZZ;

include conf/geo.conf;

delete 127.0.0.0/16;

proxy 192.168.100.0/24;

proxy 2001:0db8::/32;

 

127.0.0.0/24 US;

127.0.0.1/32 RU;

10.1.0.0/16 RU;

192.168.1.0/24 UK;

}

 

# vim conf/geo.conf  //編輯conf/geo.cong檔案

10.2.0.0/16 RU;

192.168.2.0/24 RU;

 

地址段例子:

geo $country {

ranges;

default ZZ;

127.0.0.0-127.0.0.0 US;

127.0.0.1-127.0.0.1 RU;

127.0.0.1-127.0.0.255 US;

10.1.0.0-10.1.255.255 RU;

192.168.1.0-192.168.1.255 UK;

}

 

geo指令主要是根據IP來對變數進行賦值的。因此geo塊下只能定義IP或網路段,否則會報錯。

====================nginx利用geo模組做限速白名單操作======================

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

nginx的限速白名單需要結合geo和map指令來實現,map指令使用ngx_http_map_module模組提供的。預設情況下,nginx安裝時是會自動載入這個模組,除非安裝時人為手動新增--without-http_map_module。

ngx_http_map_module模組可以建立變數,這些變數的值與另外的變數值相關聯。允許分類或者同時對映多個值到多個不同值並儲存到一個變數中,map指令用來建立變數,但是僅在變數被接受的時候執行視

圖對映操作,對於處理沒有引用變數的請求時,這個模組並沒有效能上的缺失。

 

配置如下:

http {

 geo $whiteiplist  {

 default 1;

 127.0.0.1 0;

 192.0.0.0/8 0;

 103.20.102.0/24 0;

 }

   

 map $whiteiplist  $limit {

 1 $binary_remote_addr;

 "";

 }

   

 limit_conn_zone $limit zone=limit:10m;

   

 server {

        listen       80;

        server_name  test.huanqiu.com;

   

        location ^~ /download/ {

                limit_conn limit 4;

                limit_rate 200k;

                alias /data/www.huanqiu.com/data/download/;

        }

 }

}

 

 

------------------------如下是一個nginx中geo限速白名單的配置例項--------------------------

[root@localhost ~]# cat /usr/local/nginx/conf/vhosts/wangshibo.conf

geo $whiteiplist  {

 default 1;

 127.0.0.1 0;

 192.168.0.0/16 0;

 58.68.230.0/24 0;

 }

   

 map $whiteiplist  $limit {

 1 $binary_remote_addr;

 "";

 }

   

 limit_conn_zone $limit zone=limit:10m;

 

 server {

    listen 80;

    server_name dev.wangshibo.com wangshibo.com *.wangshibo.com;

    

    access_log  /usr/local/nginx/logs/8080-access.log main;

    error_log  /usr/local/nginx/logs/8080-error.log;

      

   

    location ~ / {

    root /var/www/html/8080;        

    index index.html index.php index.htm;

    }

 

    location ^~ /download/ {

          limit_conn limit 4;        //最大的併發連線數

          limit_rate 200k;           //每個連線的頻寬

          alias /data/wangshibo/download/;

        }

  }

 

 

配置要點解釋:

1)geo指令定義一個白名單$whiteiplist, 預設值為1, 所有都受限制。 如果客戶端IP與白名單列出的IP相匹配,則$whiteiplist值為0也就是不受限制。

2)map指令是將$whiteiplist值為1的,也就是受限制的IP,對映為客戶端IP。將$whiteiplist值為0的,也就是白名單IP,對映為空的字串。

3)limit_conn_zone和limit_req_zone指令對於鍵為空值的將會被忽略,從而實現對於列出來的IP不做限制。

 

測試方法

[root@localhost vhosts]# ab -c 100 -n 300  http://dev.wangshibo.com/download/docs/pdf/kevingarce.pdf

==============Nginx利用geo模組做負載均衡的操作記錄===============

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

本次測試的機器ip資訊如下:

 

server1: 113.110.86.28

server2: 113.110.86.25

server3: 188.84.155.239

 

客戶端1:113.110.86.23

客戶端2:113.110.86.51

客戶端3:113.110.86.19

 

三臺server機器上都部署了nginx環境,為了測試效果,特意配置了server1和server2的9090埠的首頁,如下:

[root@localhost ~]# curl http://113.110.86.28:9090

this is server1:113.110.86.28

 

[root@localhost ~]# curl http://113.110.86.25:9090

this is server2:113.110.86.25

 

配置server3,在server3上實現利用geo模組做負載均衡的目的,server3的nginx配置如下:

[root@localhost vhosts]# cat test.conf

geo $geo {

    default default;

    113.110.86.19/32   uk;

    113.110.86.51/32   us;

    }

 

#這裡我是單網測試,所以掩碼是32位;如果是vlan,可以是24位掩碼,比如:

# 113.110.86.0/24   tw;

 

    upstream  uk.server {

      server 113.110.86.28:9090;

    }

 

    upstream  us.server {

      server 113.110.86.25:9090;

    }

 

    upstream  default.server {

      server 188.84.155.239:9090;

    }

 

    server {

      listen    80;

      server_name 188.84.155.239;

      index index.html index.htm;

      root /var/www/html/80;

    

      location / {

      proxy_redirect off;

      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_pass http://$geo.server$request_uri;

      }

    }

   

    server {

      listen    9090;

      server_name 188.84.155.239;

 

      location / {

      root  /var/www/html/9090;

      index index.html index.htm;

      }

    }

 

 

訪問server3的9090埠

[root@localhost vhosts]# curl http://188.84.155.239:9090

this is server3:188.84.155.239

 

------------------------接下來就開始測試-------------------------

1)在客戶端1上訪問http://188.84.155.239,如下:

[root@localhost ~]# curl http://188.84.155.239

this is server3:188.84.155.239

 

因為客戶端1的IP地址為113.110.86.23,按照上面server3中nginx的配置,它訪問的很明顯是server3的9090埠!

 

2)在客戶端2上訪問http://188.84.155.239,如下:

[root@localhost ~]# curl http://188.84.155.239

this is server2:113.110.86.25

 

按照server3的nginx配置,客戶端2訪問server3的80埠就會被負載到server2的9090埠上!

 

3)在客戶端3上訪問http://188.84.155.239,如下:

[root@jenkins-server ~]# curl http://188.84.155.239

this is server1:113.110.86.28

 

按照server3的nginx配置,客戶端3訪問server3的80埠就會被負載到server1的9090埠上!

 

------------------------------------------------------------

通過上面的測試,很明顯能看到geo模組起到了負載均衡的作用。這樣就可以把三臺伺服器分別放到不同的IDC機房。然後在資料同步就可以了。

這樣做的好處就是省去了在DNS上做手腳,因為智慧DNS有時候按照來訪IP解析的時候會解析對方的DNS地址,把它匹配到一臺伺服器,如果對方是

網通使用者,它用的電信DNS,會直接把它匹配到電信的伺服器。而nginx的geo模組就是根據來訪問IP來匹配伺服器的,這樣只要我們把各地區的IP段收集起來就可以了~~

*************** 當你發現自己的才華撐不起野心時,就請安靜下來學習吧!***************

相關文章