Nginx的反向代理與負載均衡


1.1 集群是什么

  簡單地說,集群就是指一組(若干個)相互獨立的計算機,利用高速通信網絡組成的一個較大的計算機服務系統,每個集群節點(即集群中的每台計算機)都是運行各自服務的獨立服器。這些服務器之間可以彼此通信,協同向用戶提供應用程序、系統資源和數據,並以單一系統的模式加以管理。當用戶客戶機請求集群系統時,集群給用戶的感覺就是一個單一獨立的服務器,而實際上用戶請求的是一組集群服務器。

  打開谷歌、百度的頁面,看起來好簡單,也許你覺得用幾分鍾就可以制作出相似的網頁,而實際上,這個頁面的背后是由成千上萬台服務器集群協同工作的結果。而這么多的服務器維護和管理,以及相互協調工作也許就是讀者你未來的工作職責了。

  若要用一句話描述集群,即一堆服務器合作做同一件事,這些機器可能需要整個技術團隊架構、設計和統一協調管理,這些機器可以分布在一個機房,也可以分布在全國全球各個地區的多個機房。

1.2 為什么要有集群

  高性能、價格有效性、可伸縮性、高可用性

  透明性、可管理性、可編輯性

1.2.1 集群種類

  負載均衡集群 LB 解決調度問題

  高可用集群  HA 解決單點故障問題(keeplived

  高性能計算集群         HP 、網絡計算集群 GC

1.2.2 硬件設備

  F5 設備   A10

1.2.3 軟件

  nginx (7層  1.9版本之后支持4層)、LVS (4層)、HAproxy (4層 7層)

1.2.4 負載均衡概念說明

  對用戶的訪問請求進行調度管理

  對用戶的訪問請求進行壓力分擔

 

1.2.5 反向代理

  接收用戶請求代替用戶向后端訪問

  反向代理與數據轉發的區別

1.2.6 壓力測試的方式

  ab (apache里的命令) 

  通過   yum install httpd-tools   獲得

1.3 nginx反向代理實踐

1.3.1 地址規划說明

HOSTNAME

IP

說明

lb01

10.0.0.5

Nginx 主負載服務器

lb02

10.0.0.6

nginx 輔負載服務器

web01

10.0.0.8

web01服務器

web02

10.0.0.7

web02服務器

web03

10.0.0.9

web03服務器

說明:以上為實際生產架構負載實現規划內容

ip命令說明

ip address show  查看ip地址
ip route show  查看路由信息

1.3.2 反向代理與數據轉發的區別

 

1.3.3 安裝部署nginx過程(安裝命令集)

yum install -y pcre-devel openssl-devel
mkdir -p /server/tools
cd /server/tools
wget -q http://nginx.org/download/nginx-1.10.3.tar.gz
ls -l nginx-1.10.3.tar.gz
useradd www -s /sbin/nologin -M
tar xf nginx-1.10.3.tar.gz
cd nginx-1.10.3
./configure  --user=nginx --group=nginx --prefix=/application/nginx-1.10.3 --with-http_stub_status_module  --with-http_ssl_module
make
make install
ln -s /application/nginx-1.10.3 /application/ngin

1.3.4 編寫nginx配置文件(統一web服務器配置)

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    server {
        listen       80;
        server_name  bbs.etiantian.org;
        location / {
            root   html/bbs;
            index  index.html index.htm;
        }
      access_log  logs/access_bbs.log  main;
    }        
    server {
        listen       80;
        server_name  www.etiantian.org;
        location / {
            root   html/www;
            index  index.html index.htm;
        }
        access_log  logs/access_www.log  main;
    }
}

1.3.5 統一nginx測試環境 (web文件)

mkdir -p /application/nginx/html/{www,bbs}
for name in www bbs; do echo $name `hostname` >/application/nginx/html/$name/xiaoxinxin.html;done
for name in www bbs; do cat /application/nginx/html/$name/xiaoxinxin.html;done

1.3.6 測試

[root@lb01 ~]# curl -H host:bbs.etiantian.org  10.0.0.8/xiaoxinxin.html
bbs web01
[root@lb01 ~]# curl -H host:bbs.etiantian.org  10.0.0.7/xiaoxinxin.html
bbs web02
[root@lb01 ~]# curl -H host:bbs.etiantian.org  10.0.0.9/xiaoxinxin.html
bbs web03
[root@lb01 ~]# curl -H host:www.etiantian.org  10.0.0.8/xiaoxinxin.html
www web01
[root@lb01 ~]# curl -H host:www.etiantian.org  10.0.0.7/xiaoxinxin.html
www web02
[root@lb01 ~]# curl -H host:www.etiantian.org  10.0.0.9/xiaoxinxin.html
www web03

