Skip to content

Consul

consul, ekiplerin servisler arasında ve çoklu ön hazırlık ve çoklu bulut ortamlarında güvenli bir şekilde ağ bağlantılarını yönetmelerini sağlayan bir çözümdür. Servis keşfi, servis mesh, trafik yönetimi, ağ altyapısı otomatik güncelleme ve daha birçok özellik sunar.

Resmi dokümantasyon: Consul by HashiCorp

Açık kaynak adresi: hashicorp/consul

Consul, HashiCorp şirketi tarafından açık kaynak olarak sunulan bir servis keşfi ve kayıt aracıdır. Raft seçim algoritmasını kullanır ve aracın kendisi Go programlama dili ile geliştirilmiştir, bu nedenle dağıtımı oldukça hafiftir. Consul'ın aşağıdaki özellikleri vardır:

  • Servis keşfi
  • Servis kaydı
  • Sağlık kontrolü
  • Anahtar-değer depolama
  • Çoklu veri merkezi

Aslında consul'ın yapabileceği şeyler servis keşfinden daha fazladır, dağıtık yapılandırma merkezi olarak da kullanılabilir. Benzer açık kaynak araçlar da vardır, örneğin zookeeper, nacos gibi, burada daha fazla tanıtım yapılmayacaktır.

Kurulum

Ubuntu için aşağıdaki komutu çalıştırarak apt ile kurulum yapabilirsiniz

sh
$ wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
$ sudo apt update && sudo apt install consul

Veya resmi web sitesinden ilgili kurulum paketini indirebilirsiniz Install Consul consul go ile geliştirildiği için kurulum paketi tek bir binary çalıştırılabilir dosyadan oluşur ve kurulumu oldukça kolaydır. Kurulum başarılı olduktan sonra aşağıdaki komutu çalıştırarak versiyonu kontrol edebilirsiniz.

sh
$ consul version

Normal çıktı sorun olmadığını gösterir

Consul v1.16.1
Revision e0ab4d29
Build Date 2023-08-05T21:56:29Z
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)

Hızlı Başlangıç

Aşağıda consul tek düğümünü hızlı bir şekilde nasıl kuracağınız tanıtılacaktır. Genellikle tek düğüm geliştirme sırasında test amaçlı kullanılır. Tek düğümde sorun yoksa, büyük olasılıkla çoklu düğüm kümesinde de sorun olmayacaktır. Tek düğüm kurulumu oldukça basittir, sadece tek bir komut satırı yeterlidir

sh
$ consul agent -dev -bind=192.168.48.141 -data-dir=/tmp/consul -ui -node=dev01

Genellikle aşağıdaki gibi çıktı olur

==> Starting Consul agent...
               Version: '1.16.1'
            Build Date: '2023-08-05 21:56:29 +0000 UTC'
               Node ID: 'be6f6b8d-9668-f7ff-8709-ed57c72ffdec'
             Node name: 'dev01'
            Datacenter: 'dc1' (Segment: '<all>')
                Server: true (Bootstrap: false)
           Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, gRPC-TLS: 8503, DNS: 8600)
          Cluster Addr: 192.168.48.141 (LAN: 8301, WAN: 8302)
     Gossip Encryption: false
      Auto-Encrypt-TLS: false
           ACL Enabled: false
     Reporting Enabled: false
    ACL Default Policy: allow
             HTTPS TLS: Verify Incoming: false, Verify Outgoing: false, Min Version: TLSv1_2
              gRPC TLS: Verify Incoming: false, Min Version: TLSv1_2
      Internal RPC TLS: Verify Incoming: false, Verify Outgoing: false (Verify Hostname: false), Min Version: TLSv1_2
==> Log data will now stream in as it occurs:
2023-08-25T17:23:33.763+0800 [DEBUG] agent.grpc.balancer: switching server: target=consul://dc1.be6f6b8d-9668-f7ff-8709-ed57c72ffdec/server.dc1 from=<none> to=<none>
2023-08-25T17:23:33.767+0800 [INFO]  agent.server.raft: initial configuration: index=1 servers="[{Suffrage:Voter ID:be6f6b8d-9668-f7ff-8709-ed57c72ffdec Address:192.168.48.141:8300}]"

