当前位置:网站首页>go-micro教程 — 第二章 go-micro v3 使用Gin、Etcd
go-micro教程 — 第二章 go-micro v3 使用Gin、Etcd
2022-07-04 15:03:00 【西木Qi】
go-micro教程 — 第二章 go-micro v3 使用Gin、Etcd
前言
注意
:本文使用的Go版本为 go1.17.6
使用 1.18.x
版本或其他版本在操作时总是碰到各种问题,比如依赖下载异常。当然也可能是我电脑的问题。
参考文档:go 微服务之go-micro v3+gin
一、启动Etcd集群
在使用Etcd作为注册中心前需要先有Etcd节点或者Etcd集群,Etcd集群的安装配置及启动,详见:Etcd教程 — 第四章 Etcd集群安全配置。
二、创建项目并安装相关依赖
注意
:2.3到 2.6 步骤执行完同时会在 ${GOPATH}\bin
下生成exe文件。
2.1 创建项目
本文创建的项目名称为 micro-demo
2.2 初始化项目
go mod init micro-demo
2.3 安装 proto
2.4 安装 protoc-gen-go
go get github.com/golang/protobuf/protoc-gen-go
2.5 安装 protoc-gen-micro
注意
:是安装 asim
下的而不是micro
下的,因为micro
下的始终下载不了,这个也是go micro 3.0 框架。
go get github.com/asim/go-micro/cmd/protoc-gen-micro/v3
2.6 安装micro v3 构建工具
- 需要用到Micro 3.0 的micro工具,主要是用于快速构建micro项目,但是不使用这个的配置,用下面2的
go install github.com/micro/micro/[email protected]
- 下载go micro 3.0 库,下面库没有上面micro构建工具
go get github.com/asim/go-micro/v3
2.7 安装gin
go get -u github.com/gin-gonic/gin
三、开发项目
3.1 创建web
模块
在 micro-demo
下创建web
文件夹
3.2 进入web
文件夹
创建main.go
文件
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
const addr = ":8080"
func Index(c *gin.Context) {
c.JSON(http.StatusOK, map[string]interface{}{
"message": "index访问成功",
})
}
func main() {
r := gin.Default()
r.Handle("GET", "/", Index)
if err := r.Run(addr); err != nil {
fmt.Println("err")
}
}
然后执行 go run .
或者在Goland中执行main函数,启动web服务。
启动成功后,在浏览器访问 http://127.0.0.1, 得到如下响应:
// 20220704103107
// http://localhost:8080/
{
"message": "index访问成功"
}
3.3 创建services模块
在 micro-demo
下执行micro new services
命令,创建后端服务模块。
3.4 删除go.mod文件
删除services
模块下的go.mod
文件,统一使用micro-demo
下的go.mod
。
3.5 根据proto生成pb文件
3.5.1 修改 services.proto
主要是修改go_package
指定生成pb文件的路经,这里是将 ./改为 ../
即可。
syntax = "proto3";
package services;
//option go_package = "./proto;services";
//将 ./改为 ../
option go_package = "../proto;services";
service Services {
rpc Call(Request) returns (Response) {}
rpc Stream(StreamingRequest) returns (stream StreamingResponse) {}
rpc PingPong(stream Ping) returns (stream Pong) {}
}
message Message {
string say = 1;
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}
message StreamingRequest {
int64 count = 1;
}
message StreamingResponse {
int64 count = 1;
}
message Ping {
int64 stroke = 1;
}
message Pong {
int64 stroke = 1;
}
3.5.2 生成pb文件
进入到 micro-demo\services\proto>
。执行生成命令:
protoc --proto_path=. --micro_out=. --go_out=. *.proto
执行完后可以在micro-demo\services\proto>
看到生成的services.pb.go
和services.pb.micro.go
文件。
3.6 修改handler/services.go文件
修改 micro-demo\services\handler>
下的 services.go
主要是修改引入的 pb文件位置。
import (
"context"
log "github.com/micro/micro/v3/service/logger"
//services "services/proto"
services "micro-demo/services/proto"
)
3.7 修改services/main.go文件
package main
import (
//修改 1
//"services/handler"
"micro-demo/services/handler"
//pb "services/proto"
pb "micro-demo/services/proto"
//修改 2
//"github.com/micro/micro/v3/service"
//"github.com/micro/micro/v3/service/logger"
service "github.com/asim/go-micro/v3"
"github.com/asim/go-micro/v3/logger"
)
func main() {
// Create service
//修改 3
srv := service.NewService( // service.New
service.Name("services01"),
service.Version("latest"),
)
// Register handler
//修改 4
_ = pb.RegisterServicesHandler(srv.Server(), new(handler.Services))
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}
然后执行 go run .
或者在Goland中执行main函数,启动名为services01
的服务。
启动成功后,控制台显示内容:
API server listening at: 127.0.0.1:51514
2022-07-04 11:26:04 [email protected]/service.go:206 level=info Starting [service] services01
2022-07-04 11:26:04 file=server/rpc_server.go:820 level=info Transport [http] Listening on [::]:51521
2022-07-04 11:26:04 file=server/rpc_server.go:840 level=info Broker [http] Connected to 127.0.0.1:51522
2022-07-04 11:26:04 file=server/rpc_server.go:654 level=info Registry [mdns] Registering node: services01-ea97f1e6-f4b4-4431-8087-d41e430979ef
3.8 通过web模块调用services模块的服务
3.8.1 创建web/handler/services01Handler.go
文件
package handler
import (
"github.com/asim/go-micro/v3"
"github.com/gin-gonic/gin"
servicepb "micro-demo/services/proto"
"net/http"
)
func Index(c *gin.Context) {
c.JSON(http.StatusOK, map[string]interface{}{
"message": "index",
})
}
func ServiceOne(c *gin.Context) {
service := micro.NewService()
service.Init()
// 创建微服务客户端
client := servicepb.NewServicesService("services01", service.Client())
// 调用服务
rsp, err := client.Call(c, &servicepb.Request{
Name: c.Query("key"),
})
if err != nil {
c.JSON(200, gin.H{"code": 500, "msg": err.Error()})
return
}
c.JSON(200, gin.H{"code": 200, "msg": rsp.Msg})
}
3.8.2 修改web/main.go文件
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"micro-demo/web/handler"
"net/http"
)
const addr = ":8080"
func Index(c *gin.Context) {
c.JSON(http.StatusOK, map[string]interface{}{
"message": "index访问成功",
})
}
func main() {
r := gin.Default()
r.Handle("GET", "/", Index)
r.Handle("GET", "/service-req", handler.ServiceOne)
if err := r.Run(addr); err != nil {
fmt.Println("err")
}
}
然后执行 go run .
或者在Goland中执行main函数,重新启动web服务。
启动结果:
[GIN-debug] GET / --> main.Index (3 handlers)
[GIN-debug] GET /service-req --> micro-demo/web/handler.ServiceOne (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8080
浏览器访问http://127.0.0.1:8080/service-req?key=哈哈
,得到如下响应:
// 20220704113801
// http://127.0.0.1:8080/service-req?key=%E5%93%88%E5%93%88
{
"code": 200,
"msg": "Hello 哈哈"
}
※四、使用consul作为注册中心注册服务
注意
:使用consul作为注册中心注册服务这块尚未实践,可能会有问题。
4.1 安装配置consul
首选需要安装配置consul服务,独立安装,或者使用docker安装均可。
启动consul后,使用浏览器访问http://192.168.1.224:8500
4.2 项目加入consul包
go get -u github.com/asim/go-micro/plugins/registry/consul/v3
4.3 修改services/main.go
主要修改或加入的地方 consul 1
、consul 2
、consul 3
package main
import (
"micro-demo/services/handler"
pb "micro-demo/services/proto"
service "github.com/asim/go-micro/v3"
"github.com/asim/go-micro/v3/logger"
//consul 1
"github.com/asim/go-micro/plugins/registry/consul/v3"
"github.com/asim/go-micro/v3/registry"
)
//consul 2
const (
ServerName = "services01"
ConsulAddr = "192.168.1.224:8500"
)
func main() {
// consul 3
consulReg := consul.NewRegistry(
registry.Addrs(ConsulAddr),
)
srv := service.NewService(
service.Name(ServerName), // 服务名字
service.Registry(consulReg),// 注册中心
)
// Register handler
_ = pb.RegisterServicesHandler(srv.Server(), new(handler.Services))
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}
执行go run .,重新启动services模块的名为services01的服务。
4.4 修改web/handler/services01Handler.go
主要修改或加入的地方 consul 1
、consul 2
package handler
import (
"github.com/asim/go-micro/v3"
"github.com/gin-gonic/gin"
servicepb "micro-demo/services/proto"
"net/http"
//consul 1
"github.com/asim/go-micro/plugins/registry/consul/v3"
"github.com/asim/go-micro/v3/registry
)
func Index(c *gin.Context) {
c.JSON(http.StatusOK, map[string]interface{}{
"message": "index",
})
}
func ServiceOne(c *gin.Context) {
//consul 2
consulReg := consul.NewRegistry(
registry.Addrs("192.168.1.224:8500"),
)
service := micro.NewService(
micro.Registry(consulReg), //设置注册中心
)
service.Init()
// 创建微服务客户端
client := servicepb.NewServicesService("services01", service.Client())
// 调用服务
rsp, err := client.Call(c, &servicepb.Request{
Name: c.Query("key"),
})
if err != nil {
c.JSON(200, gin.H{"code": 500, "msg": err.Error()})
return
}
c.JSON(200, gin.H{"code": 200, "msg": rsp.Msg})
}
执行go run .,重启web。
五、使用etcd作为注册中心
5.1 项目加入etcd包
go get -u "github.com/asim/go-micro/plugins/registry/etcd/v3"
5.2 修改services/main.go
package main
import (
"micro-demo/services/handler"
pb "micro-demo/services/proto"
service "github.com/asim/go-micro/v3"
"github.com/asim/go-micro/v3/logger"
//etcd 1
"github.com/asim/go-micro/plugins/registry/etcd/v3"
"github.com/asim/go-micro/v3/registry"
)
//etcd 2
const (
ServerName = "services01"
EtcdAddr = "192.168.1.221:2379"
)
func main() {
//etcd 3
etcdReg := etcd.NewRegistry(
registry.Addrs(EtcdAddr),
)
srv := service.NewService(
service.Name(ServerName), // 服务名字
service.Registry(etcdReg), // 注册中心
)
// Register handler
_ = pb.RegisterServicesHandler(srv.Server(), new(handler.Services))
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}
5.3 修改web/handler/services01Handler.go
package handler
import (
"github.com/asim/go-micro/v3"
"github.com/gin-gonic/gin"
servicepb "micro-demo/services/proto"
"net/http"
//etcd 1
"github.com/asim/go-micro/plugins/registry/etcd/v3"
"github.com/asim/go-micro/v3/registry"
)
func Index(c *gin.Context) {
c.JSON(http.StatusOK, map[string]interface{}{
"message": "index",
})
}
func ServiceOne(c *gin.Context) {
// etcd 2
etcdReg := etcd.NewRegistry(
registry.Addrs("192.168.1.221:2379"),
)
service := micro.NewService(
micro.Registry(etcdReg), //设置注册中心
)
service.Init()
// 创建微服务客户端
client := servicepb.NewServicesService("services01", service.Client())
// 调用服务
rsp, err := client.Call(c, &servicepb.Request{
Name: c.Query("key"),
})
if err != nil {
c.JSON(200, gin.H{"code": 500, "msg": err.Error()})
return
}
c.JSON(200, gin.H{"code": 200, "msg": rsp.Msg})
}
执行go run .,重启web,然后再发送 http://127.0.0.1:8080/service-req?key=哈哈
,返回结果:
// 20220704132910
// http://127.0.0.1:8080/service-req?key=%E5%93%88%E5%93%88
{
"code": 200,
"msg": "Hello 哈哈"
}
5.4 查看etcd中的服务注册情况
边栏推荐
- Transformer中position encoding实践
- [Previous line repeated 995 more times]RecursionError: maximum recursion depth exceeded
- Final consistency of MESI cache in CPU -- why does CPU need cache
- Accounting regulations and professional ethics [7]
- 从数数开始
- How to implicitly pass values when transferring forms
- Vscode setting outline shortcut keys to improve efficiency
- Visual studio 2019 (localdb) mssqllocaldb SQL Server 2014 database version is 852 and cannot be opened. This server supports 782
- TypeError: list indices must be integers or slices, not str
- China's roof ladder market trend report, technological innovation and market forecast
猜你喜欢
~88 running people practice
~89 deformation translation
MFC implementation of ACM basic questions encoded by the number of characters
Can you really use MySQL explain?
Understand the rate control mode rate control mode CBR, VBR, CRF (x264, x265, VPX)
Software Engineer vs Hardware Engineer
DIY a low-cost multi-functional dot matrix clock!
@EnableAspectAutoJAutoProxy_ Exposeproxy property
What is torch NN?
Understand asp Net core - Authentication Based on jwtbearer
随机推荐
Research Report on market supply and demand and strategy of surgical stapler industry in China
CMPSC311 Linear Device
Go development: how to use go singleton mode to ensure the security of high concurrency of streaming media?
基于check-point实现图数据构建任务
Accounting regulations and professional ethics [8]
Common knowledge of unity Editor Extension
Cut! 39 year old Ali P9, saved 150million
跳跃表实例
[North Asia data recovery] a database data recovery case where the partition where the database is located is unrecognized due to the RAID disk failure of HP DL380 server
Statistical learning: logistic regression and cross entropy loss (pytoch Implementation)
矿产行业商业供应链协同系统解决方案:构建数智化供应链平台,保障矿产资源安全供应
安信证券网上开户安全吗 开户收费吗
Anta is actually a technology company? These operations fool netizens
Research Report on market supply and demand and strategy of China's four sided flat bag industry
Hair growth shampoo industry Research Report - market status analysis and development prospect forecast
std::shared_ ptr initialization: make_ shared< Foo> () vs shared_ ptr< T> (new Foo) [duplicate]
PyTorch深度学习快速入门教程
时钟轮在 RPC 中的应用
Median and order statistics
Object.keys()的用法