摘要:前两个数据业务相关的服务即下图的,第三个项目就是的实现的负载均衡。这里后台,前台项目各启动了三个实例,用户访问的时候,就会根据配置的负载均衡的策略,访问其中一个。这一部分与之前我转发的实现服务发现及网关其实也只是差了个网关和负载均衡。
一.简介
上一篇只讲了博客的前端问题,这一篇讲一下后端的微服务搭建。项目的后端使用的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...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/40473.html
摘要:注册器监视每个守护进程的事件,并在生命周期事件期间自动更新。条件可以包括亲和规则否定至软强制意味着尽可能地避免。当使用通用标记如或部署服务时,可能会出现意外的后果。月日,北京海航万豪酒店,容器技术大会即将举行。 在这篇文章中,我们将讨论如何用Rancher实现consul的服务发现。 如果你还没有准备好,推荐你阅读本系列中先前的文章:第一篇:CI /CD和Docker入门第二篇:使部署...
摘要:接入层作用一的聚合。接入层作用二服务发现与动态负载均衡既然统一的入口变为了接入层,则接入层就有责任自动的发现后端拆分,聚合,扩容,缩容的服务集群,当后端服务有所变化的时候,能够实现健康检查和动态的负载均衡。 此文已由作者刘超授权网易云社区发布。 欢迎访问网易云社区,了解更多网易技术产品运营经验。 这个系列是微服务高并发设计,所以我们先从最外层的接入层入手,看都有什么样的策略保证高并发。...
摘要:之前提到的文件即可利用以下模板生成请注意,其中的与就是占位符。如将某一特定部署至生产环境并运行个实例。而另一种方式则是使用等负载均衡器即服务器端发现。可重配置且能够在变更发生后立即将请求路由至新实例。 如今与Mesos相关的文章可谓层出不穷,不过展示能够直接用于生产的完整基础设施的资料却相当少见。在今天的文章中,我将介绍各组件的配置与使用方式,旨在帮助大家利用Mesos构建起持续交付且...
摘要:个推针对服务场景,基于和搭建了微服务框架,提高了开发效率。三容器化在微服务落地实践时我们选择了,下面将详细介绍个推基于的实践。 2016年伊始Docker无比兴盛,如今Kubernetes万人瞩目。在这个无比需要创新与速度的时代,由容器、微服务、DevOps构成的云原生席卷整个IT界。个推针对Web服务场景,基于OpenResty和Node.js搭建了微服务框架,提高了开发效率。在微服...
阅读 3467·2021-11-12 10:36
阅读 2834·2021-09-22 15:35
阅读 2781·2021-09-04 16:41
阅读 1143·2019-08-30 15:55
阅读 3558·2019-08-29 18:43
阅读 2052·2019-08-23 18:24
阅读 1351·2019-08-23 18:10
阅读 1902·2019-08-23 11:31