1.3.7 配置負載服務文件

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;                                  
    upstream server_pools {
        server 10.0.0.7:80;
        server 10.0.0.8:80;
        server 10.0.0.9:80;
    } 
    server {
        listen 80;
        server_name bbs.etiantian.org;
        location / {
            proxy_pass http://server_pools;
        }
    }

1.3.8 測試訪問

[root@lb01 conf]# curl -H host:bbs.etiantian.org 10.0.0.5/xiaoxinxin.html
bbs web03
[root@lb01 conf]# curl -H host:bbs.etiantian.org 10.0.0.5/xiaoxinxin.html
bbs web02
[root@lb01 conf]# curl -H host:bbs.etiantian.org 10.0.0.5/xiaoxinxin.html
bbs web01

1.4 nginx中常用模塊說明

ngx_http_status_module
ngx_http_ssl_module
ngx_http_log_module
ngx_http_upstream_module
ngx_http_proxy_module

1.4.1 模塊調度算法

      ①. 定義輪詢調度算法-rr-默認調度算法

      ②. 定義權重調度算法-wrr

      ③. 定義靜態調度算法-ip_hash

      ④. 定義最小的連接數-least_conn

1.4.2 nginx反向代理相關兩個模塊

    upstream 模塊 類似與一個池塘,將nginx節點放置到池塘中

    proxy模塊  用池塘里面的nginx節點,利用pr oxy進行調用

1.4.3 upstream模塊核心參數簡介

    weight 權重

    max_fails 拋得次數

    fail_timeout 失敗的超時時間

    backup  備份

1.4.4 weight 參數實踐 (權重)

  upstream 模塊只能在http區塊里

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream server_pools{
         server 10.0.0.7:80 weight=1;
         server 10.0.0.8:80 weight=2;
    }
    server{
       listen 80;
       server_name bbs.etiantian.org;
       location / {
          proxy_pass http://server_pools;
       }
    }
}

測試

[root@test tools]# curl 10.0.0.5
web01 www
[root@test tools]# curl 10.0.0.5
web01 www
[root@test tools]# curl 10.0.0.5
web02 www
[root@test tools]# curl 10.0.0.5
web01 www
[root@test tools]# curl 10.0.0.5
web01 www
[root@test tools]# curl 10.0.0.5
web02 www

1.4.5 其他的參數說明

  max_fails    失敗的嘗試次數

  fail_timeout 失敗后的再次嘗試時間

  backup 備份節點:所有的節點都掛掉后數據才會請求web01

server 10.0.0.7:80 weight=1 max_fails=3 fail_timeout=10 ;
server 10.0.0.8:80 weight=2 max_fails=3 fail_timeout=10 backup;

測試,將web02停掉

[root@test tools]# curl 10.0.0.5
web02 www
[root@test tools]# curl 10.0.0.5
web02 www

停掉web02后

[root@test tools]# curl 10.0.0.5
web01 www
[root@test tools]# curl 10.0.0.5
web01 www
[root@test tools]# curl 10.0.0.5

1.4.6 訪問抓包

用戶請求報文

 

負載均衡請求報文

 

說明:

    hosts 主機頭不同,未配置proxy_set_header Host $host 參數,在負載均衡訪問的時候會不帶hosts信息。

1.4.7 upsrteam參數詳細說明

upstream模塊內參數

參數說明

server 10.0.10.8:80

負載均衡后面的RS配置,可以是IP或域名,如果端口不寫,默認是80端口。

高並發場景下, IP可換成域名,通過 DNS做負載均衡。

weigth=1

代表服務器的權重,默認值是1。權重數字越大表示接受的請求比例越大。

max_fails=3

Nginx嘗試連接后端主機失敗的次數,這個值是配合 proxy_next_upstreamfastcgi_next_upstreammemcached_next_upstream 這三個參數來使用的。當nginx接收后端服務器返回這三個參數定義的狀態碼時,會將這個請求轉發給正常工作的后端服務器,例如404502503 Max_fails的默認值是1 ;

企業場景下建議2-3次。如京東1次,藍汛10次,根據業務需求去配置

fail_timeout=10s

max_fails定義的失敗次數后,距離下次檢查的間隔時間,默認是10s ;如果max_fails5 ,它就檢測5次,如果5次都是502,那么,它就會根據fail_timeout的值,等待10s再去檢查,還是只檢查一次,如果持續502,在不重新加載 Nginx配置的情況下,每隔10s都只檢查一次。常規業務2~3秒比較合理,比如京東3秒,藍汛3秒,可根據業務需求去配置。

