摘要:前兩個數據業務相關的服務即下圖的,第三個項目就是的實現的負載均衡。這里后臺,前臺項目各啟動了三個實例,用戶訪問的時候,就會根據配置的負載均衡的策略,訪問其中一個。這一部分與之前我轉發的實現服務發現及網關其實也只是差了個網關和負載均衡。
一.簡介
上一篇只講了博客的前端問題,這一篇講一下后端的微服務搭建。項目的后端使用的thinkjs框架,在我之前的博客中已經寫過,這里就不重點說明了。
后端項目分為三個:
博客前臺頁面服務端:在這里。
博客后臺頁面服務端:在這里。
consul-template+nginx實現的基于微服務注冊發現的負載均衡:在這里。
前兩個數據業務相關的服務即下圖的service_web,第三個項目就是consul-template+nginx的實現的負載均衡。
如果對consul基礎概念不了解,建議讀完我博客里這兩篇文章再繼續看下面的內容。
consul+docker實現服務注冊。
consul+docker實現服務發現及網關。
首先看下架構圖:
consul-template會訂閱consul注冊中心上的服務消息,當service-web改變時,consul注冊中心會將新的service web信息推送給consul-template,consul-template會修改nginx配置文件,nginx重載入配置后,就達到了可以自動修改更新的負載均衡。
二.consul-template+nginx實現基于微服務的負載均衡 consul-template 介紹Consul-Template是基于Consul的自動替換配置文件的應用。在Consul-Template沒出現之前,大家構建服務發現系統大多采用的是Zookeeper、Etcd+Confd這樣類似的系統。
使用場景:可以查詢Consul中的服務目錄、Key、Key-values等。這種強大的抽象功能和查詢語言模板可以使Consul-Template特別適合動態的創建配置文件。例如:創建Apache/Nginx Proxy Balancers、Haproxy Backends、Varnish Servers、Application Configurations等。
代碼介紹當consul注冊中心的的服務改變時,consul-template會根據nginx-consul-template重新生成nginx.conf。首先看一下nginx.conf.ctmpl的代碼:
upstream admin { {{range service "service-admin"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; {{else}}server 127.0.0.1:65535; # force a 502{{end}} } upstream app { {{range service "service-web"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; {{else}}server 127.0.0.1:65535; # force a 502{{end}} } server { listen 80 default_server; # 映射博客后臺管理服務 location /admin{ proxy_pass http://admin/; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } #請求博客后臺服務的靜態資源 location ^~/static/blog-backend-react{ proxy_pass http://admin/static/blog-backend-react; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } #請求博客前臺服務的靜態資源 location ^~/static/blog-react{ proxy_pass http://app/static/blog-react; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 接口請求,映射博客前臺服務 location /font{ proxy_pass http://app; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 接口請求,映射博客后臺服務 location /api{ proxy_pass http://admin/api; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 默認映射到博客前端服務 location / { proxy_pass http://app; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
template與正常nginx.conf區別就是upstream里部分,根據服務名——這里是兩個服務,self-blog-backend博客后臺管理服務與self-blog-fontend博客前臺服務——動態生成服務對應的ip。
template的反向代理部分,與正常nginx配置一致,因為有兩個項目,所以每個url請求接口,靜態資源,服務,都需要映射到特定的服務。
服務啟動后,根據模版生成的nginx配置文件如下:
upstream admin { server 172.25.0.7:8362 max_fails=3 fail_timeout=60 weight=1; server 172.25.0.8:8362 max_fails=3 fail_timeout=60 weight=1; server 172.25.0.11:8362 max_fails=3 fail_timeout=60 weight=1; } upstream app { server 172.25.0.4:8365 max_fails=3 fail_timeout=60 weight=1; server 172.25.0.9:8365 max_fails=3 fail_timeout=60 weight=1; server 172.25.0.10:8365 max_fails=3 fail_timeout=60 weight=1; } server { .... }
可以看到,upstream里,根據服務名已經找到了對應的ip。這里后臺,前臺項目各啟動了三個實例,用戶訪問的時候,就會根據配置的nginx負載均衡的策略,訪問其中一個ip。
用于啟動nginx服務
#!/bin/sh # 啟動nginx # daemon off 關閉守衛進程,保證nginx前臺運行 nginx -c /etc/nginx/nginx.conf -t && nginx -c /etc/nginx/nginx.conf -g "daemon off;"
用于啟動consul-template
#!/bin/sh # 啟動consul-template,指定consul地址 # consul變化后,根據模板 nginx.conf ,生成nigix配置文件并reload exec consul-template -consul-addr=consul:8500 -template "/etc/consul-templates/nginx.conf:/etc/nginx/conf.d/app.conf:nginx -s reload"
因為整個負載均衡服務需要做成鏡像,與其他服務一起部署,所以這里需要維護Dockerfile
FROM nginx # 聲明告訴系統,無需向用戶請求輸入(非交互式) RUN DEBIAN_FRONTEND=noninteractive # 更新軟件包列表 apt-get update -qq && # 安裝 curl runit apt-get -y install curl runit && # rm 刪除,-r 全部刪除子目錄, -f 強制刪除 rm -rf /var/lib/apt/lists/* ADD consul-template_0.19.4_linux_amd64.tgz /usr/local/bin/ # 將 nginx.service 放到指定文件夾,生成run文件 ADD nginx.service /etc/service/nginx/run # 給所有人添加文件的可執行權限 RUN chmod a+x /etc/service/nginx/run ADD consul-template.service /etc/service/consul-template/run RUN chmod a+x /etc/service/consul-template/run RUN rm -v /etc/nginx/conf.d/* ADD nginx.conf /etc/consul-templates/nginx.conf # 使用runit ,當 runsvdir在/etc/service/目錄中發現新的配置時, # 啟動runsv進程來執行和監控/etc/service下的run腳本 CMD ["/usr/bin/runsvdir", "/etc/service"]
維護好之后,就可以制作自己的nginx-consul-template鏡像了。
docker-compose.yml博客后臺與前臺服務端項目github上,都有自己的Dockerfile,將他們做成鏡像后,與nginx-consul-template鏡像一起,通過docker-compose統一部署這幾個服務。
version: "2.0" services: consulserver: image: progrium/consul:latest hostname: consulserver ports: - "8300" - "8400" - 8500:8500 - "53" command: -server -ui-dir /ui -data-dir /tmp/consul --bootstrap-expect=3 consulserver1: image: progrium/consul:latest hostname: consulserver1 depends_on: - consulserver ports: - "8300" - "8400" - "8500" - "53" command: -server -data-dir /tmp/consul -join consulserver consulserver2: image: progrium/consul:latest hostname: consulserver2 depends_on: - consulserver ports: - "8300" - "8400" - "8500" - "53" command: -server -data-dir /tmp/consul -join consulserver registrator: image: gliderlabs/registrator:master hostname: registrator depends_on: - consulserver volumes: - /var/run/docker.sock:/tmp/docker.sock command: -internal consul://consulserver:8500 serviceadmin1: image: daocloud.io/sunxing102005/self-blog-backend:latest depends_on: - consulserver environment: SERVICE_8362_NAME: service-admin ports: - 3002:3002 - "8362" serviceweb1: image: daocloud.io/sunxing102005/self-blog-fontend:latest depends_on: - consulserver environment: SERVICE_8365_NAME: service-web ports: - 3005:3005 - "8365" lb: image: daocloud.io/sunxing102005/consul-template-nginx-blog:latest hostname: lb links: - consulserver:consul ports: - 80:80
運行命令,啟動服務
docker-compose up -d
運行后,就可以從注冊中心看到consul上注冊的服務:
其中consul-template-nginx-blog就是lb,service-admin,service-web分別是博客的前臺,后臺服務(3002,3005兩個服務是留給prometheus抓數據用的,不用在意)因為這里各只啟動了一個實例,所以他們每個只有一個服務。下面看下nginx的效果
訪問默認80端口,直接訪問博客前端服務
訪問80端口加上admin后綴,就會跳到博客管理網站。
這里放一些開發過程中,自己記錄的一些問題和知識點。
如何進入docker容器查看consul-template生成的nginx.confdocker ps //查看consul-template-nginx容器id docker exec -it exec 22fff6c360f1 /bin/sh // 進入容器 cat /etc/nginx/conf.d/app.conf //查看文件docker運行nginx為什么要執行daemon off
docker容器后臺運行時,前臺必須有一個前臺進程。
容器運行的命令,如果不是一直掛起的就會自動退出。
nginx是后臺進程模式運行,導致沒有前臺運行的應用,他就會立即退出應用。
解決方法:
將你要運行的容器以前臺形式運行,關閉守衛進程
nginx -g " daemon off"
添加tail,top這種可以前臺運行的程序,推薦使用tail,然后持續輸出log
service nginx start && tail -f /var/log/nginx/error.lognginx.conf.ctmpl注意事項
upstream admin { {{range service "service-admin"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; {{else}}server 127.0.0.1:65535; # force a 502{{end}} } upstream app { {{range service "service-web"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; {{else}}server 127.0.0.1:65535; # force a 502{{end}} } server { listen 80 default_server; location /admin{ proxy_pass http://admin/; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
location匹配的如果不是/ ,如果想跳轉到這個服務的根目錄,里面proxy_pass定義的url,后面要加上/,比如這里匹配的 /admin,
proxy_pass是http://admin/,如果是http://admin,則反向代理的路徑是http://XXXX:8362/admin,而不是8362服務的跟路徑http://XXXX:8362。
nginx 服務器重啟命令,關閉 nginx -s reload :修改配置后重新加載生效 nginx -s reopen :重新打開日志文件 nginx -t -c /path/to/nginx.conf 測試nginx配置文件是否正確 關閉nginx: nginx -s stop :快速停止nginx quit :完整有序的停止nginx 其他的停止nginx 方式: ps -ef | grep nginx kill -QUIT 主進程號 :從容停止Nginx kill -TERM 主進程號 :快速停止Nginx pkill -9 nginx :強制停止Nginx 啟動nginx: nginx -c /path/to/nginx.conf 平滑重啟nginx: kill -HUP 主進程號nginx 反向代理加req header
前端每次請求,都token放到了request header里。之前header里設置的字段叫access_token,傳不過去,發現nginx反向代理時,會忽略帶下劃線的header,所以改成了accesstoken。
docker常用命令啟動 systemctl start docker 守護進程重啟 sudo systemctl daemon-reload 重啟docker服務 systemctl restart docker 重啟docker服務 sudo service docker restart 關閉docker service docker stop 關閉docker systemctl stop dockerdocker 批量刪除容器
docker rm `docker ps -a -q` //刪除所有容器 docker rmi `docker images -q` //刪除所有鏡像 //按條件刪除鏡像 //沒有打標簽 docker rmi `docker images -q | awk "/^linx chmod 命令/ {print $3}"` //鏡像關鍵字 docker rmi `docker images | grep doss api | awk "print $3"`
如果給所有人添加可執行權限:chmod a+x 文件名
如果給文件所有者添加可執行權限:chmod u+x 文件名
如果給所在組添加可執行權限:chmod g+x 文件名
如果給所在組以外的人添加可執行權限:chmod o+x 文件名
詳細chmod命令,可參考這里。
linx service服務管理通過ubuntu自帶service,可以很方便創建后臺運行程序。
service文件路徑:/lib/systemd/ystem
service文件包含多個部分,下面是簡單的后臺運行的service文件。
啟動服務
service leshan-erver start
停止服務
service leshan-erver stop
查看服務狀態
systemctl status lenshan-server
重新加載service文件
systemctl daemon-reload四.總結
本篇主要講解consul-template+nginx的負載均衡的實現,網上類似的講解有很多,consul+nginx+consul-template構建簡單微服務也是很基礎常用的方案。這一部分與之前我轉發的consul+docker實現服務發現及網關其實也只是差了個網關和負載均衡。稍微值得注意的是,本項目里,用到了兩個業務層面的服務——博客前臺與后臺兩個服務——而不是單體項目,稍微有點微服務的感覺了,把大項目拆開管理。所以nginx這部分就需要分別反向代理到兩個項目里,這里請求接口,靜態什么的,兩個服務要有區分,讓nginx有代理區分的標準。
至此博客的前端,后端微服務搭建都講完了,有空的話下一篇講一下daocloud平臺部署和prometheus+grafana的監控系統。
https://www.jianshu.com/p/a4c...
http://blog.zongwu233.com/Con...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/40473.html
摘要:注冊器監視每個守護進程的事件,并在生命周期事件期間自動更新。條件可以包括親和規則否定至軟強制意味著盡可能地避免。當使用通用標記如或部署服務時,可能會出現意外的后果。月日,北京海航萬豪酒店,容器技術大會即將舉行。 在這篇文章中,我們將討論如何用Rancher實現consul的服務發現。 如果你還沒有準備好,推薦你閱讀本系列中先前的文章:第一篇:CI /CD和Docker入門第二篇:使部署...
摘要:接入層作用一的聚合。接入層作用二服務發現與動態負載均衡既然統一的入口變為了接入層,則接入層就有責任自動的發現后端拆分,聚合,擴容,縮容的服務集群,當后端服務有所變化的時候,能夠實現健康檢查和動態的負載均衡。 此文已由作者劉超授權網易云社區發布。 歡迎訪問網易云社區,了解更多網易技術產品運營經驗。 這個系列是微服務高并發設計,所以我們先從最外層的接入層入手,看都有什么樣的策略保證高并發。...
摘要:之前提到的文件即可利用以下模板生成請注意,其中的與就是占位符。如將某一特定部署至生產環境并運行個實例。而另一種方式則是使用等負載均衡器即服務器端發現。可重配置且能夠在變更發生后立即將請求路由至新實例。 如今與Mesos相關的文章可謂層出不窮,不過展示能夠直接用于生產的完整基礎設施的資料卻相當少見。在今天的文章中,我將介紹各組件的配置與使用方式,旨在幫助大家利用Mesos構建起持續交付且...
摘要:個推針對服務場景,基于和搭建了微服務框架,提高了開發效率。三容器化在微服務落地實踐時我們選擇了,下面將詳細介紹個推基于的實踐。 2016年伊始Docker無比興盛,如今Kubernetes萬人矚目。在這個無比需要創新與速度的時代,由容器、微服務、DevOps構成的云原生席卷整個IT界。個推針對Web服務場景,基于OpenResty和Node.js搭建了微服務框架,提高了開發效率。在微服...
閱讀 3495·2021-11-12 10:36
閱讀 2875·2021-09-22 15:35
閱讀 2824·2021-09-04 16:41
閱讀 1174·2019-08-30 15:55
閱讀 3585·2019-08-29 18:43
閱讀 2079·2019-08-23 18:24
閱讀 1424·2019-08-23 18:10
閱讀 1928·2019-08-23 11:31