Consul

Consul ist eine Lösung, die Teams ermöglicht, Netzwerkverbindungen zwischen Diensten in vor-ort und Multi-Cloud-Umgebungen sicher zu verwalten. Es bietet eine Reihe von Funktionen wie Service Discovery, Service Mesh, Datenverkehrskontrolle und automatische Aktualisierung der Netzwerkinfrastruktur.
Offizielle Dokumentation: Consul by HashiCorp
Open-Source-Adresse: hashicorp/consul
Consul ist ein Open-Source-Tool für Service Discovery und Registrierung von HashiCorp. Es verwendet den Raft-Wahalgorithmus und ist in Go entwickelt, was die Bereitstellung sehr einfach macht. Consul hat folgende Eigenschaften:
- Service Discovery
- Service Registrierung
- Gesundheitsprüfung
- Schlüssel-Wert-Speicher
- Mehrere Rechenzentren
Tatsächlich kann Consul mehr als nur Service Discovery. Es kann auch als verteiltes Konfigurationszentrum verwendet werden. Es gibt viele ähnliche Open-Source-Tools wie Zookeeper und Nacos, auf die hier nicht weiter eingegangen wird.
Installation
Für Ubuntu können Sie Consul mit folgenden Befehlen über apt installieren:
$ 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 consulAlternativ können Sie das entsprechende Installationspaket von der offiziellen Website herunterladen: Install Consul. Da Consul in Go entwickelt wurde, enthält das Installationspaket nur eine binäre ausführbare Datei, was die Installation sehr einfach macht. Nach erfolgreicher Installation können Sie die Version mit folgendem Befehl überprüfen:
$ consul versionEine korrekte Ausgabe zeigt, dass alles funktioniert:
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)Schnellstart
Im Folgenden wird beschrieben, wie Sie schnell einen einzelnen Consul-Knoten einrichten. Einzelknoten werden normalerweise für Tests während der Entwicklung verwendet. Wenn der Einzelknoten problemlos funktioniert, wird auch ein Multi-Knoten-Cluster mit hoher Wahrscheinlichkeit funktionieren. Die Einrichtung eines Einzelknotens ist sehr einfach und erfordert nur einen Befehl:
$ consul agent -dev -bind=192.168.48.141 -data-dir=/tmp/consul -ui -node=dev01Typischerweise erhalten Sie folgende Ausgabe:
==> 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}]"Kurze Erläuterung der Parameter:
agentist ein Unterbefehl und der Kernbefehl von Consul.consul agentstartet einen neuen Consul-Agenten. Jeder Knoten ist ein Agent.devist der Betriebsmodus des Agenten. Es gibt drei Modi:dev,clientundserver.bindist die LAN-Kommunikationsadresse. Der Standardport ist 8301. Normalerweise ist dies die interne Netzwerkadresse des Servers.advertiseist die WAN-Kommunikationsadresse. Der Standardport ist 8302. Normalerweise ist dies die öffentliche Netzwerkadresse des Servers.data-dirist das Verzeichnis für die Datenspeicherung.config-dirist das Verzeichnis für die Konfiguration. Consul liest alle JSON-Dateien in diesem Verzeichnis.bootstrapmarkiert den aktuellen Server als Bootstrap-Modus. Bei der Raft-Wahl gibt er seine eigene Stimme ab. In einem Cluster darf nur ein Server in diesem Modus sein.bootstrap-expectist die erwartete Anzahl von Servern im Cluster. Bis diese Anzahl erreicht ist, beginnt der Cluster nicht mit der Wahl. Kann nicht zusammen mitbootstrapverwendet werden.retry-joinbewirkt, dass der Agent nach dem Start wiederholt versucht, dem angegebenen Knoten beizutreten. Es werden auch folgende Cloud-Provider-Discovery-Methoden unterstützt:aliyun aws azure digitalocean gce hcp k8s linode mdns os packet scaleway softlayer tencentcloud triton vsphereuistartet das Web-Backend.nodegibt den Knotennamen an, der im Cluster eindeutig sein muss.
TIP
Weitere Parametererklärungen für den Agenten finden Sie unter Agents - CLI Reference | Consul | HashiCorp Developer. Beachten Sie, dass einige Parameter nur in der Enterprise-Version verfügbar sind.
Nach erfolgreichem Start können Sie die Web-Oberfläche unter 127.0.0.1:8500 aufrufen.

