Consul结合nginx构建高可用可扩展的Web服务
Consul介绍
Consul是由hashicorp组织发起的开源项目。Consul由Go语言开发,部署起来非常容易,只需要极少的可执行程序和配置文件,具有绿色、轻量级的特点。Consul有一组组件,因此能提供多种功能,目前主要的功能就是服务发现,其他的附加功能,比如自动编排,key-value数据库等,暂时归属为附加值。
在Consul的服务发现定义中,应用服务(如Web服务、数据库服务、Redis服务等)在向Consul服务注册的过程中是作为提供服务方(具体是由Consul Agent实现的),Consul是接受服务方,服务信息由Consul Agent提供给Consul Server。在除了向Consul服务注册,其他过程中可能会反过来,Consul Server可能会主动质询Consul Agent。
借助Consul,被服务者可以从Consul那里获得到提供服务者提供了哪些可用的服务、应用。这些服务、应用是随时可以添加或移除的,借助负载均衡设备或软件可以非常容易实现高可用、可扩展的、弹性的应用服务架构。
Consul解决了动态提供服务信息、动态更改服务配置的问题。
方案概述
nginx提供的负载均衡服务同样支持高可用、可扩展的Web服务,但缺点是比较依赖于人工。例如传统的nginx负载均衡的配置方式是,在nginx某个配置文件中配置一个upstream,upstream中配置多个服务节点,每一个服务节点就是一个web应用服务。nginx虽然可以做到对服务节点的健康检查,但是当服务节点增加、减少或者发生状态改变,nginx配置文件是固定写死的,不能动态的感知后端服务节点的服务状态信息,因此需要有一种解决方案能够帮助ngnix动态的感知后端服务节点的服务信息。要想实现这种需求,不仅Consul一家,但此例中使用Consul来实现,关于Consul其他的使用案例可以继续学习和研究。
配置概述
服务器 | 服务 | 解释 |
---|---|---|
101.43.121.33 | Docker-ce、Consul、Consul-template | Consul-template基于consul自动替换配置文件的应用 |
120.48.12.204 | Docker-ce、Registrator、Tomcat | Registrator是用于监听监控节点上容器的变化(增加或减少,或者宕机),一旦有变化会把这些信息告诉并注册在consul server端 |
此方案用到的组件:consul、consul-template(基于consul自动替换配置文件的应用)、nginx、docker、registrator。
nginx前端作为负载均衡器使用,它代理了三台能提供web服务的服务器,每一台服务器上均安装consul,并以registrator的形式运行在服务器上,Consul-template与Consul Cluster的Server连接,动态的从Consul的服务信息库汇中拉取nginx代理的三台服务器的IP、端口号等信息,并将IP地址以及端口号写入到nginx的配置文件中,在完成一次写入后(即后台服务发生变更时),Consul-template将自动将nginx重启加载,实现nginx应用新配置文件的目的。
操作步骤
- 部署nginx、docker等
- 构建consul cluster(consul 集群)
- 构建Web应用服务
- 安装和配置registrator
- 安装并配置consul-template使consul-template与nginx联动
- 验证与测试
部署nginx、docker
此处省略
构建consul cluster
如果您只想运行Consul Agent的单个实例来尝试其功能:
docker run -p 8400:8400 -p 8500:8500 -p 8600:53/udp -h node1 progrium/consul -server -bootstrap
可以通过添加-UI-dir标志来启用Web UI:
docker run -p 8400:8400 -p 8500:8500 -p 8600:53/udp -h node1 progrium/consul -server -bootstrap -ui-dir /ui
部署容器化单机集群:
docker run -d --name node1 -h node1 progrium/consul -server -bootstrap-expect 3
我们可以通过检查容器来获取容器的内部IP。我们将把它放在环境变量JOIN_IP中。
JOIN_IP="$(docker inspect -f '{{.NetworkSettings.IPAddress}}' node1)"
docker run -d --name node2 -h node2 progrium/consul -server -join $JOIN_IP
docker run -d --name node3 -h node3 progrium/consul -server -join $JOIN_IP
docker run -d -p 8400:8400 -p 8500:8500 -p 8600:53/udp --name node4 -h node4 progrium/consul -join $JOIN_IP
构建Web应用服务
构建Web应用服务可以通过多种方式,根据自己的实际情况搭建。比如可以用java语言写一个简单的serverlet也可以nginx做一个Web测试页出来,还可以直接用docker hub上现有的Web程序做测试
编写Web脚本进行测试
vim /web/index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>登录</title>
</head>
<body>
<form action="LoginServlet" method="post">
<table>
<tr>
<td>账号</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td><input type="submit" value="登录"></td>
</tr>
</table>
</form>
</body>
启动两台tomcat
docker run -itd -p:8001:8080 -v /web:/usr/local/tomcat/webapps/ROOT --name docker01-t1 -h docker01-t1 tomcat
docker run -itd -p:8002:8080 -v /web:/usr/local/tomcat/webapps/ROOT --name docker01-t2 -h docker01-t2 tomcat
自动注册
安装consul-template
wget https://releases.hashicorp.com/consul-template/0.20.0/consul-template_0.20.0_linux_amd64.zip
unzip consul-template_0.20.0_linux_amd64.zip
mv consul-template /usr/bin/
编写修改nginx模板
cat /root/consul/nginx.tmp
uptream http_backend {
{{range service "tomcat"}}
server {{ .Address }}:{{ .Port }};
{{ end }}
}
server {
listen 8080;
server_name localhost 192.168.2.224;
access_log /usr/local/nginx/logs/crushlinux-access.log;
index index.html index.jsp index.php;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://http_backend;
}
}
修改nginx配置文件
vim /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
include vhost/*.conf; ##添加这一行,子配置文件
default_type application/octet-stream;
新建虚拟主机文件
mkdir /usr/local/nginx/conf/vhost
启动 template
consul-template -consul-addr 101.43.121.33:8500 -template "/root/consul/nginx.tmp:/usr/local/nginx/conf/vhost/Carrie.conf:/usr/local/nginx/sbin/nginx -s reload" --log-level=debug
在另外一台新启动几个服务
docker run -itd -p:8003:8080 -v /web:/usr/local/tomcat/webapps/ROOT --name docker01-t3 -h docker01-t3 tomcat
docker run -itd -p:8004:8080 -v /web:/usr/local/tomcat/webapps/ROOT --name docker01-t4 -h docker01-t4 tomcat
docker run -itd -p:8005:8080 -v /web:/usr/local/tomcat/webapps/ROOT --name docker01-t5 -h docker01-t5 tomcat
查看/usr/local/nginx/conf/vhost/Carrie.conf是否发生变化(nginx重载,配置文件已增加)
访问主机(未部署tomcat)的8080已成功代理