Consul & Consul-template & Nginx 动态更新Nginx配置文件实现简单的网关

Consul & Consul-template & Nginx 动态更新Nginx配置文件实现简单的网关
注册服务到Consul

我注册了两个服务到Consul中,只是将下面程序中的localPort更改成81与82两个不一样的端口进行监听

Consul & Consul-template & Nginx 动态更新Nginx配置文件实现简单的网关_第1张图片

package main

import (
	"fmt"
	"log"
	"net/http"

	consulapi "github.com/hashicorp/consul/api"
)

const (
	consulAddress = "agent ip:8500"
	localIp       = "localhost ip"
	localPort     = 82
)

func consulRegister() {
	// 创建连接consul服务配置
	config := consulapi.DefaultConfig()
	config.Address = consulAddress
	client, err := consulapi.NewClient(config)
	if err != nil {
		fmt.Println("consul client error : ", err)
	}

	// 创建注册到consul的服务到
	registration := new(consulapi.AgentServiceRegistration)
	registration.ID = "2"
	registration.Name = "LoginService"
	registration.Port = localPort
	registration.Tags = []string{"testService"}
	registration.Address = localIp

	// 增加consul健康检查回调函数
	check := new(consulapi.AgentServiceCheck)
	check.HTTP = fmt.Sprintf("http://%s:%d", registration.Address, registration.Port)
	check.Timeout = "5s"
	check.Interval = "5s"
	check.DeregisterCriticalServiceAfter = "30s" // 故障检查失败30s后 consul自动将注册服务删除
	registration.Check = check

	// 注册服务到consul
	err = client.Agent().ServiceRegister(registration)
	if err != nil {
		log.Println(err)
	}
}

func Handler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("localhost ip:82 Login Success"))
}

func main() {
	consulRegister()
	//定义一个http接口
	http.HandleFunc("/", Handler)
	err := http.ListenAndServe("0.0.0.0:82", nil)
	if err != nil {
		fmt.Println("error: ", err.Error())
	}
}
编写Consul-template模板文件

这里配置文件有个坑,如果你是使用的docker容器中的Nginx,请将 server_name 换成 服务器ip

{{range service ["name"]}} //获取已注册的集群名为name的集群
{{.Address}}//获取该集群下每个节点的Address
{{.Port}}//获取每个节点的端口
{{end}}//结束该循环,切记end不可遗落,否则启动consul-template时会报错
注:在upstream中写入模板时,切记集群中至少要有一个服务端会运行,因为nginx关系,若upstream中无节点时,会报错,导致consul-template运行失败,从而使consul-template停止运行。


user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    upstream loginService {
	{{ range service "LoginService" }}
	server {{ .Address }}:{{ .Port }} weight=1;{{ end }}
    }

    server {
        listen       80;
        server_name  localhost;

        location / {
           proxy_pass http://loginService;
        }

    }
}
启动Consul-template监控Consul服务列表

这里配置文件有个坑,如果你是使用的是本机的nginx,请将 docker restart nginx容器id 换成 nginx -s reload

consul-template -consul-addr 127.0.0.1:8500 -template "./consul-template.tpl:/home/server/nginx/conf/nginx.conf:docker restart nginx-grpc"

-consul-addr [ip] //从该ip连接consul集群,获取信息
-template [string] //consul-template在发现consul集群有变更时,运行该string语句
//该语句通常为:"模板地址:nginx配置文件地址:docker restart nginx-grpc"
// 意为 Consul 服务列表发生变化时,就会使用模板文件来覆盖 nginx 配置文件 并执行 docker restart nginx-grpc
//一般模板后缀为tpl

你可能感兴趣的:(golang,nginx,consul,gateway)