Nginx利用Consul实现动态负载均衡

首先,说声抱歉哈~~,最近更新的比较慢,不是工作比较忙,而是自己变懒了,对不住各位了

一. 前言

由于最近手中的项目在不断更新迭代,经常对服务做些调整,一调整就需要改配置文件,真是烦死了,这里先简单说下我司架构, openresty 当前端网关,利用nginx反向代理多应用服务器,提供服务(不重要的服务省略了),通过查资料发现,利用consul 可以和nginx配合,实现动态修改nginx配置的需求

二. 资源说明

10.10.100.4

  • centos 系统
  • nginx服务
  • consul template服务

10.10.100.3

  • centos 系统
  • consul服务
  • web1服务
  • web2服务

由于资源有限,就开了2台虚拟机来模拟一下,当然可以用docker实现,这里就不演示了,consul服务也不开集群模式了,同时 consul服务与web服务就放在同一个服务器上了,看懂意思就可以了,多个web服务,就以不同的端口来区分

三. 安装过程

3.1 在10.10.100.4安装openresty

 # add the yum repo:
 wget https://openresty.org/package/centos/openresty.repo
 sudo mv openresty.repo /etc/yum.repos.d/
 
 # 更新
 sudo yum check-update
 #安装
 sudo yum install openresty
 #启动
 systemctl start openresty.service 
 #开机自启动
 systemctl enable openresty.service 
 

验证安装成功

  • 浏览器访问 10.10.100.4
  • 10.10.100.4服务器上的命令行中执行curl 127.0.0.1

3.2 在10.10.100.4安装 consul-template

consul-template是基于consul自动替换配置文件的应用。在Consul-Template没出现之前,大家构建服务发现系统大多采用的是Zookeeper、Etcd+Confd这样类似的系统。

Consul官方推出了自己的模板系统Consul-Template后,动态的配置系统可以分化为Etcd+Confd和Consul+Consul-Template两大阵营。Consul-Template的定位和Confd差不多,Confd的后端可以是Etcd或者Consul。

Consul-Template提供了一个便捷的方式从Consul中获取存储的值,Consul-Template守护进程会查询Consul实例来更新系统上指定的任何模板。当更新完成后,模板还可以选择运行一些任意的命令。

 #下载 
 wget https://releases.hashicorp.com/consul-template/0.29.2/consul-template_0.29.2_linux_amd64.zip
 #解压
 unzip consul-template_0.29.2_linux_amd64.zip 
 #添加到环境变量中,这里直接复制到里面
 mv consul-template /usr/local/bin/
 #查看版本
 consul-template -v
 

3.3 在10.10.100.3安装 consul

 sudo yum install -y yum-utils
 #配置源
 sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
 #安装consul
 sudo yum -y install consul
 #查看版本
 consul -v 
 #测试环境这里使用单机 dev模式了,这种模式只能使用127.0.0.1 的ip访问
 consul agent -dev
 #客户端ip访问 可以指定client参数 就可以访问了http://10.10.100.3:8500/ui/dc1/services
 consul agent -dev -ui -client 10.10.100.3
 

3.4 在10.10.100.3安装 web应用服务

这里的web服务,我使用go语言实现了,源码在后面,这里通过不同的端口,来对应多个不同的服务,go程序编译后就是一个二进制文件,直接上传到服务器,运行即可!

上传web服务到10.10.100.3,并启动

 #go程序编译命令
 go build -o web01 main.go
 #修改端口号,重新编译
 go build -o web02 main.go
 #修改端口号,重新编译
 go build -o web03 main.go
 #上传到10.10.100.3服务器的/web目录
 #启动命令
 cd /web
 nohup ./web01 >/dev/null 2>&1 &
 nohup ./web02 >/dev/null 2>&1 &
 nohup ./web03 >/dev/null 2>&1 &

web服务源码如下:

package main

import (
	"fmt"
	consulapi "github.com/hashicorp/consul/api"
	"net/http"
)

const (
	CONSULURL  = "10.10.100.3"
	CONSULPORT = 8500
	SERVERADDR = "10.10.100.3"
	SERVERPORT = 8081  //端口需要修改,8081,  8082 ,8083
	SERVERNAME = "go-server"
	SERVERID   = "100"  //需要修改 100 ,200 ,300
	checkAddr  = "10.10.100.3"
	checkPort  = 8081  //端口需要修改 8081,  8082 ,8083
)

func consulRegister() {
	//链接到consul
	config := consulapi.DefaultConfig()
	config.Address = fmt.Sprintf("%s:%d", CONSULURL, CONSULPORT)
	client, err := consulapi.NewClient(config)
	if err != nil {
		fmt.Println("consul client err ", err)
		return
	}
	//注册服务到consul
	registion := new(consulapi.AgentServiceRegistration)
	registion.ID = SERVERID
	registion.Name = SERVERNAME
	registion.Port = SERVERPORT
	registion.Address = SERVERADDR
	registion.Tags = []string{"web03", "go-web03"}
	//增加consul健康检查回调函数
	check := new(consulapi.AgentServiceCheck)
	check.HTTP = fmt.Sprintf("http://%s:%d%s", checkAddr, checkPort, "/check")
	check.Timeout = "5s"
	check.Interval = "5s"
	check.DeregisterCriticalServiceAfter = "30s" //故障检查失败30s后,自动删除删除
	registion.Check = check
	//注册服务
	err = client.Agent().ServiceRegister(registion)
	if err != nil {
		fmt.Println("注册服务失败", err)
		return
	}
}
func main() {
	consulRegister()
	http.HandleFunc("/check", func(writer http.ResponseWriter, request *http.Request) {
		writer.Write([]byte("我是check "))
	})
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
		writer.Write([]byte("我是8081 端口服务返回的 "))
	})
	fmt.Println("启动....")
	err := http.ListenAndServe(fmt.Sprintf("%s:%d", "", SERVERPORT), nil)
	if err != nil {
		fmt.Println("启动 http 失败", err)
	}
}
 

3.5 在10.10.100.4配置consul-template文件

consul-template的常用参数

 -consul-auth=      设置基本的认证用户名和密码。
 -consul-addr=
设置Consul实例的地址。 -max-stale= 查询过期的最大频率,默认是1s。 -dedup 启用重复数据删除,当许多consul template实例渲染一个模板的时候可以降低consul的负载。 -consul-ssl 使用https连接Consul。 -consul-ssl-verify 通过SSL连接的时候检查证书。 -consul-ssl-cert SSL客户端证书发送给服务器。 -consul-ssl-key 客户端认证时使用的SSL/TLS私钥。 -consul-ssl-ca-cert 验证服务器的CA证书列表。 -consul-token= 设置Consul API的token。 -syslog 把标准输出和标准错误重定向到syslog,syslog的默认级别是local0。 -syslog-facility= 设置syslog级别,默认是local0,必须和-syslog配合使用。 -template=