【從零開始搭建後端微服務架構】-02-系統的入口

每一個系統都需要有一個供用戶進入的入口,這個入口一般是用來接通公網和內網的通道。它是系統流量的總入口也是系統最前端的哨兵。本篇主要介紹從用戶發起請求到負載均衡層的設計。

背景

系統入口的業務

當前系統與外部交互的場景有兩個:

1.與終端的交互

當前系統終端有app端(andriod,ios)web端。所有終端主要都通過http協議與服務端交互。

2.與外部系統的交互

當前系統從某種意義上講也是一個大的數據中臺,有可能是提供接口由外部系統調我們接口灌輸進來,也可能是我們需要提供接口供外部系統取用數據

流量體量分析

當前系統的流量灌輸主要有以下幾個方面:

1.外部數據的導入

外部數據會定時從各個地方匯聚到本系統,本場景下流量穩定,不會有流量激增。數據匯聚的頻率具體要看每種數據的提供方,但總體來說並不會有很大的流量,唯一有高流量的位置在接收物聯網設計的信息,暫定這一塊的會產生100次每秒的併發。

2.用戶行爲

C端,B端,G端用戶使用本產品所產生的流量,這部分流量應該從兩方面來分析,一方面是預期行爲產生的流量,另一方面是非預期行爲產生的流量。

預期行爲指的是用戶在正常使用產品時產生的流量,比如查看首頁,修改個人信息,查看藥品信息等,這些行爲極少會產生突增的流量傾瀉,一般是依賴用戶數量的增長而增長,依照業務方提供的信息,該企業服務過1億左右的人,擁有多次消費的忠實用戶大約有三百萬人。經過業務的測算並考慮到以後的增長,我們以10倍的體量來設計,暫時認定本系統用戶基數爲3000W,每日產生2000萬pv

非預期行爲指如秒殺,爆款,明星離婚帶來的不確定性用戶行爲,可能會在某個時間突然激增,這些流量可能會是我們預知的,比如秒殺。也可能是我們未知的比如突然出現爆款等。這些行爲的流量就不好測算了,但是要求我們的系統擁有在突發情況下的緊急應對辦法。

概要設計

這裏我們主要討論請求到達後端之後的流程,前端和app端的不做考慮。

針對如上的需求,我的設計是入口層分兩部分:第一步分爲http請求的輸入,這一部分主要是用戶行爲產生的流量,包括預期性性和非預期性行爲,請求首先到達第一層負載均衡器lvs,然後再由lvs轉發到不同的第二層負載均衡器nginx上,nginx部分分爲集羣A和集羣B,分別用來處理預期性行爲和非預期性行爲;第二部分爲netty服務,用來接收各種各樣協議類型的物聯網數據。

                                             

 

詳細設計

業務要求架構要能適應系統的野蠻生長,所以我整體上採用了兩層負載的方案去設計。詳細設計分爲三個模塊:1.第一層負載lvs 2.第二層負載nginx 3.netty服務

第一層負載lvs

對於nginx相信很多人都瞭解,但是對於lvs可能很多人都不熟悉。它與nginx相同,都是一個開源的軟件,但不同點是它是基於的四層負載,而nginx是基於七層負載。我們用lvs做第一層負載,將請求負載到不同的nginx上。這樣可以讓二層的nginx做水平擴展。並且可以讓每個nginx在功能上有所區分,比如nginx1負責業務1,nginx2負載業務2。這樣架構就更加靈活了,可以讓各個業務互不影響。比如出現秒殺場景時,可以在秒殺開始前增加秒殺場景nginx,即使沒來得及增加設備,當前nginx掛掉,其他業務線也可以穩定運行。

*關於四層負載和七層負載這裏簡單講解下:

osi網絡分層將網絡協議分爲了七層,從下到上分爲物理層,數據鏈路層,網絡層,傳輸層,會話層,表示層,應用層。每一層都有不同的協議,四層負載是指負載均衡器是根據前四層的協議來決定請求如何分發,也就是基於IP,TCP,IP等協議,根據ip加端口來決定請求如何分發,常見的有lvs和f5。它的速度比七層負載要快,因爲不需要再解析請求的5,6,7層協議。七層負載指負載均衡器是根據前七層的協議來決定請求如何分發,常見的有nginx,apache。可以根據具體的應用層協議來決定如何轉發請求,功能更多更靈活,但是效率要低於四層負載。

在這一層我們準備兩臺騰訊雲服務器,採用lvs+keepalive來構建一個高可用的第一層負載。

第二層負載均衡nginx

這裏我們需要配置兩套nginx,一套用來接收用戶預期性行爲,一套用來接收非預期性的行爲。由於在上一層我們使用了lvs,所以我們這一層的nginx可以水平擴容的,它的伸展性特別好,可以根據業務類型新增nginx(新開一條業務線,如果想讓這條業務線與其他業務線隔絕,可以爲這條業務線新加一套nginx),也可以根據流量大小橫向擴展已經存在的nginx集羣。

