| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 | 
							- package main
 
- import (
 
- 	"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}
 
- }
 
 
  |