Kısaca açıklama

  • agent alt komuttur, consul'ın temel komutudur, consul agent yeni bir consul ajanı çalıştırır, her düğüm bir ajandır.

  • dev, ajanın çalışma modudur, toplamda üç tane vardır: dev, client, server

  • bind, yerel alan ağı iletişim adresi, varsayılan port 8301, genellikle bu değer sunucunun iç ağ adresidir

  • advertise, geniş alan ağı iletişim adresi, varsayılan port 8302, genellikle bu değer sunucunun dış ağ adresidir

  • data-dir, veri depolama dizini

  • config-dir, yapılandırma depolama dizini, consul dizindeki tüm json dosyalarını okur

  • bootstrap, mevcut server'ın bootstrap moduna girdiğini belirtir, raft seçiminde kendisine oy verir, kümede bu modda olan server birden fazla olamaz

  • bootstrap-expect, kümede beklenen server sayısıdır. Belirtilen sayıya ulaşılana kadar küme seçim oylamasına başlamaz, bootstrap ile aynı anda kullanılamaz.

  • retry-join, ajan başlatıldıktan sonra sürekli olarak belirtilen düğümlere katılmayı dener, aşağıdaki servis keşif yöntemlerini de destekler

    aliyun aws azure digitalocean gce hcp k8s linode mdns os packet scaleway softlayer tencentcloud triton vsphere
  • ui, Web arayüzünü çalıştırır

  • node, düğüm adını belirtir, kümede benzersiz olmalıdır.

TIP

Daha fazla ajan parametresi açıklaması için Agents - CLI Reference | Consul | HashiCorp Developer adresine gidin. Bazı parametrelerin sadece kurumsal sürümde kullanılabileceğine dikkat edin.

Başarıyla çalıştırıldıktan sonra 127.0.0.1:8500 adresini ziyaret ederek web arayüzünü görüntüleyebilirsiniz.

dev01 simgesi bir yıldızdır, bu onun leader düğüm olduğunu gösterir.

Çıkış yaparken, diğer düğümlerin mevcut düğümün çıkışını algılayabilmesi için işlemi zorla sonlandırmak önerilmez, şu komutu kullanabilirsiniz

sh
consul leave

veya

sh
consul force-leave

Ayrıca ctrl+c ile consul agent'ın zarif bir şekilde çıkış yapmasını sağlayabilirsiniz.

Kavramlar

Bu bir consul kümesi şemasıdır, şekil iki bölüme ayrılmıştır: kontrol düzlemi ve veri düzlemi. consul sadece kontrol düzleminden sorumludur, servis kümesi ve istemci olarak ayrılır, servis kümesi takipçiler ve lider olarak ayrılır. Genel olarak, şekildaki consul kümesi bir veri merkezi oluşturur. Aşağıda bazı terimler açıklanacaktır

  • Agent (Ajan): Veya düğüm olarak adlandırmak daha uygun olabilir, her ajan uzun süre çalışan bir daemon prosesidir, HTTP ve DNS arayüzlerini dışa açar, sağlık kontrolleri ve servis senkronizasyonundan sorumludur.
  • Server (Servis Ajanı): Bir consul server olarak görevleri Raft seçimlerine katılmak, küme durumunu korumak, sorgulara yanıt vermek, diğer veri merkezleriyle veri alışverişi yapmak ve sorguları lider ve diğer veri merkezlerine yönlendirmektir.
  • Client (İstemci Ajanı): client, server'a göre devletsizdir, Raft seçimlerine katılmaz, yaptığı tek şey tüm istekleri server'a yönlendirmektir, arka planla ilgili tek katıldığı şey yerel alan dedikodu havuzudur (LAN gossip pool).
  • Leader (Lider): leader tüm server'ların lideridir ve sadece bir lider olabilir, leader Raft seçim algoritması ile seçilir, her liderin kendi görev süresi vardır, görev süresi boyunca diğer server'lar ne tür bir istek alırsa alsın lidere bildirmelidir, bu nedenle liderin verisi en güncel ve en yenidir.
  • Gossip (Dedikodu): Consul, Serf (aynı şirketin başka bir ürünü) üzerine inşa edilmiştir, gossip protokolünü kullanır, bu protokol düğümler arası rastgele iletişim için özelleşmiştir, UDP'ye benzer, consul bu protokolü servis kümesi arasında birbirini bilgilendirmek için kullanır.
  • Data Center (Veri Merkezi): Bir yerel alan ağındaki consul kümesine bir veri merkezi denir, consul çoklu veri merkezini destekler, çoklu veri merkezi iletişim yöntemi WAN gossip'tir.

TIP

Daha fazla kelime ve terim için Glossary | Consul | HashiCorp Developer adresini ziyaret edebilirsiniz.

