| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 | package mainimport (	"flag"	"fmt"	"github.com/go-kit/kit/log"	"github.com/hashicorp/consul/api"	"math/rand"	"net/http"	"net/http/httputil"	"os"	"os/signal"	"strings"	"syscall")func main() {	// 创建环境变量	var (		//consulHost = flag.String("consul.host", "114.67.98.210", "consul server ip address")		consulHost = flag.String("consul.host", "106.15.233.99", "consul server ip address")		consulPort = flag.String("consul.port", "8500", "consul server port")	)	flag.Parse()	//创建日志组件	var logger log.Logger	{		logger = log.NewLogfmtLogger(os.Stderr)		logger = log.With(logger, "ts", log.DefaultTimestampUTC)		logger = log.With(logger, "caller", log.DefaultCaller)	}	// 创建consul api客户端	consulConfig := api.DefaultConfig()	consulConfig.Address = "http://" + *consulHost + ":" + *consulPort	consulClient, err := api.NewClient(consulConfig)	if err != nil {		logger.Log("err", err)		os.Exit(1)	}	//创建反向代理	proxy := NewReverseProxy(consulClient, logger)	errc := make(chan error)	go func() {		c := make(chan os.Signal)		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)		errc <- fmt.Errorf("%s", <-c)	}()	//开始监听	go func() {		logger.Log("transport", "HTTP", "addr", "9099")		errc <- http.ListenAndServe(":9099", proxy)	}()	// 开始运行,等待结束	logger.Log("exit", <-errc)}// NewReverseProxy 创建反向代理处理方法func NewReverseProxy(client *api.Client, logger log.Logger) *httputil.ReverseProxy {	//创建Director	director := func(req *http.Request) {		//查询原始请求路径		reqPath := req.URL.Path		if reqPath == "" {			return		}		//按照分隔符'/'对路径进行分解,获取服务名称serviceName		pathArray := strings.Split(reqPath, "/")		serviceName := pathArray[1]		//调用consul api查询serviceName的服务实例列表		result, _, err := client.Catalog().Service(serviceName, "", nil)		if err != nil {			logger.Log("ReverseProxy failed", "query service instance error", err.Error())			return		}		if len(result) == 0 {			logger.Log("ReverseProxy failed", "no such service instance", serviceName)			return		}		//重新组织请求路径,去掉服务名称部分		destPath := strings.Join(pathArray[2:], "/")		//随机选择一个服务实例		tgt := result[rand.Int()%len(result)]		logger.Log("service id", tgt.ServiceID)		//设置代理服务地址信息		req.URL.Scheme = "http"		req.URL.Host = fmt.Sprintf("%s:%d", tgt.ServiceAddress, tgt.ServicePort)		req.URL.Path = "/" + destPath	}	return &httputil.ReverseProxy{Director: director}}
 |