Consul

consul là một giải pháp cho phép các nhóm quản lý kết nối mạng một cách an toàn giữa các dịch vụ và trên các môi trường đa đám mây, nó cung cấp các chức năng như khám phá dịch vụ, lưới dịch vụ, quản trị lưu lượng, cập nhật tự động cơ sở hạ tầng mạng và nhiều tính năng khác.
Tài liệu chính thức: Consul by HashiCorp
Mã nguồn mở: hashicorp/consul
Consul là một công cụ khám phá và đăng ký dịch vụ mã nguồn mở do công ty HashiCorp phát triển, sử dụng thuật toán bầu cử Raft, công cụ này được phát triển bằng ngôn ngữ Go nên việc triển khai rất linh hoạt. Consul có các đặc điểm sau:
- Khám phá dịch vụ
- Đăng ký dịch vụ
- Kiểm tra sức khỏe
- Lưu trữ khóa-giá trị
- Đa trung tâm dữ liệu
Thực tế consul có thể làm nhiều việc hơn là khám phá dịch vụ, nó còn có thể làm trung tâm cấu hình phân tán, có nhiều công cụ mã nguồn mở cùng loại khác như zookeeper, nacos, ở đây sẽ không giới thiệu thêm.
Cài đặt
Đối với Ubuntu, thực hiện lệnh dưới đây để cài đặt bằng apt
$ 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 consulHoặc cũng có thể tải xuống từ trang web chính thức Install Consul gói cài đặt tương ứng, vì consul được phát triển bằng go, bản thân gói cài đặt chỉ là một tệp thực thi nhị phân duy nhất, việc cài đặt cũng khá thuận tiện, sau khi cài đặt thành công, thực hiện lệnh sau để xem phiên bản.
$ consul versionĐầu ra bình thường sẽ không có vấn đề gì
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)Bắt đầu nhanh
Phần dưới đây giới thiệu cách nhanh chóng thiết lập một nút đơn consul, thông thường nút đơn được sử dụng để kiểm tra trong quá trình phát triển, nếu nút đơn hoạt động tốt thì hầu như cụm nhiều nút cũng sẽ không có vấn đề. Việc thiết lập nút đơn rất đơn giản, chỉ cần một dòng lệnh
$ consul agent -dev -bind=192.168.48.141 -data-dir=/tmp/consul -ui -node=dev01Thông thường sẽ có đầu ra như sau
==> 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}]"Giải thích ý nghĩa một cách đơn giản
agentlà lệnh con, là lệnh cốt lõi của consul,consul agentlà chạy một proxy consul mới, mỗi node đều là một proxy.dev, là chế độ chạy của agent, tổng cộng có ba loạidev,client,serverbind, địa chỉ giao tiếp mạng LAN, cổng mặc định là 8301, thông thường giá trị này là địa chỉ nội bộ của máy chủadvertise, địa chỉ giao tiếp mạng WAN, cổng mặc định là 8302, thông thường giá trị này là địa chỉ bên ngoài của máy chủdata-dir, thư mục lưu trữ dữ liệuconfig-dir, thư mục lưu trữ cấu hình, consul sẽ đọc tất cả các tệp json trong thư mụcbootstrap, đánh dấu server hiện tại vào chế độ bootstrap, sẽ tự bỏ phiếu cho mình trong quá trình bầu cử raft, trong cụm không được có quá một server ở chế độ nàybootstrap-expect, số lượng server mong đợi trong cụm, trước khi đạt đến số lượng chỉ định, cụm sẽ không bắt đầu bầu cử, không thể sử dụng cùng lúc vớibootstrap.retry-join, sau khi agent khởi động, sẽ liên tục cố gắng gia nhập các nút được chỉ định, cũng hỗ trợ các phương pháp khám phá dịch vụ của các nhà cung cấp saualiyun aws azure digitalocean gce hcp k8s linode mdns os packet scaleway softlayer tencentcloud triton vsphereui, chạy giao diện Webnode, tên nút thực thi, phải duy trì duy nhất trong cụm.
TIP
Về thêm các tham số agent, hãy đến Agents - CLI Reference | Consul | HashiCorp Developer , lưu ý rằng một số tham số chỉ có sẵn trong phiên bản doanh nghiệp.
Sau khi chạy thành công, truy cập 127.0.0.1:8500 để xem giao diện Web.