consul kümesinde server sayısı sıkı bir şekilde kontrol edilmelidir, çünkü bunlar doğrudan LAN gossip ve WAN gossip, raft seçimlerine katılır ve veri depolar, server sayısı arttıkça iletişim maliyeti de artar. Client sayısının biraz fazla olması sorun değildir, sadece yönlendirmeden sorumludur, seçimlere katılmaz, kaynak kullanımı düşüktür, şekildaki kümede çeşitli servisler client aracılığıyla kendini server'a kaydeder, eğer bir server kapanırsa client diğer kullanılabilir server'ları kendisi bulur.

Küme Kurulum Örneği

Aşağıda basit bir consul çoklu düğüm küme örneği kurulacaktır, önce dört sanal makine hazırlayın

Dört sanal makinede üç server, bir client vardır, resmi öneri server sayısının tek sayı olması ve en az üç olması yönündedir. Burada vm00-vm02 server olarak, vm03 client olarak kullanılacaktır.

Server için aşağıdaki komutu çalıştırarak server agent oluşturun

sh
consul agent -server -bind=vm_address -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent_name -ui

Client için aşağıdaki komutu çalıştırarak client agent oluşturun

sh
consul agent -client=0.0.0.0  -bind=vm_address -data-dir=/tmp/consul/ -node=agent_name -ui

Çalıştırılan komutlar sırasıyla şöyledir

sh
# vm00
consul agent -server -bind=192.168.48.138 -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent01 -ui -bootstrap

# vm01
consul agent -server -bind=192.168.48.139 -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent02 -ui -retry-join=192.168.48.138

# vm02
consul agent -server -bind=192.168.48.140 -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent03 -ui -retry-join=192.168.48.138

# vm03
consul agent -bind=192.168.48.140 -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent03 -ui -retry-join=192.168.48.138

Bazı parametre açıklamaları

  • client, 0.0.0.0 tüm kaynaklardan gelen istekleri kabul eder, eğer sadece client parametresi varsa ve server parametresi yoksa, agent client modunda çalışacaktır.

Tüm agent'lar çalıştıktan sonra retry-join otomatik olarak join komutunu çalıştırmaya eşdeğerdir, başarısız olduktan sonra sürekli deneyecektir, varsayılan yeniden deneme süresi 30 saniyedir

sh
$ consul join 192.168.48.138

Join tamamlandıktan sonra her düğüm birbirinin varlığından haberdar olur, vm00 bootstrap modu belirttiği için varsayılan lider olur. Eğer bootstrap modu belirtilmezse tüm düğümler join sırasında belirtilen düğüm varsayılan lider olur, lider seçilmeden önce küme normal çalışamaz, web arayüzü 500 hatası döndürür, bazı komutlar da normal çalışmaz. Eğer kümede bir düğüm bootstrap modu belirtirse kümedeki diğer düğümler bootstrap modu belirtmemelidir, aynı zamanda diğer düğümler bootstrap-expect parametresini de kullanmamalıdır, kullanılırsa otomatik olarak devre dışı bırakılır.

Bu noktada lider düğümde (aslında bu noktada herhangi bir düğümde kontrol edilebilir) veri merkezinin üye bilgilerini görüntülemek için aşağıdaki komutu çalıştırın

sh
$ consul members
Node      Address              Status  Type    Build   Protocol  DC   Partition  Segment
agent01   192.168.48.138:8301  alive   server  1.16.1  2         dc1  default    <all>
agent02   192.168.48.139:8301  alive   server  1.16.1  2         dc1  default    <all>
agent03   192.168.48.140:8301  alive   server  1.16.1  2         dc1  default    <all>
client01  192.168.48.141:8301  alive   client  1.16.1  2         dc1  default    <default>
  • Node, düğüm adı
  • Address, iletişim adresi
  • Status, alive canlı olduğunu gösterir, left çevrimdışı olduğunu gösterir
  • Type, ajan türü, server ve client olmak üzere iki mod
  • Build, düğümün kullandığı consul versiyonu, consul farklı versiyonlardaki düğümlerle belirli bir aralıkta çalışabilir
  • Protocol, kullanılan Raft protokol versiyonudur, bu protokol tüm düğümlerde tutarlı olmalıdır
  • DC, Data Center, veri merkezi, çıktıda tüm düğümler dc1 veri merkezine aittir
  • Partition, düğümün ait olduğu bölüm, kurumsal sürüm özelliği, her düğüm sadece aynı bölümdeki düğümlerle iletişim kurabilir
  • Segment, düğümün ait olduğu ağ segmenti, kurumsal sürüm özelliği