Das Stern-Symbol bei dev01 zeigt an, dass es sich um den Leader-Knoten handelt.
Beim Beenden sollten Sie den Prozess nicht gewaltsam beenden, damit andere Knoten das Verlassen bemerken. Verwenden Sie stattdessen den Befehl:
consul leaveoder
consul force-leaveAlternativ können Sie ctrl+c drücken, um den Consul-Agenten ordnungsgemäß zu beenden.
Konzepte
Dies ist ein Diagramm eines Consul-Clusters. Die Abbildung ist in zwei Teile unterteilt: die Kontrollebene und die Datenebene. Consul ist nur für die Kontrollebene verantwortlich und ist in Server-Cluster und Clients unterteilt. Der Server-Cluster ist wiederum in Follower und Leader unterteilt. Insgesamt bildet der Consul-Cluster in der Abbildung ein Rechenzentrum. Im Folgenden werden einige Begriffe erläutert:
Agent: Ein Agent ist ein lang laufender Daemon-Prozess, der HTTP- und DNS-Schnittstellen nach außen bereitstellt und für Gesundheitsprüfungen und Dienstsynchronisation verantwortlich ist.
Server: Als Consul-Server sind seine Hauptaufgaben die Teilnahme an der Raft-Wahl, die Aufrechterhaltung des Cluster-Status, die Beantwortung von Anfragen, der Datenaustausch mit anderen Rechenzentren sowie die Weiterleitung von Anfragen an den Leader und andere Rechenzentren.
Client: Im Vergleich zum Server ist der Client zustandslos. Er nimmt nicht an der Raft-Wahl teil. Seine einzige Aufgabe ist die Weiterleitung aller Anfragen an den Server. Die einzige Backend-bezogene Aufgabe, an der er teilnimmt, ist die LAN-Gossip-Weiterleitung (LAN gossip pool).
Leader: Der Leader ist der Anführer aller Server, und es kann nur einen Leader geben. Der Leader wird durch den Raft-Wahalgorithmus gewählt. Jeder Leader hat seine eigene Amtszeit. Während der Amtszeit muss jeder Server den Leader über jede eingehende Anfrage informieren, daher sind die Daten des Leaders immer aktuell.
Gossip: Consul basiert auf Serf (einem anderen Produkt von HashiCorp) und verwendet das Gossip-Protokoll. Dieses Protokoll dient der zufälligen Kommunikation zwischen Knoten, ähnlich wie UDP. Consul verwendet dieses Protokoll für die gegenseitige Benachrichtigung zwischen Server-Clustern.
Data Center: Ein Consul-Cluster in einem LAN wird als ein Rechenzentrum bezeichnet. Consul unterstützt mehrere Rechenzentren. Die Kommunikation zwischen mehreren Rechenzentren erfolgt über WAN-Gossip.
TIP
Weitere Begriffe und Terminologie finden Sie unter Glossary | Consul | HashiCorp Developer.
In einem Consul-Cluster sollte die Anzahl der Server streng kontrolliert werden, da sie direkt an LAN-Gossip, WAN-Gossip und der Raft-Wahl teilnehmen und Daten speichern müssen. Je mehr Server, desto höher die Kommunikationskosten. Die Anzahl der Clients kann etwas höher sein, da sie nur für die Weiterleitung zuständig sind und nicht an Wahlen teilnehmen, was sehr wenige Ressourcen verbraucht. Im Cluster in der Abbildung registrieren sich die verschiedenen Dienste über Clients beim Server. Wenn ein Server ausfällt, sucht der Client automatisch nach einem anderen verfügbaren Server.
Cluster-Einrichtungsbeispiel
Im Folgenden wird ein einfaches Beispiel für einen Multi-Knoten-Consul-Cluster eingerichtet. Bereiten Sie zuerst vier virtuelle Maschinen vor:

Von den vier virtuellen Maschinen sind drei Server und einer ein Client. Offiziell wird empfohlen, dass die Anzahl der Server ungerade ist und idealerweise drei oder mehr beträgt. Hier werden vm00-vm02 als Server und vm03 als Client konfiguriert.
Für einen Server führen Sie folgenden Befehl aus, um einen Server-Agent zu erstellen:
consul agent -server -bind=vm_address -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent_name -uiFür einen Client führen Sie folgenden Befehl aus, um einen Client-Agent zu erstellen:
consul agent -client=0.0.0.0 -bind=vm_address -data-dir=/tmp/consul/ -node=agent_name -uiDie auszuführenden Befehle sind wie folgt:
# 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.138Einige Parametererklärungen:
client:0.0.0.0lässt Anfragen von allen Quellen zu. Wenn nur der client-Parameter ohne server-Parameter angegeben wird, bedeutet das, dass der Agent im Client-Modus läuft.
Nachdem alle Agenten gestartet wurden, bewirkt retry-join automatisch die Ausführung des join-Befehls. Bei Fehlern wird erneut versucht, standardmäßig alle 30 Sekunden:
$ consul join 192.168.48.138Nach erfolgreichem join kennen alle Knoten einander. Da vm00 den Bootstrap-Modus angegeben hat, ist es der Standard-Leader. Wenn kein Bootstrap-Modus angegeben wurde, ist der beim join angegebene Knoten der Standard-Leader. Bevor ein Leader gewählt wurde, kann der Cluster nicht normal arbeiten. Der Zugriff auf die Web-Oberfläche gibt 500 zurück, und einige Befehle funktionieren nicht. Wenn ein Knoten im Cluster den Bootstrap-Modus angegeben hat, sollten keine anderen Knoten im Cluster den Bootstrap-Modus angeben, und andere Knoten sollten auch den Parameter bootstrap-expect nicht verwenden. Wenn er verwendet wird, wird er automatisch deaktiviert.
Führen Sie nun auf dem Leader-Knoten (tatsächlich kann jeder Knoten dies anzeigen) folgenden Befehl aus, um die Mitgliederinformationen des Rechenzentrums anzuzeigen:
$ 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: Knotenname
- Address: Kommunikationsadresse
- Status:
alivebedeutet aktiv,leftbedeutet offline - Type: Agent-Typ, Server und Client sind zwei Modi
- Build: Die vom Knoten verwendete Consul-Version. Consul kann innerhalb eines bestimmten Bereichs Knoten mit unterschiedlichen Versionen unterstützen.
- Protocol: Die verwendete Raft-Protokollversion. Dieses Protokoll sollte bei allen Knoten identisch sein.
- DC: Data Center, Rechenzentrum. Alle Knoten in der Ausgabe gehören zum Rechenzentrum dc1.
- Partition: Die Partition, zu der der Knoten gehört. Eine Enterprise-Funktion. Jeder Knoten kann nur mit Knoteln derselben Partition kommunizieren.
- Segment: Das Netzwerksegment, zu dem der Knoten gehört. Eine Enterprise-Funktion.

Ebenso sollte ein Knoten beim Verlassen consul leave verwenden, um ordnungsgemäß zu gehen und andere Knoten über das bevorstehende Verlassen zu informieren. Bei Multi-Knoten-Setups ist das ordnungsgemäße Verlassen besonders wichtig, da es die Datenkonsistenz betrifft.
TIP
Für die Demonstration wurden alle Firewalls auf den virtuellen Maschinen deaktiviert. In Produktionsumgebungen sollten diese aus Sicherheitsgründen aktiviert werden. Beachten Sie dazu alle von Consul verwendeten Ports: Required Ports | Consul | HashiCorp Developer.
Testen wir kurz die Datenkonsistenz. Fügen Sie auf der vm00 virtuellen Maschine folgende Daten hinzu:
$ consul kv put sys_confg {"name":"consul"}
Success! Data written to: sys_confgNach dem Speichern können Sie über die HTTP-API auf andere Knoten zugreifen und feststellen, dass die Daten ebenfalls vorhanden sind (der Wert ist base64-kodiert):
$ 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}]Tatsächlich werden die von Consul bereitgestellten Service Discovery- und Registrierungsfunktionen über das Gossip-Protokoll an andere Knoten übertragen. Wenn ein beliebiger Knoten dem aktuellen Rechenzentrum beitritt, werden alle Knoten diese Änderung bemerken.
Beispiel für die Einrichtung mehrerer Rechenzentren
Bereiten Sie fünf virtuelle Maschinen vor. vm00-vm02 sind der Cluster aus dem vorherigen Beispiel und gehören zum Rechenzentrum dc1. vm03-vm04 gehören zum Rechenzentrum dc2. Beim Start eines Agenten ist das Rechenzentrum standardmäßig dc1.

TIP
Für diese Demonstration werden nur Server eingerichtet, Clients werden weggelassen.
Starten Sie zuerst vm03 als Standard-Leader:
$ consul agent -server -datacenter=dc2 -bind=192.168.48.141 -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent04 -ui -bootstrapStarten Sie dann vm04, um automatisch dem vm03-Knoten beizutreten:
$ 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.141Zeigen Sie nun die Mitglieder auf vm00 und vm03 an:
# 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>Sie können sehen, dass das DC-Feld unterschiedlich ist. Da dies eine Demonstration mit virtuellen Maschinen ist, befinden sich alle im selben Netzwerksegment. In der Realität könnten zwei Rechenzentren Server-Cluster an verschiedenen Standorten sein. Lassen Sie nun einen beliebigen Knoten von dc1 einem beliebigen Knoten von dc2 beitreten. Hier lässt vm01 vm03 beitreten:
$ consul join -wan 192.168.48.141
Successfully joined cluster by contacting 1 nodes.Nach erfolgreichem Join zeigen Sie die WAN-Mitglieder an:
$ 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
dc1Sobald ein beliebiger Knoten von dc1 einem beliebigen Knoten von dc2 beigetreten ist, werden alle Knoten beider Rechenzentren diese Änderung bemerken. Beim Anzeigen der Mitglieder können Sie auch die Knoten beider Rechenzentren sehen.
Versuchen Sie nun, KV-Daten auf dem vm00-Knoten hinzuzufügen:
$ consul kv put name consul
Success! Data written to: nameVersuchen Sie, die Daten auf dem vm01-Knoten zu lesen. Sie können sehen, dass die Daten innerhalb desselben Rechenzentrums synchronisiert sind:
$ consul kv get name
consulVersuchen Sie dann, die Daten auf vm03 in einem anderen Rechenzentrum zu lesen. Sie werden feststellen, dass Daten zwischen verschiedenen Rechenzentren nicht synchronisiert werden:
$ consul kv get name
Error! No key exists at: nameWenn Sie eine Synchronisation zwischen mehreren Rechenzentren wünschen, informieren Sie sich unter hashicorp/consul-replicate: Consul cross-DC KV replication daemon.
Service-Registrierung und -Discovery