Biểu tượng dev01 là một ngôi sao, cho thấy nó là nút leader.
Khi thoát, để các nút khác có thể nhận biết được việc nút hiện tại thoát, không nên buộc kill tiến trình, có thể sử dụng lệnh
consul leavehoặc
consul force-leaveCũng có thể dùng ctrl+c để consul agent thoát một cách lịch sự.
Khái niệm
Đây là sơ đồ cụm consul, được chia thành hai phần, mặt phẳng điều khiển và mặt phẳng dữ liệu. consul chỉ chịu trách nhiệm mặt phẳng điều khiển, được chia thành cụm dịch vụ và máy khách, trong cụm dịch vụ lại được chia thành follower và leader, nhìn chung, cụm consul trong hình đã cấu thành một trung tâm dữ liệu. Dưới đây là giải thích một số thuật ngữ
- Agent (Đại lý): hoặc gọi là nút sẽ phù hợp hơn, mỗi agent đều là một tiến trình daemon chạy lâu dài, chúng cung cấp giao diện HTTP và DNS bên ngoài, chịu trách nhiệm kiểm tra sức khỏe và đồng bộ hóa dịch vụ.
- Server (Đại lý dịch vụ): Là một consul server, nhiệm vụ chính của nó bao gồm tham gia bầu cử Raft, duy trì trạng thái cụm, phản hồi truy vấn, trao đổi dữ liệu với các trung tâm dữ liệu khác, và chuyển tiếp truy vấn đến leader và các trung tâm dữ liệu khác.
- Client (Đại lý khách hàng): client tương đối so với server là không trạng thái, nó không tham gia bầu cử Raft, việc nó làm chỉ là chuyển tiếp tất cả các yêu cầu đến server, việc duy nhất nó tham gia liên quan đến nền tảng là chuyển tiếp tin đồn mạng LAN (LAN gossip pool).
- Leader (Lãnh đạo): leader là lãnh đạo của tất cả server, và chỉ có thể có một lãnh đạo, leader được bầu thông qua thuật toán bầu cử Raft, mỗi leader có nhiệm kỳ của mình, trong nhiệm kỳ, bất kể server khác nhận được yêu cầu gì đều phải báo cho leader, vì vậy dữ liệu của leader là cập nhật và mới nhất.
- Gossip (Tin đồn): Consul được xây dựng dựa trên Serf (một sản phẩm khác của công ty này), nó sử dụng giao thức gossip, giao thức này chuyên dùng cho giao tiếp ngẫu nhiên giữa các nút, tương tự như UDP, consul sử dụng giao thức này để thông báo lẫn nhau trong cụm dịch vụ.
- Data Center (Trung tâm dữ liệu): Một cụm consul trong một mạng LAN được gọi là một trung tâm dữ liệu, consul hỗ trợ đa trung tâm dữ liệu, cách thức giao tiếp giữa các trung tâm dữ liệu là WAN gossip.
TIP
Biết thêm từ vựng và thuật ngữ có thể đến Glossary | Consul | HashiCorp Developer để tìm hiểu.
Trong cụm consul, số lượng server nên được kiểm soát chặt chẽ, vì chúng trực tiếp tham gia vào LAN gossip và WAN gossip, bầu cử raft, và phải lưu trữ dữ liệu, càng nhiều server thì chi phí giao tiếp càng cao. Còn số lượng client nhiều một chút cũng không sao, nó chỉ chịu trách nhiệm chuyển tiếp, không tham gia bầu cử, chiếm rất ít tài nguyên, trong cụm ở hình, các dịch vụ thông qua client đăng ký chính mình vào server, nếu có server bị lỗi thì client sẽ tự tìm server khả dụng khác.
Ví dụ thiết lập cụm
Dưới đây là một ví dụ đơn giản về việc thiết lập cụm consul nhiều nút, trước tiên chuẩn bị bốn máy ảo