Aynı şekilde, bir düğümün çıkış yapmasını istiyorsanız consul leave kullanarak düğümün zarif bir şekilde çıkış yapmasını ve diğer düğümlere çıkış yapacağını bildirmesini sağlamalısınız, çoklu düğüm durumunda düğümün zarif çıkışı özellikle önemlidir çünkü bu veri tutarlılığı ile ilgilidir.

TIP

Sanal makineler gösterim sırasında tüm güvenlik duvarlarını kapattı, gerçek üretim ortamında güvenlik nedeniyle açılmalıdır, bu nedenle consul'ın kullandığı tüm portlara dikkat etmelisiniz: Required Ports | Consul | HashiCorp Developer.

Ardından veri tutarlılığını basitçe test edelim, vm00 sanal makinesinde aşağıdaki verileri ekleyin

sh
$ consul kv put sys_confg {"name":"consul"}
Success! Data written to: sys_confg

Kaydedildikten sonra HTTP API aracılığıyla diğer düğümlere eriştiğinizde verilerin aynı şekilde mevcut olduğunu göreceksiniz (içindeki value base64 kodludur)

sh
$ curl http://192.168.48.138:8500/v1/kv/sys_confg
[{"LockIndex":0,"Key":"sys_confg","Flags":0,"Value":"ewogICJuYW1lIjoiY29uc3VsIgp9","CreateIndex":2518,"ModifyIndex":2518}]
$ curl http://192.168.48.139:8500/v1/kv/sys_confg
[{"LockIndex":0,"Key":"sys_confg","Flags":0,"Value":"ewogICJuYW1lIjoiY29uc3VsIgp9","CreateIndex":2518,"ModifyIndex":2518}]
$ curl http://192.168.48.140:8500/v1/kv/sys_confg
[{"LockIndex":0,"Key":"sys_confg","Flags":0,"Value":"ewogICJuYW1lIjoiY29uc3VsIgp9","CreateIndex":2518,"ModifyIndex":2518}]

Aslında consul'ın sağladığı servis keşfi ve kayıt işlevi gossip protokolü aracılığıyla diğer düğümlere yayınlanır ve herhangi bir düğüm mevcut veri merkezine katıldığında tüm düğümler bu değişikliği algılar.

Çoklu Veri Merkezi Kurulum Örneği

Beş sanal makine hazırlayın, vm00-vm02 önceki örneğin kümesidir, dc1 veri merkezine aittir, ona dokunmayın, vm03-vm04 dc2 veri merkezine aittir, veri merkezi ajan başlatıldığında varsayılan olarak dc1'dir.

TIP

Burada gösterim için sadece server kuruldu, client atlandı.

Önce vm03'ü sırasıyla başlatın, varsayılan lider olarak kullanılacaktır

sh
$ consul agent -server -datacenter=dc2 -bind=192.168.48.141 -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent04 -ui -bootstrap

vm04'ü başlatın, vm03 düğümüne otomatik olarak katılmasını sağlayın

sh
$ consul agent -server -datacenter=dc2 -bind=192.168.48.142 -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent05 -ui -retry-join=192.168.48.141

Bu noktada sırasıyla vm00 ve vm03'te members kontrolünü yapın

sh
# vm00-vm02
$ consul members
Node      Address              Status  Type    Build   Protocol  DC   Partition  Segment
agent01   192.168.48.138:8301  alive   server  1.16.1  2         dc1  default    <all>
agent02   192.168.48.139:8301  alive   server  1.16.1  2         dc1  default    <all>
agent03   192.168.48.140:8301  alive   server  1.16.1  2         dc1  default    <all>

# vm03-vm04
$ consul members
Node     Address              Status  Type    Build   Protocol  DC   Partition  Segment
agent04  192.168.48.141:8301  alive   server  1.16.1  2         dc2  default    <all>
agent05  192.168.48.142:8301  alive   server  1.16.1  2         dc2  default    <all>

DC alanının farklı olduğunu görebilirsiniz, burada sanal makine gösterimi olduğu için aynı ağ segmentindeler, gerçekte iki veri merkezi farklı bölgelerdeki sunucu kümeleri olabilir. Ardından dc1'in herhangi bir düğümünün dc2'nin herhangi bir düğümüne katılmasını sağlayın, burada vm01'in vm03'e katılmasını sağlayın

sh
$ consul join -wan 192.168.48.141
Successfully joined cluster by contacting 1 nodes.

