什么是go-micro和etcd,本文不在這里敘述,會有例外的文章介紹须教。這里只是一個示列,簡單的了解和運用下服務發(fā)現(xiàn)斩芭。
通過一張圖來了解什么是服務發(fā)現(xiàn)轻腺?服務的基本流程:
1.先把自己的服務注冊到注冊中心
2.客戶端調(diào)用的時候去注冊中心查詢調(diào)用的服務的服務器列表
3.得到服務列表,隨機調(diào)取一臺進行遠程協(xié)程
服務發(fā)現(xiàn)的目的:
傳統(tǒng)單機應用動態(tài)性不強划乖,不會頻繁地更新和重新發(fā)布贬养,也較少地進行自動伸縮。但隨著互聯(lián)網(wǎng)分布式系統(tǒng)的普及琴庵,服務與服務之間的伸縮性和可擴展性的要求也越來越大误算。
為了滿足服務的垂直和水平的擴張,以往一般使用預定義的端口配置服務迷殿,當新的服務需要上線或當期服務需要冗余擴展的時候儿礼,我們需要靜態(tài)化地“注冊”相關(guān) ip 與端口信息到一個地方,再通過程序之間定時“更新”的方法去同步信息庆寺。
下面通過一個示列來學習服務發(fā)現(xiàn):
1.安裝ectd蚊夫,編輯docker-compose.yml
version: '3'
networks:
myetcd_single:
services:
etcd:
image: quay.io/coreos/etcd:v3.3.12
container_name: etcd
ports:
- 23791:2379
- 2380
environment:
ETCDCTL_API: 3
#volumes:
# - ./data/etcd/etcd-data:/etcd-data
networks:
- myetcd_single
command:
- "/usr/local/bin/etcd"
- "--name"
- "s1"
- "--data-dir"
- "/etcd-data"
- "--advertise-client-urls"
- "http://0.0.0.0:2379"
- --listen-client-urls
- "http://0.0.0.0:2379"
- "--initial-advertise-peer-urls"
- "http://0.0.0.0:2380"
- "--listen-peer-urls"
- "http://0.0.0.0:2380"
- "--initial-cluster-token"
- "tkn"
- "--initial-cluster"
- "s1=http://0.0.0.0:2380"
- "--initial-cluster-state"
- "new"
etcdkeeper:
image: deltaprojects/etcdkeeper
container_name: etcdkeeper_single
ports:
- 8088:8080
networks:
- myetcd_single
啟動etcd
docker-compose up -d
2.go-micro示列
proto文件及bp執(zhí)行
// hello.proto
syntax = "proto3";
package hello;
option go_package = "proto/hello";
option java_multiple_files = true;
option java_outer_classname = "HelloWorldProto";
service Hello {
rpc Ping(Request) returns (Response) {}
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}
protoc -I . --go_out=. --micro_out=. hello.proto
服務注冊
package main
import (
micro "github.com/micro/go-micro"
//"github.com/micro/go-micro/web"
proto "mymicro/proto/hello"
//"net/http"
"context"
//"fmt"
"github.com/micro/go-micro/registry"
//"github.com/micro/go-micro/registry/etcd"
"github.com/micro/go-plugins/registry/etcdv3"
)
type Hello struct{}
func (h *Hello) Ping(ctx context.Context, req *proto.Request, res *proto.Response) error {
res.Msg = "Hello " + req.Name
return nil
}
func main() {
reg := etcdv3.NewRegistry(func(op *registry.Options) {
op.Addrs = []string{"192.168.99.101:23791"}
})
service := micro.NewService(
micro.Name("cowkeys.srv.say"),
micro.Registry(reg),
)
service.Init()
proto.RegisterHelloHandler(service.Server(), new(Hello))
if err := service.Run(); err != nil {
panic(err)
}
}
// func main() {
// server := web.NewService(web.Address(":8081")) // 路由
// server.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// w.Write([]byte("hello go micro"))
// })
// _ = server.Run()
// }
服務發(fā)現(xiàn)
package main
import (
"context"
"fmt"
proto "mymicro/proto/hello"
micro "github.com/micro/go-micro"
"github.com/micro/go-micro/registry"
//"github.com/micro/go-micro/registry/etcd"
"github.com/micro/go-plugins/registry/etcdv3"
)
func main() {
reg := etcdv3.NewRegistry(func(op *registry.Options) {
op.Addrs = []string{"192.168.99.101:23791"}
})
service := micro.NewService(
micro.Registry(reg),
)
service.Init()
sayClent := proto.NewHelloService("cowkeys.srv.say", service.Client())
rsp, err := sayClent.Ping(context.Background(), &proto.Request{Name: "World ^_^"})
if err != nil {
panic(err)
}
fmt.Println(rsp)
}
附一張主流注冊中心的對別圖