backup

熱備配置(RS節點的高可用),當前面激活的RS都失敗后會自動啟用熱備RS這標志看這個服務器作為備份服務器,若主服務器全部宕機了,就會向它轉發請求。

注意:當負載調度算法為ip_hash時,后端服務器在負載均衡調度中的狀態不能是weightbackup

down

這標志着服務器永遠不可用,這個參數可配合ip_hash使用;類似與注釋。

  weight :調節服務器的請求分配權重。1.4.8 上述命令的說明如下:

    📌check :開啟對該服務器健康檢查。

    📌inter:設置連續兩次的健康檢查間隔時間,單位毫秒,默認值2000。

    📌rise :指定多少次連續成功的健康檢查后,即可認定該服務器處於可用狀態。

    📌fall :指定多少次不成功的健康檢查后,即認為服務器為宕機狀態,默認值3。

    📌 maxconn :指定可被發送到該服務器的最大並發連接數。

雖然Nginx本身不支持一致性hash算法,但Nginx的分支Tengine支持。詳細可見http://tengine.taobao.org/document_cn/http_upstream_consistent_hash_cn.html

1.4.9 ip_hash 參數實踐

  每個訪問的用戶都會生成一個hash值。

      每個請求按客戶端 IP的 hash結果分配,當新的請求到達時,先將其客戶端 IP通過哈希算法哈希出一個值,在隨后的客戶端請求中,客戶IP的咍希值只要相同,就會被分配至同一台服務器,該調度算法可以解決動態網頁的session共享問題,但有時會導致請求分配不均,即無法保證1:1的負載均衡,因為在國內大多數公司都是NAT上網橫式,多個客戶端會對應_個外部IP ,所以,這些客戶端都會被分配到同一節點服務器,從而導致請求分配不均。

          LVS負載均衡的-p參數、Keepalived配置里的 persistence jimeout 50參數都類似這個 Nginx里的ip_hash參數,其功能都可以解決動態網頁的session共享問題。

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream server_pools{
            ip_hash;
         server 10.0.0.7:80;
         server 10.0.0.8:80;
    }
    server{
       listen 80;
       server_name bbs.etiantian.org;
       location / {
          proxy_pass http://server_pools;
       }
    }
}

1.4.10 least_conn 參數

  看誰閑,誰閑發送給誰

  least_conn算法會根據后端節點的連接數來決定分配情況,哪個機器連接數少就分發。

1.4.11 fair 參數

  看誰響應的快

  此算法會根據后端節點服務器的響應時間來分配請求,響應時間短的優先分配。這是更加智能的調度算法。此種算法可以依據頁面大小和加載時間長短智能地進行負載均衝,也就是根據后端服務器的響應時間來分配請求,響應時間短的優先分配。Nginx本身不支持fair調度算法,如果需要使用這種調度算法,必須下載Nginx的相關模塊upstream_fair。

示例如下:

upstream name {
server 192.168.1.1;
server 192.168.1.2;
fair;
}

  除了上面這些算法外,還有一些第三方調度算法,例如:url_hash、一致性hash算法等.

1.4.12 調度算法

  定義輪詢調度算法 rr 默認調度算法   平均分配

  定義權重調度算法 wrr

  定義靜態調度算法 ip-hash

  定義最小的連接數-least_conn

1.4.13 nginx負載均衡相關重要參數

Nginx反向代理重要參敎

解釋說明

proxy.pass http://server_pools; 

通過proxy_pass功能把用戶的清求轉向到反向代理定義的upstream服務器池

proxy_set_header Host $host

在代理向后端服務器發送的 http請求頭中加入 host字段信息,用於當后端服務器配置有多個虛擬主機時,可以識別代理的是哪個虛擬主機。這是節點服務器多虛擬主機時的關鍵配置

proxy_set_header X-ForwardedFor

$remote_addr;

在代理向后端服務器發送的 http請求頭中加入 X-Forward-For字段信息,用於后端服務器程序、日志等接收記錄真實用戶的 IP ,而不是代理服務器的 IP這是反向代理時,節點服務器獲取用戶真實 IP的必要功能配置

1.4.14 反向代理排錯思路

  01.先在lb01上訪問后端節點進行測試

  02.在lb01上訪問本地地址進行測試

  03.在瀏覽器上進行測試

          緩存、域名解析