下面我們開始搭建我們的nginx:

1.安裝nginx所需要的環境

yum -y install gcc pcre-devel zlib-devel openssl openssl-devel

2.安裝nginx

由於nginx是源碼包,所以需要編譯安裝,依次執行下面的命令

./configure --prefix=/usr/local/nginx
make
make install

安裝完成後會在/usr/local/nginx目下下生成如下目錄

cd /usr/loca/nginx/ ---進入安裝目錄
./sbin/nginx -t     ---檢測是否安裝成功

如果出現如下輸出證明安裝成功

安裝成功後我們可以啓動nginx啦

/usr/local/nginx/sbin/nginx  --啓動nginx

啓動成功後我們可以在瀏覽器輸入nginx所在機器的ip來訪問了(nginx默認監聽80端口,所以直接ip訪問即可)

上圖爲訪問ip之後出現的頁面,說明我們的nginx已經沒有問題了。

下面爲了讓我們的nginx更加可靠,我們還需要再對nginx做一些配置,附上我的nginx配置文件(負載均衡服務器數量還沒有確定,後面根據壓測結果確定最終節點數)。

集羣A的nginx.conf文件



#######################################################################################
################這裏暫時只有一臺服務器,大家見諒#######################################
#######################################################################################
#user  nobody;

#設置worker進程的數量,這裏設置成於cpu相同
worker_processes  2;

##設置錯誤日誌的輸出級別爲warn,減輕日誌輸出的壓力
error_log  logs/error.log warn;
##設置pid文件路徑
pid        logs/nginx.pid;


events {
    ##使用epoll模型,linux下建議使用epoll
    use epoll;
	##每個worker線城所能接受的最大連接數
    worker_connections  50000;
	##設置網路連接序列化,防止驚羣現象發生,默認爲on。
	##如果當前機器的worker線城很多的話可以選擇置爲off,但如果只有幾個work線程的話建議爲on,當前設爲on。
    accept_mutex on;   

}


####################################################################################################################
################對於輪詢算法的選擇這裏推薦:當集羣中的機器配置都一致時採用輪詢即可##################################
################如果配置不同則採用權重算法,調高配置高的機器的權重。同時如果發送到##################################
################服務的請求有很多比較耗時,可以採用第三方模塊nginx-upstream-fair#####################################
####################################################################################################################


http {
    ##設定mime類型,類型由mime.type文件定義
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #開啓自定義錯誤頁面,如果當前是做反向代理的,那必須加這個配置才能自定義錯誤頁面
    proxy_intercept_errors on;


    ##疫苗集羣地址,這裏爲疫苗服務設置了5臺機器,因爲這裏是主打業務。
    upstream vaccine-cluster{
	    ##這裏採用默認的輪詢算法即可
	    server 172.17.16.4:8021 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8022 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8023 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8024 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8025 max_fails=5 fail_timeout=600s;
    }
    ##樣本集羣地址
    upstream specimen-cluster{
	    ##這裏採用默認的輪詢算法即可
	    server 172.17.16.4:8031 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8032 max_fails=5 fail_timeout=600s;
    }

    ##血液集羣地址
    upstream blood-cluster{
	    ##這裏採用默認的輪詢算法即可
	    server 172.17.16.4:8041 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8042 max_fails=5 fail_timeout=600s;
    }

    ##健康管理集羣地址,這裏爲健康管理服務設置了5臺機器,因爲這裏是主打業務。
    upstream healthy-cluster{
	    ##這裏採用默認的輪詢算法即可
	    server 172.17.16.4:8051 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8052 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8053 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8054 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8055 max_fails=5 fail_timeout=600s;
    }


    ##用戶集羣地址,用戶基數比較多,設置了三臺
    upstream user-cluster{
	    ##這裏採用默認的輪詢算法即可
	    server 172.17.16.4:8061 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8062 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8063 max_fails=5 fail_timeout=600s;
    }
    
    ##靜態資源服務器
    upstream static-cluster{
	    ##這裏採用默認的輪詢算法即可
	    server 172.17.16.4:8071 max_fails=5 fail_timeout=600s;
	    server 172.17.16.4:8072 max_fails=5 fail_timeout=600s;
    }


	##只提供80端口的監聽
    server {
        listen       80;
        server_name  localhost;
		
		##設置編碼爲utf-8
        charset utf-8;
		
		##開啓訪問日誌,用來更好的統計用戶訪問數據
        access_log  logs/host.access.log  main;
		
		##匹配疫苗服務相關請求
        location ^~/vaccine {
            proxy_pass http://vaccine-cluster;
			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_connection_timeout 30s;
			proxy_send_timeout 30s;
			proxy_read_timeout 30s;
        }
		
		##匹配樣本服務相關請求
        location ^~/specimen {
            proxy_pass http://specimen-cluster;
			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_connection_timeout 30s;
			proxy_send_timeout 30s;
			proxy_read_timeout 30s;
        }
		
		##匹配血液服務相關請求
        location ^~/blood {
            proxy_pass http://blood-cluster;
			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_connection_timeout 30s;
			proxy_send_timeout 30s;
			proxy_read_timeout 30s;
        }
		
		##匹配健康管理服務相關請求
        location ^~/healthy {
            proxy_pass http://healthy-cluster;
			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_connection_timeout 30s;
			proxy_send_timeout 30s;
			proxy_read_timeout 30s;
        }
		
		##匹配用戶服務相關請求
        location ^~/user {
            proxy_pass http://user-cluster;
			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_connection_timeout 30s;
			proxy_send_timeout 30s;
			proxy_read_timeout 30s;
        }
		
		##匹配數據拉取服務相關請求
        location ^~/transfer {
            proxy_pass http://172.17.16.4:8010;
			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_connection_timeout 30s;
			proxy_send_timeout 30s;
			proxy_read_timeout 30s;

        }

		##狀態監控
		location /status {
          stub_status                 on;
          access_log                  off;
		  ##設置允許的ip,只有127.0.0.1和172.16.100.71兩臺服務器可以訪問狀態監控
          allow                       127.0.0.1;
		  ##設置允許的ip,只有127.0.0.1和172.16.100.71兩臺服務器可以訪問狀態監控
          allow                       172.16.100.71;
		  ##禁止訪問,配合allow可以起到白名單的效果
          deny                        all;
		}
		
		##匹配靜態資源服務器,這裏沒有將靜態資源放到本nginx本地,因爲考慮到後期可能會水平擴展    nginx,所以將靜態資源獨立存放。
		location ~ .*\.(js|css|html|svg|ico|png|jpg|gif) {
            proxy_pass http://static-cluster;
			root static;
			proxy_connection_timeout 30s;
			proxy_send_timeout 30s;
			proxy_read_timeout 30s;
        }
		
		##如果都沒有匹配則禁止訪問
		location / {
		  ##禁止訪問
          deny                        all;
		}

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }



}

