etcd版本:etcd-v3.3.25
etcd节点:
192.168.0.50:2379
192.168.0.51:2379
192.168.0.52:2379
etcd启动配置文件:
config.yaml
name: consul01
data-dir: /usr/local/etcd-v3.3.25/data
listen-client-urls: http://192.168.0.50:2379,http://127.0.0.1:2379
advertise-client-urls: http://192.168.0.50:2379,http://127.0.0.1:2379
listen-peer-urls: http://192.168.0.50:2380
initial-advertise-peer-urls: http://192.168.0.50:2380
initial-cluster: consul01=http://192.168.0.50:2380,consul02=http://192.168.0.51:2380,consul03=http://192.168.0.52:2380
initial-cluster-token: etcd-cluster-token
initial-cluster-state: new
etcd启动脚本:
service.sh
#!/bin/bash
#cd /usr/local/etcd-v3.3.25;nohup ./etcd --config-file config.yaml &
DIR=/usr/local/etcd-v3.3.25
cd $DIR
echo "================ start etcd server================="
PID=`ps aux |grep etcd |grep "config.yaml" |grep -v grep|awk -F " " '{print $2}'`
if [ $PID > 0 ];then
echo " etcd service is already running!"
exit 0
fi
nohup ./etcd --config-file config.yaml 1>>./start.log 2>&1 &
stat=$?
if [ $stat == 0 ]
then
pid=`ps aux |grep etcd |grep "config.yaml" |grep -v grep|awk -F " " '{print $2}'`
if [ $pid > 0 ]; then
echo "etcd service start success, pid:$pid"
else
echo "etcd service start fail"
fi
exit 0
else
echo "etcd server start failed"
fi
etcdctl 命令:
ETCDCTL_API=3 ./etcdctl --endpoints=http://0:2379,http://1:2379,http://2:2379 endpoint status --write-out=table
etcd 版本为 3.4,可以ETCDCTL_API=3,或ETCDCTL_API=2,默认情况下用的就是v3了,可以不用声明ETCDCTL_API
version: 查看版本
member list: 查看节点状态,learner 情况
endpoint status: 节点状态,leader 情况
endpoint health: 健康状态与耗时
alarm list: 查看警告,如存储满时会切换为只读,产生 alarm
alarm disarm:清除所有警告
set app demo: 写入
get app: 获取
update app demo1:更新
rm app: 删除
mkdir demo 创建文件夹
rmdir dir 删除文件夹
backup 备份
compaction: 压缩
defrag:整理碎片
watch key 监测 key 变化
get / –prefix –keys-only: 查看所有 key
–write-out= tables,可以用表格形式输出更清晰,注意有些输出并不支持tables
目录结构:
tree .
.
├── client
│ └── main.go
├── go.mod
├── go.sum
├── proto
│ └── hello
│ ├── hello.pb.go
│ ├── hello.pb.micro.go
│ └── hello.proto
└── server
└── main.go
go.mod文件信息如下:
module mehelloword
go 1.14
replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
require (
github.com/golang/protobuf v1.4.3
github.com/micro/go-micro v1.18.0
google.golang.org/protobuf v1.25.0
)
服务接口声明
mkdir proto/hello -p && cd proto/hello
hello.proto
syntax = "proto3";
package mehello;
service Lemon{
rpc SayHi(Request) returns (Response) {};
}
message Request{
string name = 1;
string address = 2;
}
message Response {
string ret = 1;
}
如上述代码所示,我们定义了一个名为 Lemon 的服务,该服务中包含一个 SayHi 方法,该方法接收一个 Request 对象,然后返回一个 Response 对象.
通过服务声明生成原型代码
protoc -I. --go_out=. --micro_out=. proto/hello/hello.proto
编写服务实现代码
接下来,我们就可以在项目根目录下创建server/main.go,然后基于上述服务原型代码来编写第一个微服务服务端接口了:
package main
import (
"context"
"fmt"
mehello "mehelloword/proto/hello"
"github.com/micro/go-micro"
)
type LemonService struct {
}
func (l *LemonService) SayHi(ctx context.Context,
in *mehello.Request, rsp *mehello.Response) error {
rsp.Ret = "你好," + in.Name + ", welcome to " + in.Address
return nil
}
func main() {
service := micro.NewService(micro.Name("LemonService"), micro.Address("192.168.0.103:9091"))
service.Init()
err := mehello.RegisterLemonHandler(service.Server(), new(LemonService))
if err != nil {
fmt.Printf("register handler failed,err:%v\n", err)
return
}
if err := service.Run(); err != nil {
panic(err)
}
}
go run main.go --registry=etcd --registry_address 192.168.0.50:2379
2020-12-15 11:46:37.526713 I | Transport [http] Listening on 192.168.0.103:9091
2020-12-15 11:46:37.527120 I | Broker [http] Connected to [::]:57848
2020-12-15 11:46:37.527166 I | Registry [etcd] Registering node: LemonService-60b77ea5-ecc2-412f-8c58-061cc7930b8b


客户端调用
我们来编写一段简单的客户端测试代码,在项目根目录下创建client/main.go 并编写代码如下:
package main
import (
"context"
"fmt"
mehello "mehelloword/proto/hello"
"github.com/micro/go-micro"
)
func main() {
service := micro.NewService(micro.Name("LemonService.Client"))
service.Init()
lemon := mehello.NewLemonService("LemonService", service.Client())
rsp, err := lemon.SayHi(context.Background(), &mehello.Request{Name: "柠檬君", Address: "西安"})
if err != nil {
panic(err)
}
fmt.Printf("ret:%v\n", rsp.Ret)
fmt.Println(rsp)
}
go run main.go --registry=etcd --registry_address 192.168.0.50:2379
ret:你好,柠檬君, welcome to 西安
ret:"你好,柠檬君, welcome to 西安"