1.4.15 proxy_next_uptream 參數

  當nginx接收后端服務器返回proxy_next_upstream 參數定義的狀態碼時,會將這個請求轉發給正常工作的后端服務器,例如500,502,503,504,此參數可以提升用戶的訪問體驗。

1.5 定義多個虛擬主機標簽信息

1.5.1 proxy_set_header 參數

配置文件

[root@lb01 conf]# cat nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream server_pools{
         server 10.0.0.7:80;
         server 10.0.0.8:80;
    }
    server{
       listen 80;
       server_name bbs.etiantian.org;
       location / {
          proxy_pass http://server_pools;
              proxy_set_header Host $host;
       }
    }
    server{
       listen 80;
       server_name www.etiantian.org;
       location / {
          proxy_pass http://server_pools;
               proxy_set_header Host $host;
       }
    }

}

訪問抓包

    該參數在負載服務器在訪問后端服務器的時候 會帶上hosts信息。

 

1.5.2 X-Forwarded-For 參數

  proxy_set_header X-Forwarded-For $remote_addr;

                  代理的啥時候在后面顯示真實的IP地址

[root@lb01 conf]# cat nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream server_pools{
         server 10.0.0.8:80;
         server 10.0.0.7:80;
         server 10.0.0.9:80;
    }
    server{
       listen 80;
       server_name bbs.etiantian.org;
       location / {
          proxy_pass http://server_pools;
             proxy_set_header Host $host; 
          proxy_set_header X-Forwarded-For $remote_addr;
       }
    }
    server{
       listen 80;
       server_name www.etiantian.org;
       location / {
          proxy_pass http://server_pools;
             proxy_set_header Host $host;
             proxy_set_header X-Forwarded-For $remote_addr;
       }
    }
    server{
       listen 80;
       server_name blog.etiantian.org;
       location / {
          proxy_pass http://server_pools;
             proxy_set_header Host $host;
             proxy_set_header X-Forwarded-For $remote_addr;
       }
    }

}

參看日志信息

1 10.0.0.5 - - [30/Oct/2017:12:36:10 +0800] "GET / HTTP/1.0" 200 10 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" "10.0.0.1"
2 10.0.0.5 - - [30/Oct/2017:12:36:10 +0800] "GET /favicon.ico HTTP/1.0" 404 571 "http://www.etiantian.org/" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" "10.0.0.1"

         該參數配置,會在訪問日志的后面加上真正的訪問用戶ip

1.5.3 http proxy 模塊相關參數說明

http proxy 模塊相關參數

 說明

proxy_set_header

設置http請求header項傳給后端服務器節點,例如:可實現讓代理后端的服務器節點獲取訪問客戶端用戶的真實IP地址

client_body_buffer_size

用於指定客戶端請求主體緩沖區大小

proxy_connect_timeout

表示反向代理后端節點服務器連接的超時時間,即發起握手等候響應的超時時間

proxy_send_timeout

表示代理后端服務器的數據回傳時間,即在規定時間內后端服務器必須傳完所有數據,否則nginx將斷開這個連接

proxy_read_timeout

設置nginx從代理的后端服務器獲取信息的時間,表示連接建立成功后,nginx等待后端服務器的響應時間,其實是nginx已經進入后端的排隊之中等候處理的時間

proxy_buffer_size

設置緩沖區大小,默認該緩沖區大小等於指令proxy_buffers設置的大小

proxy_buffers

設置緩沖區的數量和大小,nginx從代理的后端服務器獲取的響應信息,會設置到緩沖區

proxy_busy_buffers_size

用於設置相同很忙時可以使用的proxy_buffers大小,官方推薦的大小為 proxy_buffers * 2

proxy_trmp_file_write_size

指定proxy緩存臨時文件的大小

1.6.1 相據URL目錄地址轉發的應用場景1.6 基於目錄(uri)進行轉發--網站動靜分離

  根據HTTP的URL進行轉發的應用情況,被稱為第7層(應用層)的負載均衡,而LVS的負載均衡一般用於TCP等的轉發,因此被稱為第4層(傳輸層)的負載均衡。

  在企業中,有時希望只用一個域名對外提供服務,不希望使用多個域名對應同一個產品業務,此時就需要在代理服務器上通過配置規則,使得匹配不同規則的請求會交給不同的服務器池處理。這類業務有:

  📈 業務的域名沒有拆分或者不希望拆分,但希望實現動靜分離、多業務分離,

  📈 不同的客戶端設備(例如:手機和 PC端)使用同一個域名訪問同一個業務網站,就需要根 據規則將不同設備的用戶請求交給后端不同的服務器處理,以便得到最佳用戶體驗。

  