Es gibt zwei Möglichkeiten zur Service-Registrierung in Consul: Registrierung über Konfigurationsdateien und Registrierung über die API. Für einfachere Tests bereiten wir hier einen Hello-World-Dienst vor (das Beispiel aus dem gRPC-Artikel) und stellen ihn zweimal an verschiedenen Standorten bereit. Informationen zur Registrierung über Konfigurationsdateien finden Sie unter Register external services with Consul service discovery | Consul | HashiCorp Developer. Hier wird nur die Registrierung über die HTTP-API beschrieben.
TIP
Für lokale Dienste (die sich auf demselben Host wie der Consul-Client befinden) kann die Agent-Service-Registrierung direkt verwendet werden. Andernfalls sollte die Catalog-Register-Methode verwendet werden.
Consul bietet ein SDK für die HTTP-API. SDKs für andere Sprachen finden Sie unter Libraries and SDKs - HTTP API | Consul | HashiCorp Developer. Hier laden wir die Go-Abhängigkeit herunter:
go get github.com/hashicorp/consul/apiBei Dienststart wird der Service aktiv bei Consul registriert, bei Dienstabschaltung wird er abgemeldet. Hier ist ein Beispiel:
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{
// Muss eindeutig sein
ID: "hello-service1",
Service: "hello-service",
// Zwei Instanzen bereitgestellt, eine auf Port 8080, eine auf Port 8081
Port: 8080,
}
)
// Service registrieren
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)
}
// Service abmelden
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()
// Port überwachen
listen, err := net.Listen("tcp", ":8080")
if err != nil {
panic(err)
}
// gRPC-Server erstellen
server := grpc.NewServer(
grpc.Creds(insecure.NewCredentials()),
)
// Service registrieren
pb.RegisterSayHelloServer(server, &HelloRpc{})
log.Println("server running...")
// Ausführen
err = server.Serve(listen)
if err != nil {
panic(err)
}
}Der Client-Code verwendet einen benutzerdefinierten Consul-Resolver, um den entsprechenden Dienst beim Registrierungszentrum abzufragen und in die echte Adresse aufzulösen.
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-Strategie
ServiceConfig: c.cc.ParseServiceConfig(
`{"loadBalancingPolicy":"round_robin"}`),
})
}
func (c ConsulResolver) ResolveNow(options resolver.ResolveNowOptions) {
c.resolve()
}
func (c ConsulResolver) Close() {
}Der Client registriert den Resolver beim Start:
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 registrieren
resolver.Register(
// Benutzerdefinierten Consul-Resolver registrieren
myresolver.NewConsulResolverBuilder("192.168.48.138:8500"),
)
}
func main() {
// Verbindung herstellen, ohne Verschlüsselungsverifizierung
conn, err := grpc.Dial("consul:hello-service",
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
panic(err)
}
defer conn.Close()
// Client erstellen
client := hello2.NewSayHelloClient(conn)
for range time.Tick(time.Second) {
// Entfernter Aufruf
helloRep, err := client.Hello(context.Background(), &hello2.HelloReq{Name: "client"})
if err != nil {
panic(err)
}
log.Printf("received grpc resp: %+v", helloRep.String())
}
}Starten Sie zuerst den Server, dann den Client. Es gibt zwei Server, die denselben Dienst bereitstellen, aber unterschiedliche Adressen haben. Die Lastverteilungsstrategie des Clients ist Round-Robin. An den Zeitintervallen in den Server-Logs kann man erkennen, dass die Strategie wirksam ist.
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"Dies ist ein einfaches Beispiel für die Implementierung von Service-Registrierung und -Discovery mit Consul und gRPC.