Join başarılı olduktan sonra geniş alan ağı members kontrolünü yapmak için komutu çalıştırın

sh
$ consul members -wan
Node         Address              Status  Type    Build   Protocol  DC   Partition  Segment
agent01.dc1  192.168.48.138:8302  alive   server  1.16.1  2         dc1  default    <all>
agent02.dc1  192.168.48.139:8302  alive   server  1.16.1  2         dc1  default    <all>
agent03.dc1  192.168.48.140:8302  alive   server  1.16.1  2         dc1  default    <all>
agent04.dc2  192.168.48.141:8302  alive   server  1.16.1  2         dc2  default    <all>
agent05.dc2  192.168.48.142:8302  alive   server  1.16.1  2         dc2  default    <all>

$ consul catalog datacenters
dc2
dc1

dc1'in herhangi bir düğümü dc2'nin herhangi bir düğümüne katıldığında iki veri merkezindeki tüm düğümler bu değişikliği algılar, members kontrolü yaparken de iki veri merkezinin düğümlerini görebilirsiniz.

Ardından vm00 düğümünde bir KV veri eklemeyi deneyin

sh
$ consul kv put name consul
Success! Data written to: name

vm01 düğümünde veriyi okumayı deneyin, aynı veri merkezinin verilerinin senkronize olduğunu görebilirsiniz

sh
$ consul kv get name
consul

Ardından farklı veri merkezindeki vm03'te veriyi okumayı deneyin, farklı veri merkezlerinin verilerinin senkronize olmadığını göreceksiniz.

sh
$ consul kv get name
Error! No key exists at: name

Çoklu veri merkezi veri senkronizasyonu istiyorsanız hashicorp/consul-replicate: Consul cross-DC KV replication daemon projesini inceleyebilirsiniz.

Servis Kaydı ve Keşfi

consul servis kayıt yöntemi iki türlüdür: yapılandırma dosyası kaydı ve API kaydı. Kolay test için burada önceden bir Hello World servisi (gRPC makalesindeki örnek) hazırlanmıştır, iki kopya dağıtılmıştır, farklı konumlardadırlar. Yapılandırma dosyası kayıt yöntemi için Register external services with Consul service discovery | Consul | HashiCorp Developer adresini ziyaret edebilirsiniz, burada sadece HTTP API aracılığıyla kayıt tanıtılacaktır.

TIP

Yerel servisler için (consul client ile birlikte) doğrudan agent service kaydı kullanılabilir, aksi takdirde catalog register kullanılarak kayıt yapılmalıdır.

consul HTTP API SDK sağlar, diğer dillerin SDK'ları için Libraries and SDKs - HTTP API | Consul | HashiCorp Developer adresini ziyaret edebilirsiniz. Burada go bağımlılığı indirilir

sh
go get github.com/hashicorp/consul/api

Servis başlatıldığında consul'a aktif olarak servis kaydı yapılır, servis kapatıldığında consul'dan servis kaydı silinir, aşağıda bir örnek verilmiştir.

go
package main

import (
  consulapi "github.com/hashicorp/consul/api"
  "google.golang.org/grpc"
  "google.golang.org/grpc/credentials/insecure"
  pb "grpc_learn/helloworld/hello"
  "log"
  "net"
)

var (
  server01 = &consulapi.AgentService{
        // Benzersiz olmalıdır
    ID:      "hello-service1",
    Service: "hello-service",
        // İki kopya dağıtılmıştır, birinin portu 8080, diğerinin portu 8081
    Port:    8080,
  }
)

// Servis kaydı
func Register() {
  client, _ := consulapi.NewClient(&consulapi.Config{Address: "192.168.48.138:8500"})
  _, _ = client.Catalog().Register(&consulapi.CatalogRegistration{
    Node:    "hello-server",
    Address: "192.168.2.10",
    Service: server01,
  }, nil)
}

// Servis kaydını sil
func DeRegister() {
  client, _ := consulapi.NewClient(&consulapi.Config{Address: "192.168.48.138:8500"})
  _, _ = client.Catalog().Deregister(&consulapi.CatalogDeregistration{
    Node:      "hello-server",
    Address:   "192.168.2.10",
    ServiceID: server01.ID,
  }, nil)
}

func main() {
  Register()
  defer DeRegister()

  // Portu dinle
  listen, err := net.Listen("tcp", ":8080")
  if err != nil {
    panic(err)
  }
  // gprc sunucusu oluştur
  server := grpc.NewServer(
    grpc.Creds(insecure.NewCredentials()),
  )
  // Servis kaydı
  pb.RegisterSayHelloServer(server, &HelloRpc{})
  log.Println("server running...")
  // Çalıştır
  err = server.Serve(listen)
  if err != nil {
    panic(err)
  }
}

