上一篇只講了博客的前端問題,這一篇講一下後端的微服務搭建。項目的後端使用的thinkjs框架,在我以前的博客中已經寫過,這裏就不重點說明了。
後端項目分爲三個:html
前兩個數據業務相關的服務即下圖的service_web,第三個項目就是consul-template+nginx的實現的負載均衡。
若是對consul基礎概念不瞭解,建議讀完我博客裏這兩篇文章再繼續看下面的內容。
consul+docker實現服務註冊。
consul+docker實現服務發現及網關。
首先看下架構圖:
前端
consul-template會訂閱consul註冊中心上的服務消息,當service-web改變時,consul註冊中心會將新的service web信息推送給consul-template,consul-template會修改nginx配置文件,nginx重載入配置後,就達到了能夠自動修改更新的負載均衡。react
Consul-Template是基於Consul的自動替換配置文件的應用。在Consul-Template沒出現以前,你們構建服務發現系統大多采用的是Zookeeper、Etcd+Confd這樣相似的系統。linux
使用場景:能夠查詢Consul中的服務目錄、Key、Key-values等。這種強大的抽象功能和查詢語言模板可使Consul-Template特別適合動態的建立配置文件。例如:建立Apache/Nginx Proxy Balancers、Haproxy Backends、Varnish Servers、Application Configurations等。nginx
當consul註冊中心的的服務改變時,consul-template會根據nginx-consul-template從新生成nginx.conf。首先看一下nginx.conf.ctmpl的代碼:git
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配置文件以下:github
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。web
用於啓動nginx服務docker
#!/bin/sh # 啓動nginx # daemon off 關閉守衛進程,保證nginx前臺運行 nginx -c /etc/nginx/nginx.conf -t && \ nginx -c /etc/nginx/nginx.conf -g "daemon off;"
用於啓動consul-templatebootstrap
#!/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鏡像了。
博客後臺與前臺服務端項目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 ps //查看consul-template-nginx容器id docker exec -it exec 22fff6c360f1 /bin/sh // 進入容器 cat /etc/nginx/conf.d/app.conf //查看文件
docker容器後臺運行時,前臺必須有一個前臺進程。
容器運行的命令,若是不是一直掛起的就會自動退出。
nginx是後臺進程模式運行,致使沒有前臺運行的應用,他就會當即退出應用。
解決方法:
將你要運行的容器之前臺形式運行,關閉守衛進程
nginx -g " daemon off"
添加tail,top這種能夠前臺運行的程序,推薦使用tail,而後持續輸出log
service nginx start && tail -f /var/log/nginx/error.log
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 主進程號
前端每次請求,都token放到了request header裏。以前header裏設置的字段叫access_token,傳不過去,發現nginx反向代理時,會忽略帶下劃線的header,因此改爲了accesstoken。
啓動 systemctl start docker 守護進程重啓 sudo systemctl daemon-reload 重啓docker服務 systemctl restart docker 重啓docker服務 sudo service docker restart 關閉docker service docker stop 關閉docker systemctl stop docker
docker rm `docker ps -a -q` //刪除全部容器 docker rmi `docker images -q` //刪除全部鏡像 //按條件刪除鏡像 //沒有打標籤 docker rmi `docker images -q | awk '/^<none>/ {print $3}'` //鏡像關鍵字 docker rmi `docker images | grep doss api | awk 'print $3'`
經過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...