1.6.2 第一個里程碑: 服務器規划

目錄(uri

ip

服務器目錄

類型

/upload

10.0.0.8:80

html/www/upload

upload服務器

/static

10.0.0.7:80

html/www/static

static靜態服務器

/

10.0.0.9:80

html/www

默認

1.6.3 第二個里程碑:創建/設置upstream負載信息

upstream upload_pools {
  server 10.0.0.8:80;
}
upstream static_pools {
  server 10.0.0.7:80;
}
upstream default_pools {
  server 10.0.0.9:80;
}

1.6.4 第三個里程碑:如何調用upstream信息

location /static/ { 
    proxy_pass http://static_pools;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
}
 location /upload/ { 
    proxy_pass http://upload_pools;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
}
 location / { 
    proxy_pass http://default_pools;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
}

1.6.5 第四個里程碑: 編寫配置文件lb01

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';                      
    upstream upload_pools {
      server 10.0.0.8:80;
    }

    upstream static_pools {
      server 10.0.0.7:80;
    }

    upstream default_pools {
      server 10.0.0.9:80;
    }

    server {
        listen 80;
        server_name www.etiantian.org;
    location /static/ { 
        proxy_pass http://static_pools;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
    }

        location /upload/ { 
            proxy_pass http://upload_pools;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
    }

     location / { 
            proxy_pass http://default_pools;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
         access_log  logs/access_www.log  main;
    }
}

1.6.6 第五個里程碑: 創建環境

www.etiantian.org/xxx.html
www.etiantian.org/upload/xxx.html
www.etiantian.org/static/xxx.html 

##web01

mkdir -p /application/nginx/html/www/upload
echo  "web01 upload" >/application/nginx/html/www/upload/xxx.html 

##web02

mkdir -p /application/nginx/html/www/static
echo  "web02 static" >/application/nginx/html/www/static/xxx.html 

##web03

echo  "web03 default" >/application/nginx/html/www/xxx.html

1.6.7 第六個里程碑: 進行測試

[root@lb01 conf]# curl -H  host:www.etiantian.org  10.0.0.5/upload/
web01 upload:/application/nginx/html/www/upload
[root@lb01 conf]# curl -H  host:www.etiantian.org  10.0.0.5/static/
web02,/application/nginx/html/www/static
[root@lb01 conf]# curl -H  host:www.etiantian.org  10.0.0.5/
web03 www

瀏覽器進行訪問測試

  

1.7 根據客戶端的設備實現轉發(user_agent)

1.7.1 user_agent的應用

 

1.7.2 修改lb01配置文件 

 1 worker_processes  1;
 2 events {
 3     worker_connections  1024;
 4 }
 5 http {
 6     include       mime.types;
 7     default_type  application/octet-stream;
 8     sendfile        on;
 9     keepalive_timeout  65;
10     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
11                       '$status $body_bytes_sent "$http_referer" '
12                       '"$http_user_agent" "$http_x_forwarded_for"';
13                                     
14     upstream upload_pools {
15       server 10.0.0.8:80;
16     }
17 
18     upstream static_pools {
19       server 10.0.0.7:80;
20     }
21 
22     upstream default_pools {
23       server 10.0.0.9:80;
24     }
25 
26     server {
27         listen 80;
28         server_name www.etiantian.org;
29         location / {
30          if ($http_user_agent ~* "MSIE")
31           {
32             proxy_pass http://static_pools;
33           }
34          if ($http_user_agent ~* "Chrome")
35           {
36             proxy_pass http://upload_pools;
37           }
38         proxy_pass http://default_pools;
39            proxy_set_header Host $host;
40                }
41          access_log  logs/access_www.log  main;
42     }
43 }
View Code lb01配置文件

1.7.3 進行測試

  基於上一步的操作,現在可以之間的進行訪問測試

curl -A 指定訪問類型

[root@lb01 conf]# curl -A MSIE -H host:www.etiantian.org 10.0.0.5
web02 www
[root@lb01 conf]# curl -A Chrome -H host:www.etiantian.org 10.0.0.5
web01 www
[root@lb01 conf]# curl -A xx -H host:www.etiantian.org 10.0.0.5
web03 www

1.8 利用擴展名進行轉發

利用后綴名進行轉發與nginx中的基於后綴的轉跳一樣實現。

location ~.*.(gif|ipg|jpeg|png|bmp|swf|css|js)$ {
        proxy_pass http://static_pools;
           include proxy.conf
}

 本文出自“慘綠少年”,歡迎轉載,轉載請注明出處!http://blog.znix.top

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM