基于 consul + nginx 的Spring boot微服务集群部署
consul + nginx 负载均衡
最近做的基于consul的微服务项目,仅仅在单机上部署了一套,压测的时候扛不住(并发太高的时候linux文件连接数超过上限),于是想办法搞个集群部署。最终在我们的服务器的三台机器(mirage05-mirage07)上完成部署。
一. 背景介绍以及项目现状
1. consul
我们使用的微服务框架consul,其实就是一个服务中心。微服务在启动的时候将自己的信息注册到consul(服务注册/服务发现),当外部请求打到网关服务时,网关直接与consul通信来寻找其他服务来转发请求,而consul的健康检测防止请求转发到故障的服务上面。
这里其实可以看出,consul其实是自带负载均衡的。如果在一个consul服务中注册了多个相同的微服务副本,例如注册了多个user-service,那么登陆请求应该就会均匀转发到各个服务上。
而我们目前只在一台机器上部署了一个consul服务和一套微服务,其实并没有发挥微服务框架的优势。
之前做过的调研,在本地起服务,向服务器上的consul服务注册,最后虽然注册上去服务了,但请求并不会转发到本地服务处理,可能是因为没有使用consul集群的情况下,consul不会向陌生机器转发请求。(仅仅是猜想,没做过深入实验)
单机器注册多个服务副本(详见4.1)
consul服务中的每个实例名必须是唯一的,而实例名=服务名+端口号,所以想要在一台机器上起多个服务副本,且都注册到consul中,那就需要不同副本监听不同端口。
Spring boot服务启动之后监听哪个端口是在yaml里定义的,所以我们只需要定义多套yaml配置来定义不同的端口号监听,然后在起服务的时候,加参数选择不同yaml配置就好了。
consul集群(详见4.2)
在多台机器上分别启动consul服务,然后使用命令join成一个集群,最后会选出一个Leader,其余都是member。
2. Nginx
可以做负载均衡以及反向代理。
我们在前端服务和后端微服务集群间加入一个Nginx服务来分摊流量,做负载均衡。
二. 目标架构
1. 目前做法
选取几台机器(mirage05-07),分别起consul服务并组成集群,并在每台机器上起两套微服务(当然网关服务只起一个),并在06上起一个Nginx,监听8000端口,把请求均匀转发到05-07的6001端口(gateway服务端口)上。
修改前端,将所有请求发到06的8000端口,在mirage05机器上部署前端。
2. 讨论
可能看完上面的介绍有点晕,为啥consul就能做负载均衡了,还要用Nginx。
我认为可以有以下几种说法:
- 从整体架构上看。Nginx是做前端请求到目标机器(网关服务)间的负载均衡,而consul是做请求从网关服务转发到某个服务副本的负载均衡
- 从结构的稳定性看。当然可以只起一个consul和一个gateway,然后只在一台机器上起很多套服务,负载均衡完全交给consul做,但是这样就没完全发挥微服务架构的优势了,如果机器挂了/进程太多CPU卡了/内存不够等等,那整套系统就挂了。而在多台机器上部署集群,可以最大化利用硬件资源,并增强系统稳定性。
三. 实验(为了证明框架有效性及稳定性)
consul健康检测1
- 在05-07三台机器上部署consul集群,其中06上部署两套微服务。
- 查看06机器上,filesystem-service对应的两个进程,并杀掉其中一个
- 在前端多次操作文件系统,一切正常
- 查看后端日志,发现consul检测到异常之后,前端请求打到06网关之后,只向健康的filesystem-service进程转发请求
consul健康检测2
- 在05-07三台机器上部署consul集群,其中05上仅部署一套微服务。
- 杀掉05机器上的filesystem-service进程
- 在前端多次操作文件系统,在一次异常(白屏)后,一切正常
- 再次启动05上的filesystem-service
- 前端多次操作文件系统,一切正常
- 查看05的filesystem-service日志,发现有请求打过来
推测网关+consul有转发的优先级,优先向本机注册的目标服务转发请求(通信开销小),当本机的注册的目标服务全部挂掉后(可能会发一次请求确认,导致前端白屏,因为ls接口返回了null),才会将请求转发到其他机器上处理。
四. 详细做法
1. 修改yaml配置,起多服务副本监听不同端口(以example-service为例)
# 这是全局配置,这里表明默认选择名为pro的配置
spring:
profiles:
active: pro
# 用三个横线分割不同配置,当然也可以放到不同的yaml文件中
---
spring:
profiles: pro # profiles属性代表配置的名称
logging:
config: classpath:log4j.yml
server:
port: 7001
---
spring:
profiles: backup
logging:
config: classpath:log4j-backup.yml
server:
port: 7002
配置中除了设置不同的端口,也设置了不同的log4j配置,使得不同服务副本存储的日志文件分离。这样的话,服务器上启动服务的时候用以下两条命令启动两个example-service服务,分别监听7001、7002端口,并且分别生成不同名称的日志,便于查看。
nohup java -jar example-service/target/example-service-0.0.1-SNAPSHOT.jar&
nohup java -jar example-service/target/example-service-0.0.1-SNAPSHOT.jar --spring.profiles.active=backup&
2. consul集群部署
集群部署可以参考 : https://www.cnblogs.com/duanxz/p/10564502.html
这里以05-07机器部署为例(默认consul已经下载、解压、放置到/usr/local/bin目录下,可直接执行)
mirage-05启动consul
nohup consul agent -server -bootstrap-expect=3 -data-dir=/tmp/consul -node=mirage-05 -bind=mirage-05 -client=0.0.0.0 -datacenter=dssc -ui&
mirage-06启动consul
nohup consul agent -server -bootstrap-expect 3 -data-dir /tmp/consul -node mirage-06 -bind=mirage-06 -client=0.0.0.0 -datacenter=dssc -ui&
mirage-07启动consul
nohup consul agent -server -bootstrap-expect 3 -data-dir /tmp/consul -node mirage-07 -bind=mirage-07 -client=0.0.0.0 -datacenter=dssc -ui&
参数解释:
server: 以server身份启动。默认是client
bootstrap-expect:集群要求的最少server数量,当低于这个数量,集群即失效。
data-dir:data存放的目录,更多信息请参阅consul数据同步机制
node:节点id,集群中的每个node必须有一个唯一的名称。默认情况下,Consul使用机器的hostname
bind:监听的ip地址。默认绑定0.0.0.0,可以不指定。表示Consul监听的地址,而且它必须能够被集群中的其他节点访问。Consul默认会监听第一个private IP,但最好还是提供一个。生产设备上的服务器通常有好几个网卡,所以指定一个不会出错
client: 客户端的ip地址,0.0.0.0是指谁都可以访问(不加这个,下面的ui :8500无法访问)
ui: 可以访问UI界面
-config-dir指定配置文件夹,Consul会加载其中的所有文件
-datacenter 指定数据中心名称,默认是dc1
此时机器上分别起了consul服务,但还未组成集群,不能正常工作。
分别在06、07机器上输入命令
consul join mirage-05
很快将选出一个Leader,输入命令查看
consul operator raft list-peers
Node ID Address State Voter RaftProtocol
10.105.222.246 e9444b79-2df9-a641-8512-fec7540ac00e 10.105.222.246:8300 leader true 3
10.105.222.247 b13a9221-5f71-075d-804c-726c79a9e77f 10.105.222.247:8300 follower true 3
10.105.222.245 9de9c7f8-b547-ab52-e174-23445dd59189 10.105.222.245:8300 follower true 3
3. Nginx配置
目前已经在06上部署了一台Nginx服务
安装步骤
1. 下载压缩包 wget http://nginx.org/download/nginx-1.18.0.tar.gz
2. 解压 tar -zxvf nginx-1.18.0.tar.gz
3. 进入解压目录 cd nginx-1.18.0.tar.gz
4. 检查配置文件是否生效 ./configure
5. 编译 make -j4
6. 安装依赖 make install (这步之后在/usr/local目录下会生成一个nginx目录)
7. 进入/usr/bin/的目录下 cd /usr/bin
8. 创建快捷方式 ln -s /usr/local/nginx/sbin/nginx nginx
9. 直接输入nginx启动
10. 浏览器输入localhost查看,如果能看到nginx提示页面,说明启动成功
负载均衡配置(使nginx服务监听8000端口,并把请求转发到05-07的6001端口)
1. 进入配置文件目录 cd /usr/local/nginx/conf
2. vim nginx.conf
3. 修改配置
http {
upstream backend { //这里定义了三台机器的gateway地址
server mirage-05:6001;
server mirage-06:6001;
server mirage-07:6001;
}
server {
listen 8000; //监听的端口
server_name 127.0.0.1; // 表示监听的是本机器
location / { // 这里表示任何url都转发
proxy_pass http://backend; // 这里是转发的目的ip,和上边定义的一致
}
}
}
4. 热重启,配置生效 nginx -s reload
4. 新机器加入集群步骤
1. 安装consul,并join入集群
2. 拉下来后端项目,脚本启动
3. 修改Nginx配置,在upstream backend中加入新机器gateway地址
五. 未来计划
- 压测
- 测试下HDFS请求在被多机器分担后,还会不会文件连接超出
- 感觉之后系统性能瓶颈可能就不在微服务上了,可能就在Spark和hdfs、mongoDb上了
- 根据压测结果来决定微服务集群规模
- 加入日志报警系统
- 初步考虑Sentry
- 监控Error级别日志,可以及时发现服务的BUG
- 在服务挂(短时间大量5xx)之后可以及时发邮件/企业微信给对应的维护人员进行处理
原文:https://www.cnblogs.com/yanch01/p/14664264.html