Trong bốn máy ảo, ba server và một client, khuyến nghị chính thức là số lượng server nên là số lẻ, và tốt nhất là lớn hơn hoặc bằng ba. Ở đây sẽ dùng vm00-vm02 làm server, vm03 làm client,
Đối với server, chạy lệnh sau để tạo server agent
consul agent -server -bind=vm_address -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent_name -uiĐối với client, chạy lệnh sau để tạo client agent
consul agent -client=0.0.0.0 -bind=vm_address -data-dir=/tmp/consul/ -node=agent_name -uiCác lệnh thực thi lần lượt như sau
# 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.138Giải thích một số tham số
client,0.0.0.0tức là cho phép tất cả các yêu cầu từ mọi nguồn, nếu chỉ có tham số client mà không có tham số server, đại diện cho việc agent sẽ chạy ở chế độ client.
Sau khi tất cả agent chạy tốt, tác dụng của retry-join tương đương với việc tự động thực hiện lệnh join, sau khi thất bại sẽ liên tục cố gắng, thời gian重试 mặc định là 30s
$ consul join 192.168.48.138Sau khi join hoàn tất, các nút đều biết sự tồn tại của nhau, vì vm00 đã chỉ định chế độ bootstrap nên nó là leader mặc định, nếu không chỉ định chế độ bootstrap thì nút được chỉ định khi join của tất cả các nút là leader mặc định, trước khi leader được bầu ra, cụm không thể hoạt động bình thường, truy cập giao diện web sẽ trả về 500, một số lệnh cũng không hoạt động bình thường. Nếu trong cụm có nút chỉ định chế độ bootstrap, thì các nút khác trong cụm không nên có nút nào khác chỉ định chế độ bootstrap, đồng thời các nút khác cũng không nên sử dụng tham số bootstrap-expect, nếu sử dụng sẽ tự động bị vô hiệu hóa.
Lúc này trên nút leader (thực tế lúc này bất kỳ nút nào cũng có thể xem) chạy lệnh xem thông tin thành viên của data center, chạy lệnh sau
$ 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, tức là tên nút
- Address, địa chỉ giao tiếp
- Status,
alivebiểu thị đang hoạt động,leftbiểu thị đã offline - Type, loại agent, hai chế độ server và client
- Build, phiên bản consul mà nút này sử dụng, consul có thể hoạt động tương thích với các nút có phiên bản khác nhau trong một phạm vi nhất định
- Protocol, đề cập đến phiên bản giao thức Raft được sử dụng, giao thức này nên thống nhất trên tất cả các nút
- DC, Data Center, trung tâm dữ liệu, tất cả các nút trong đầu ra đều thuộc trung tâm dữ liệu dc1
- Partition, phân vùng mà nút thuộc về, là chức năng phiên bản doanh nghiệp, mỗi nút chỉ có thể giao tiếp với các nút trong cùng phân vùng
- Segment, phân đoạn mạng mà nút thuộc về, là chức năng phiên bản doanh nghiệp

Tương tự, nếu muốn một nút thoát, nên sử dụng consul leave để nút thoát một cách lịch sự và thông báo cho các nút khác rằng mình sẽ thoát, trong trường hợp nhiều nút, việc thoát lịch sự của nút đặc biệt quan trọng, vì điều này liên quan đến tính nhất quán của dữ liệu.
TIP
Máy ảo trong quá trình demo đã tắt tất cả các tường lửa, trong môi trường sản xuất thực tế để đảm bảo an toàn nên bật, vì vậy nên quan tâm đến tất cả các cổng mà consul sử dụng: Required Ports | Consul | HashiCorp Developer.
Tiếp theo kiểm tra đơn giản tính nhất quán của dữ liệu, thêm dữ liệu sau vào máy ảo vm00
$ consul kv put sys_confg {"name":"consul"}
Success! Data written to: sys_confgSau khi lưu, truy cập các nút khác thông qua HTTP API sẽ thấy dữ liệu cũng tồn tại (trong đó value được mã hóa base64)
$ 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}]Trên thực tế, chức năng khám phá và đăng ký dịch vụ mà consul cung cấp được phát sóng đến các nút khác thông qua giao thức gossip, và khi bất kỳ nút nào gia nhập trung tâm dữ liệu hiện tại, tất cả các nút sẽ nhận biết được thay đổi này.
Ví dụ thiết lập đa trung tâm dữ liệu
Chuẩn bị năm máy ảo, vm00-vm02 là cụm của ví dụ trước, thuộc trung tâm dữ liệu dc1, không động đến nó, vm03-vm04 thuộc trung tâm dữ liệu dc2, trung tâm dữ liệu mặc định là dc1 khi agent khởi động.

TIP
Ở đây để demo, chỉ thiết lập server, bỏ qua client.
Trước tiên khởi động vm03, coi nó là leader mặc định
$ consul agent -server -datacenter=dc2 -bind=192.168.48.141 -client=0.0.0.0 -data-dir=/tmp/consul/ -node=agent04 -ui -bootstrapKhởi động vm04, để nó tự động join vào nút vm03
$ 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.141Lúc này lần lượt xem members trên vm00 và vm03
# 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>Có thể thấy trường DC khác nhau, vì đây là demo máy ảo nên đều ở cùng một mạng, trong thực tế hai trung tâm dữ liệu có thể là cụm máy chủ ở các địa điểm khác nhau. Tiếp theo để một nút bất kỳ của dc1 join vào một nút bất kỳ của dc2, ở đây để vm01 join vm03
$ consul join -wan 192.168.48.141
Successfully joined cluster by contacting 1 nodes.Sau khi join thành công, thực hiện lệnh xem members của mạng WAN
$ 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
dc1Chỉ cần một nút bất kỳ của dc1 join vào một nút bất kỳ của dc2, tất cả các nút của hai trung tâm dữ liệu sẽ nhận biết được thay đổi này, khi xem members cũng có thể thấy các nút của hai trung tâm dữ liệu.
Tiếp theo thử thêm một dữ liệu KV trên nút vm00
$ consul kv put name consul
Success! Data written to: nameThử đọc dữ liệu trên nút vm01, có thể thấy dữ liệu trong cùng trung tâm dữ liệu được đồng bộ
$ consul kv get name
consulSau đó thử đọc dữ liệu trên vm03 ở trung tâm dữ liệu khác nhau, sẽ thấy dữ liệu giữa các trung tâm dữ liệu khác nhau không được đồng bộ.
$ consul kv get name
Error! No key exists at: nameNếu muốn đồng bộ dữ liệu đa trung tâm dữ liệu, có thể tìm hiểu hashicorp/consul-replicate: Consul cross-DC KV replication daemon.
Đăng ký và khám phá dịch vụ