#user  nobody;

#設置worker進程的數量,這裏設置成於cpu相同
worker_processes  2;

##設置錯誤日誌的輸出級別爲warn,減輕日誌輸出的壓力
error_log  logs/error.log warn;
##設置pid文件路徑
pid        logs/nginx.pid;


events {
    ##使用epoll模型,linux下建議使用epoll
    use epoll;
	##每個worker線城所能接受的最大連接數
    worker_connections  10240;
	##設置網路連接序列化,防止驚羣現象發生,默認爲on。
	##如果當前機器的worker線城很多的話可以選擇置爲off,但如果只有幾個work線程的話建議爲on,當前設爲on。
    accept_mutex on;   

}





http {
    ##設定mime類型,類型由mime.type文件定義
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #開啓自定義錯誤頁面,如果當前server是做反響代理的,那麼必須加這個配置才能自定義錯誤頁面
    proxy_intercept_errors on;

    ##疫苗預約集羣地址,這裏爲疫苗服務設置了5臺機器,因爲這裏是主打業務。
    upstream vaccine-order-cluster{
	    server 172.17.16.4:8091 max_fails=5 fail_timeout=60s;
	    server 172.17.16.4:8092 max_fails=5 fail_timeout=60s;
	    server 172.17.16.4:8093 max_fails=5 fail_timeout=60s;
	    server 172.17.16.4:8094 max_fails=5 fail_timeout=60s;
	    server 172.17.16.4:8095 max_fails=5 fail_timeout=60s;
    }

	##只提供80端口的監聽
    server {
        listen       80;
        server_name  localhost;
		
		##設置編碼爲utf-8
        charset utf-8;
		
		##開啓訪問日誌,用來更好的統計用戶訪問數據
        access_log  logs/host.access.log  main;

		##匹配疫苗預約訂單服務相關請求
        location ^~/vaccine/order {
            proxy_pass http://vaccine-order-cluster;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location / {
            deny  all;
        }
    }


}

 

*:需要爲nginx安裝http_stub_status_module模塊

 

*:nginx的安裝和啓動都比較方便,值得一提的是,nginx的所有操作都被封裝到sbin目錄下的nginx腳本里了,不管我們要對nginx做什麼操作都可以直接運行這個腳本。下面列出一些常用的命令

./nginx --不帶參數表示啓動nginx,默認去找conf目錄下的nginx.conf配置文件

./nginx -c /usr/local/nginx/conf/nginx.conf   --以指定的配置文件來啓動nginx

./nginx -s stop    --停止nginx

/nginx -s reload   --重新加載nginx的配置文件,如果修改了nginx配置可以使用這個命令刷新配置

下期預告

mongodb4.2版本生產集羣的搭建

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章