go基于consul的负载均衡|青训营笔记

75 阅读1分钟

这是我参与[第五届青训营]的第十七天

在通常用 Go 编写的无状态微服务中,我们需要发现它们。这就是 Hashicorp 的 Consul 提供的帮助。服务在 Consul 中注册,以便其他服务可以通过简单的 DNS 或 HTTP 查询发现它们。

从一个基本的 Web 服务开始,该服务将从 Redis 提供键值数据。

首先,解析portttladdrs命令行标志。最后一个是用.分隔的Redis地址列表;

func main() {
	port := flag.Int("port", 8080, "Port to listen on")
	addrsStr := flag.String("addrs", "", "(Required) Redis addrs (may be delimited by ;)")
	ttl := flag.Duration("ttl", time.Second*15, "Service TTL check duration")
	flag.Parse()

	if len(*addrsStr) == 0 {
		fmt.Fprintln(os.Stderr, "addrs argument is required")
		flag.PrintDefaults()
		os.Exit(1)
	}

	addrs := strings.Split(*addrsStr, ";")

现在,我们创建一个应该实现[Handler]接口并启动它的服务。

	s, err := service.New(addrs, *ttl)
	if err != nil {
		log.Fatal(err)
	}
	http.Handle("/", s)

	l := fmt.Sprintf(":%d", *port)
	log.Print("Listening on ", l)
	log.Fatal(http.ListenAndServe(l, nil))
import (
	"time"

	"github.com/go-redis/redis"
)

type Service struct {
	Name        string
	TTL         time.Duration
	RedisClient redis.UniversalClient
}

Service是一种包含名称、TTL 和 Redis 客户端处理程序的类型。它是这样实例化的:

func New(addrs []string, ttl time.Duration) (*Service, error) {
	s := new(Service)
	s.Name = "webkv"
	s.TTL = ttl
	s.RedisClient = redis.NewUniversalClient(&redis.UniversalOptions{
		Addrs: addrs,
	})

	ok, err := s.Check()
	if !ok {
		return nil, err
	}

	return s, nil
}

Check方法发出PINGRedis 命令来检查我们是否正常。这将在稍后与 Consul 注册一起使用。

func (s *Service) Check() (bool, error) {
	_, err := s.RedisClient.Ping().Result()
	if err != nil {
		return false, err
	}
	return true, nil

现在ServeHTTP将调用请求处理方法的实现:

func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	status := 200

	key := strings.Trim(r.URL.Path, "/")
	val, err := s.RedisClient.Get(key).Result()
	if err != nil {
		http.Error(w, "Key not found", http.StatusNotFound)
		status = 404
	}

	fmt.Fprint(w, val)
	log.Printf("url="%s" remote="%s" key="%s" status=%d\n",
		r.URL, r.RemoteAddr, key, status)
}

基本上,我们所做的是从请求中检索 URL 路径并将其用作 Redis“GET”命令的键。之后我们返回值或 404 以防出错。[最后,我们使用logfmt 格式]的快速的结构化日志消息记录请求 。