Có hai cách đăng ký dịch vụ consul, đăng ký qua tệp cấu hình và đăng ký qua API. Để thuận tiện cho việc kiểm tra, ở đây chuẩn bị trước một dịch vụ Hello World (ví dụ trong bài gRPC), triển khai hai bản, mỗi bản ở vị trí khác nhau. Có thể đến Register external services with Consul service discovery | Consul | HashiCorp Developer để tìm hiểu cách đăng ký qua tệp cấu hình, ở đây chỉ giới thiệu cách đăng ký qua HTTP API.
TIP
Đối với dịch vụ cục bộ (cùng với consul client), có thể trực tiếp sử dụng đăng ký dịch vụ agent, nếu không thì nên sử dụng catalog register để đăng ký.
consul cung cấp SDK HTTP API, SDK của các ngôn ngữ khác có thể đến Libraries and SDKs - HTTP API | Consul | HashiCorp Developer để tìm hiểu. Ở đây tải xuống phụ thuộc của go
go get github.com/hashicorp/consul/apiChủ động đăng ký dịch vụ với consul khi dịch vụ khởi động, hủy đăng ký dịch vụ với consul khi dịch vụ đóng, dưới đây là một ví dụ.
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{
// Phải duy trì duy nhất
ID: "hello-service1",
Service: "hello-service",
// Triển khai hai bản, một bản cổng là 8080, một bản cổng là 8081
Port: 8080,
}
)
// Đăng ký dịch vụ
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)
}
// Hủy đăng ký dịch vụ
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()
// Lắng nghe cổng
listen, err := net.Listen("tcp", ":8080")
if err != nil {
panic(err)
}
// Tạo máy chủ gprc
server := grpc.NewServer(
grpc.Creds(insecure.NewCredentials()),
)
// Đăng ký dịch vụ
pb.RegisterSayHelloServer(server, &HelloRpc{})
log.Println("server running...")
// Chạy
err = server.Serve(listen)
if err != nil {
panic(err)
}
}Mã client sử dụng bộ phân tích cú pháp tùy chỉnh của consul để truy vấn dịch vụ tương ứng từ trung tâm đăng ký và phân giải thành địa chỉ thực tế.
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,
// Chiến lược luân phiên
ServiceConfig: c.cc.ParseServiceConfig(
`{"loadBalancingPolicy":"round_robin"}`),
})
}
func (c ConsulResolver) ResolveNow(options resolver.ResolveNowOptions) {
c.resolve()
}
func (c ConsulResolver) Close() {
}Client đăng ký bộ phân tích cú pháp khi khởi động
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() {
// Đăng ký builder
resolver.Register(
// Đăng ký bộ phân tích cú pháp consul tùy chỉnh
myresolver.NewConsulResolverBuilder("192.168.48.138:8500"),
)
}
func main() {
// Thiết lập kết nối, không có xác minh mã hóa
conn, err := grpc.Dial("consul:hello-service",
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
panic(err)
}
defer conn.Close()
// Tạo client
client := hello2.NewSayHelloClient(conn)
for range time.Tick(time.Second) {
// Gọi từ xa
helloRep, err := client.Hello(context.Background(), &hello2.HelloReq{Name: "client"})
if err != nil {
panic(err)
}
log.Printf("received grpc resp: %+v", helloRep.String())
}
}Trước tiên khởi động máy chủ, sau đó khởi động client, máy chủ có hai bản, cung cấp cùng một dịch vụ, chỉ khác địa chỉ, chiến lược cân bằng tải của client là luân phiên, có thể thấy từ khoảng cách thời gian nhật ký máy chủ rằng chiến lược đã có hiệu lực.
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"Trên đây là một ví dụ đơn giản về việc sử dụng consul kết hợp với gRPC để thực hiện đăng ký và khám phá dịch vụ.
