zoukankan      html  css  js  c++  java
  • go Consul服务治理

    目前市面上常见的服务治理有consul,etcd,zookeeper,euerka,我们需要根据自己的服务特点选择自己相对合适的服务治理工具。

    FeatureConsulzookeeperetcdeuerka
    服务健康检查 服务状态,内存,硬盘等 (弱)长连接,keepalive 连接心跳 可配支持
    多数据中心 支持
    kv存储服务 支持 支持 支持
    一致性 raft paxos raft
    cap ca cp cp ap
    使用接口(多语言能力) 支持http和dns 客户端 http/grpc http(sidecar)
    watch支持 全量/支持long polling 支持 支持 long polling 支持 long polling/大部分增量
    自身监控 metrics metrics metrics
    安全 acl /https acl https支持(弱)
    spring cloud集成 已支持 已支持 已支持 已支持

    调研一个工具需要看到其优点,更需要看到其缺点,当服务优点大于自身业务需求缺点,且缺点有对应的解决方案时,我们可以倾向于考虑。

    euerka 据说现在已停止维护,决定不考虑使用。

    zookeeper 为java开发的,需要java环境,相对比较复杂,优先级较低。

    etcd 与consul为go开发,部署简单,功能相对更符合自身业务的需求。

    consul监控检查更为丰富,支持多数据中心,webui查看等,配合consul-template实现nginx动态负载均衡等特点更符合自身业务需求,因为决定选用consul作为业务的服务治理工具。

    使用consul,其主要有四大特性:

    1. 服务发现:利用服务注册,服务发现功能来实现服务治理。

    2. 健康检查:利用consul注册的检查检查函数或脚本来判断服务是否健康,若服务不存在则从注册中心移除该服务,减少故障服务请求。

    3. k/v数据存储:存储kv数据,可以作为服务配置中心来使用。

    4. 多数据中心:可以建立多个consul集群通过inter网络进行互联,进一步保证数据可用性。

    本人也是刚开始学习consul,感觉使用consul主要也就是两大作用,服务注册发现,配置共享。

    现在开始学习consul:

    启动单机consul:consul agent -server -bootstrap-expect=1 -data-dir=data -node=consul -bind=x172.16.242.129-ui -client=0.0.0.0

    我们可已通过consul --help 修改一些配置信息,比如集群个数,绑定地址,数据存放地址,配置文件地址,加入集群等配置

    启动consul后我们可以通过web查看consul运行状况:http://172.16.242.129:8500/ui/dc1/nodes

    服务启动后,现在开始测试consul的第一个功能:服务注册发现,本人使用的为go语言, 下面主要为服务注册,发现的一个demo, 需要注意的是,根据自身的实际配置去修改consul的地址信息和要注册服务的地址信息

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    
    	consulapi "github.com/hashicorp/consul/api"
    	"net/http"
    	"fmt"
    	"log"
    )
    
    func main() {
    	r := gin.Default()
    
    	// consul健康检查回调函数
    	r.GET("/", func(c *gin.Context) {
    		c.JSON(200, gin.H{
    			"message": "ok",
    		})
    	})
    
    
    	// 注册服务到consul
    	ConsulRegister()
    
    	// 从consul中发现服务
    	ConsulFindServer()
    
    	// 取消consul注册的服务
    	//ConsulDeRegister()
    
    
    	http.ListenAndServe(":8081", r)
    }
    
    // 注册服务到consul
    func ConsulRegister()  {
    	// 创建连接consul服务配置
    	config := consulapi.DefaultConfig()
    	config.Address = "172.16.242.129:8500"
    	client, err := consulapi.NewClient(config)
    	if err != nil {
    		log.Fatal("consul client error : ", err)
    	}
    
    	// 创建注册到consul的服务到
    	registration := new(consulapi.AgentServiceRegistration)
    	registration.ID = "111"
    	registration.Name = "go-consul-test"
    	registration.Port = 8081
    	registration.Tags = []string{"go-consul-test"}
    	registration.Address = "10.13.153.128"
    
    	// 增加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)
    }
    
    // 取消consul注册的服务
    func ConsulDeRegister()  {
    	// 创建连接consul服务配置
    	config := consulapi.DefaultConfig()
    	config.Address = "172.16.242.129:8500"
    	client, err := consulapi.NewClient(config)
    	if err != nil {
    		log.Fatal("consul client error : ", err)
    	}
    
    	client.Agent().ServiceDeregister("111")
    }
    
    // 从consul中发现服务
    func ConsulFindServer()  {
    	// 创建连接consul服务配置
    	config := consulapi.DefaultConfig()
    	config.Address = "172.16.242.129:8500"
    	client, err := consulapi.NewClient(config)
    	if err != nil {
    		log.Fatal("consul client error : ", err)
    	}
    
    	// 获取所有service
    	services, _ := client.Agent().Services()
    	for _, value := range services{
    		fmt.Println(value.Address)
    		fmt.Println(value.Port)
    	}
    
    	fmt.Println("=================================")
    	// 获取指定service
    	service, _, err := client.Agent().Service("111", nil)
    	if err == nil{
    		fmt.Println(service.Address)
    		fmt.Println(service.Port)
    	}
    
    }
    
    func ConsulCheckHeath()  {
    	// 创建连接consul服务配置
    	config := consulapi.DefaultConfig()
    	config.Address = "172.16.242.129:8500"
    	client, err := consulapi.NewClient(config)
    	if err != nil {
    		log.Fatal("consul client error : ", err)
    	}
    
    	// 健康检查
    	a, b, _ := client.Agent().AgentHealthServiceByID("111")
    	fmt.Println(a)
    	fmt.Println(b)
    }
    
    func ConsulKVTest()  {
    	// 创建连接consul服务配置
    	config := consulapi.DefaultConfig()
    	config.Address = "172.16.242.129:8500"
    	client, err := consulapi.NewClient(config)
    	if err != nil {
    		log.Fatal("consul client error : ", err)
    	}
    
    	// KV, put值
    	values := "test"
    	key := "go-consul-test/172.16.242.129:8100"
    	client.KV().Put(&consulapi.KVPair{Key:key, Flags:0, Value: []byte(values)}, nil)
    
    	// KV get值
    	data, _, _ := client.KV().Get(key, nil)
    	fmt.Println(string(data.Value))
    
    	// KV list
    	datas, _ , _:= client.KV().List("go", nil)
    	for _ , value := range datas{
    		fmt.Println(value)
    	}
    	keys, _ , _ := client.KV().Keys("go", "", nil)
    	fmt.Println(keys)
    }

    我们可根据上述功能去实现一个服务注册,服务发现,配置共享的功能,我们可以围绕这些根据自身业务需求进行灵活的变动,个人想法:根据此功能专门做一个服务管理的模块,客户端注册服务到服务模块,服务管理去提供其他模块的服务发现的功能,同时跟监控结合,当服务不可用时,或服务不存在时,通过监控通知相关人员,我们也可以使用页面跟我们服务管理结合,通过前台服务录入形式进行注册服务等等。

    假如公司服务使用nginx负载均衡的话,我们可与consul和consul-template结合,动态生成nginx的配置文件,然后重新reload nginx,实现nginx的动态负载均衡。

    当然还有其他方式实现nginx的动态负载均衡,如使用nginx-upsync-module和consul,openResty的lua脚本实现nginx动态负载均衡。

  • 相关阅读:
    《javascript设计模式》2接口
    对css类名className的一些操作的函数
    js设计模式方法的链式调用及回调
    js设计模式封装
    ajax的封装
    js设计模式单体(Singleton)
    js设计模式继承
    metasploit
    使用 AsyncCallback 处理异步调用
    log4net 的使用
  • 原文地址:https://www.cnblogs.com/hcy-fly/p/10826607.html
Copyright © 2011-2022 走看看