İstemci kodu, kayıt merkezinden ilgili servisi sorgulamak ve gerçek adrese çözümlemek için consul özel çözümleyici kullanır.

go
package myresolver

import (
    "fmt"
    consulapi "github.com/hashicorp/consul/api"
    "google.golang.org/grpc/resolver"
)

func NewConsulResolverBuilder(address string) ConsulResolverBuilder {
    return ConsulResolverBuilder{consulAddress: address}
}

type ConsulResolverBuilder struct {
    consulAddress string
}

func (c ConsulResolverBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
    consulResolver, err := newConsulResolver(c.consulAddress, target, cc)
    if err != nil {
       return nil, err
    }
    consulResolver.resolve()
    return consulResolver, nil
}

func (c ConsulResolverBuilder) Scheme() string {
    return "consul"
}

func newConsulResolver(address string, target resolver.Target, cc resolver.ClientConn) (ConsulResolver, error) {
    var reso ConsulResolver
    client, err := consulapi.NewClient(&consulapi.Config{Address: address})
    if err != nil {
       return reso, err
    }
    return ConsulResolver{
       target: target,
       cc:     cc,
       client: client,
    }, nil
}

type ConsulResolver struct {
    target resolver.Target
    cc     resolver.ClientConn
    client *consulapi.Client
}

func (c ConsulResolver) resolve() {
    service := c.target.URL.Opaque
    services, _, err := c.client.Catalog().Service(service, "", nil)
    if err != nil {
       c.cc.ReportError(err)
       return
    }
    var adds []resolver.Address
    for _, catalogService := range services {
       adds = append(adds, resolver.Address{Addr: fmt.Sprintf(fmt.Sprintf("%s:%d", catalogService.Address, catalogService.ServicePort))})
    }

    c.cc.UpdateState(resolver.State{
       Addresses: adds,
       // Round-robin stratejisi
       ServiceConfig: c.cc.ParseServiceConfig(
          `{"loadBalancingPolicy":"round_robin"}`),
    })
}

func (c ConsulResolver) ResolveNow(options resolver.ResolveNowOptions) {
    c.resolve()
}

func (c ConsulResolver) Close() {

}

İstemci başlatıldığında çözümleyici kaydı yapılır

go
package main

import (
    "context"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
    "google.golang.org/grpc/resolver"
    "grpc_learn/helloworld/client/myresolver"
    hello2 "grpc_learn/helloworld/hello"
    "log"
    "time"
)

func init() {
    // builder kaydı
    resolver.Register(
       // Özel consul çözümleyici kaydı
       myresolver.NewConsulResolverBuilder("192.168.48.138:8500"),
    )
}

func main() {

    // Bağlantı kur, şifreleme doğrulaması yok
    conn, err := grpc.Dial("consul:hello-service",
       grpc.WithTransportCredentials(insecure.NewCredentials()),
    )
    if err != nil {
       panic(err)
    }
    defer conn.Close()
    // İstemci oluştur
    client := hello2.NewSayHelloClient(conn)
    for range time.Tick(time.Second) {
       // Uzaktan çağrı
       helloRep, err := client.Hello(context.Background(), &hello2.HelloReq{Name: "client"})
       if err != nil {
          panic(err)
       }
       log.Printf("received grpc resp: %+v", helloRep.String())
    }

}

Önce sunucu tarafını başlatın, ardından istemciyi başlatın, sunucu iki tanedir, aynı servisi sağlar, sadece adresler farklı, istemcinin yük dengeleme stratejisi round-robin'dir, sunucu log aralığından stratejinin etkili olduğu görülebilir.

2023/08/29 17:39:54 server running...
2023/08/29 21:03:46 received grpc req: name:"client"
2023/08/29 21:03:48 received grpc req: name:"client"
2023/08/29 21:03:50 received grpc req: name:"client"
2023/08/29 21:03:52 received grpc req: name:"client"
2023/08/29 21:03:54 received grpc req: name:"client"
2023/08/29 21:03:56 received grpc req: name:"client"
2023/08/29 21:03:58 received grpc req: name:"client"
2023/08/29 21:04:00 received grpc req: name:"client"

Yukarıdaki, consul ile gRPC'yi birleştirerek servis kaydı ve keşfi实现leyen basit bir örnektir.

Golang by www.golangdev.cn edit