当前位置: 首页 > 工具软件 > go-micro > 使用案例 >

go 微服务之go-micro v3+gin

笪波鸿
2023-12-01

安装gin

go get -u github.com/gin-gonic/gin

安装go-micro v3

先安装依赖

go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go

//安装asim/go-micro   这个是go micro 3.0 框架
go get github.com/asim/go-micro/cmd/protoc-gen-micro/v3

安装micro v3

//需要用到Micro 3.0 环境的micro 工具,可以快速构建项目,但是不使用这个库,用下面的
go get github.com/micro/micro/v3

// 下载go micro 3.0 库,下面库没有上面micro 工具
go get github.com/asim/go-micro/v3

搭建项目

1、创建go微服务学习文件夹

# 先创建go.mod文件,用于管理引用的包
module go微服务学习

go 1.15

2、创建webservices文件夹

mkdir go微服务学习
cd go微服务学习
mkdir web services

创建web

  • 进入web文件夹

    • 创建main.go文件

      package main
      
      import (
      	"github.com/gin-gonic/gin"
      	"net/http"
      )
      
      const addr = ":80"
      
      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 .启动web服务

      $ go run .
      [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
      
      [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
       - using env:   export GIN_MODE=release
       - using code:  gin.SetMode(gin.ReleaseMode)
      
      [GIN-debug] GET    /test1                    --> myProject/web/handler.Index (3 handlers)
      

      浏览器访问http://127.0.0.1, 得到如下响应

      // 20220103173321
      // http://127.0.0.1/test1
      
      {
        "message": "index"
      }
      

创建service

  • 进入services文件夹,执行micro new test1命令

    • 移除go.mod文件

    • 生成pb文件, 下面命令可以在Makefile文件中查到

      protoc --proto_path=. --micro_out=. --go_out=:. proto/test1.proto
      
    • 修改handler/test1.go文件

      
      import (
      	"context"
      
      	log "github.com/micro/micro/v3/service/logger"
      	// test1 "test1/proto"
      	test1 "go微服务学习/services/test1/proto"
      )
      
    • 修改main.go文件

      package main
      
      import (
      	"go微服务学习/services/test1/handler"
      	pb "go微服务学习/services/test1/proto"
      
      	service "github.com/asim/go-micro/v3" // "github.com/micro/micro/v3/service"
      	"github.com/asim/go-micro/v3/logger"  // "github.com/micro/micro/v3/service/logger"
      )
      
      func main() {
      	// Create service
      	srv := service.NewService( // service.New
      		service.Name("test1"),
      		service.Version("latest"),
      	)
      
      	// Register handler
      	_ = pb.RegisterTest1Handler(srv.Server(), new(handler.Test1))
      
      	// Run service
      	if err := srv.Run(); err != nil {
      		logger.Fatal(err)
      	}
      }
      
    • 执行go run .启动名为test1的服务

      $ go run .
      2022-01-03 18:03:08  file=v3@v3.7.0/service.go:206 level=info Starting [service] test1
      2022-01-03 18:03:08  file=server/rpc_server.go:820 level=info Transport [http] Listening on [::]:4142
      2022-01-03 18:03:08  file=server/rpc_server.go:840 level=info Broker [http] Connected to 127.0.0.1:4143
      2022-01-03 18:03:08  file=server/rpc_server.go:654 level=info Registry [mdns] Registering node: test1-7f6989d9-e1a9-4353-b81a-707bf3b60ff5 # 使用默认的mdns作为注册中心、
      
      

通过web去调用微服务

  • 添加web/handler/test1Handler.go文件

    package handler
    
    import (
    	"github.com/asim/go-micro/v3"
    	"github.com/gin-gonic/gin"
    	test1 "go微服务学习/services/test1/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 := test1.NewTest1Service("test1", service.Client())
    
    	// 调用服务
    	rsp, err := client.Call(c, &test1.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})
    }
    
    
  • 修改web/main.go文件

    package main
    import (
    	//...
    	"go微服务学习/web/handler"
    )
    //...
    func main() {
    	r := gin.Default()
    	r.Handle("GET", "/test1", handler.ServiceOne)
    	//...
    }
    
    
  • 运行go run .重新启动web服务

    $ go run .
    [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
    
    [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
     - using env:   export GIN_MODE=release
     - using code:  gin.SetMode(gin.ReleaseMode)
    
    [GIN-debug] GET    /test1                    --> go微服务学习/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 :80
    

    浏览器访问http://127.0.0.1/test1?key=ajune,得到如下响应

    // 20220103181848
    // http://127.0.0.1/test1?key=ajune
    
    {
      "code": 200,
      "msg": "Hello ajune"
    }
    

使用consul作为注册中心注册服务

启动一个consul的docker容器

ajune@ubuntu:~$ docker network create consul # 创建一个consul网络
de9c7105e8a03fc5bfa0ac82344969e5b0ee3c9e369c90c3749f11ae57d8f0dc
ajune@ubuntu:~$ docker run --network consul --name consul -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul agent -server -bootstrap-expect 1 -ui -bind=0.0.0.0 -client=0.0.0.0
==> Starting Consul agent...
           Version: '1.11.1'
           Node ID: '4c6a5611-c56a-2468-3dfc-c5a13aa542c0'
         Node name: '602afb2bd163'
        Datacenter: 'dc1' (Segment: '<all>')
            Server: true (Bootstrap: true)
       Client Addr: [0.0.0.0] (HTTP: 8500, HTTPS: -1, gRPC: -1, DNS: 8600)
      Cluster Addr: 172.21.0.2 (LAN: 8301, WAN: 8302)
           Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false

启动后,使用浏览器访问http://192.168.8.100:8500

  • 安装consul包

    go get -u github.com/asim/go-micro/plugins/registry/consul/v3
    
  • 修改services/test1/main.go

    package main
    
    import (
      //...
      "github.com/asim/go-micro/v3/registry"
    "github.com/asim/go-micro/plugins/registry/consul/v3"
      //...
    )
    
    const (
    ServerName = "test1"
    ConsulAddr = "192.168.8.100:8500"
    )
    
    func main() {
      // 新建注册
    consulReg := consul.NewRegistry(
    	registry.Addrs(ConsulAddr),
    )
    
    srv := service.NewService(
    	service.Name(ServerName),	// 服务名字
    	service.Registry(consulReg),// 注册中心
    )
    //...
    }
    
    
  • 执行go run .,重新启动test1服务

    $ go run .
    2022-01-03 18:56:36  file=v3@v3.7.0/service.go:206 level=info Starting [service] test1
    2022-01-03 18:56:36  file=server/rpc_server.go:820 level=info Transport [http] Listening on [::]:8818
    2022-01-03 18:56:36  file=server/rpc_server.go:840 level=info Broker [http] Connected to 127.0.0.1:8819
    2022-01-03 18:56:36  file=server/rpc_server.go:654 level=info Registry [consul] Registering node: test1-1aa7262e-17ac-4b4e-a3a9-0b6035771dd2 # 使用了consul作为注册中心
    2022-01-03 18:59:47  file=handler/test1.go:15 level=info Received Test1.Call request
    2022-01-03 18:59:48  file=handler/test1.go:15 level=info Received Test1.Call request
    
    
  • 修改web/handler/test1Handler.go

    package handler
    
    import (
    	"github.com/asim/go-micro/plugins/registry/consul/v3"
    	"github.com/asim/go-micro/v3/registry"
    	//...
    )
    
    func ServiceOne(c *gin.Context) {
    	//配置注册中心
    	consulReg := consul.NewRegistry(
    		registry.Addrs("192.168.8.100:8500"),
    	)
    
    	service := micro.NewService(
    		micro.Registry(consulReg), //设置注册中心
    	)
    	//...
    }
    
    
  • 执行go run .,重启web

使用etcd作为注册中心

安装etcd

go get -u "github.com/asim/go-micro/plugins/registry/etcd/v3"

使用容器启动etcd服务

ajune@ubuntu:~$ docker network create etcd
ajune@ubuntu:~$ docker run --name etcd --network etcd -p 2379:2379 -p 2380:2380 --env ALLOW_NONE_AUTHENTICATION=yes --env ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379  bitnami/etcd:latest
etcd 11:11:42.58 
etcd 11:11:42.58 Welcome to the Bitnami etcd container
etcd 11:11:42.58 Subscribe to project updates by watching https://github.com/bitnami/bitnami-docker-etcd
etcd 11:11:42.58 Submit issues and feature requests at https://github.com/bitnami/bitnami-docker-etcd/issues
etcd 11:11:42.59 
etcd 11:11:42.59 INFO  ==> ** Starting etcd setup **
etcd 11:11:42.62 INFO  ==> Validating settings in ETCD_* env vars..
etcd 11:11:42.62 WARN  ==> You set the environment variable ALLOW_NONE_AUTHENTICATION=yes. For safety reasons, do not use this flag in a production environment.
etcd 11:11:42.63 INFO  ==> Initializing etcd
etcd 11:11:42.63 INFO  ==> Generating etcd config file using env variables
etcd 11:11:42.65 INFO  ==> There is no data from previous deployments
etcd 11:11:42.66 INFO  ==> Stopping etcd
etcd 11:11:43.67 INFO  ==> ** etcd setup finished! **

etcd 11:11:43.70 INFO  ==> ** Starting etcd **

修改services/test1/main.go

package main

import (
	//...
	"github.com/asim/go-micro/plugins/registry/etcd/v3"
    //...
)

const (
	//...
	EtcdAddr   = "192.168.8.100:2379"
)

func main() {
	// 新建注册
	//consulReg := consul.NewRegistry(
	//	registry.Addrs(ConsulAddr),
	//)
	// 使用etcd作为注册
	etcdReg := etcd.NewRegistry(
		registry.Addrs(EtcdAddr),
	)

	srv := service.NewService(
		service.Name(ServerName),  // 服务名字
		service.Registry(etcdReg), // 注册中心
	)
}

修改web/handler/test1Handler.go

package handler

import (
	"github.com/asim/go-micro/plugins/registry/etcd/v3"
    //...
)
func ServiceOne(c *gin.Context) {
	//配置注册中心
	//consulReg := consul.NewRegistry(
	//	registry.Addrs("192.168.8.100:8500"),
	//)

	// 使用etcd作为注册
	etcdReg := etcd.NewRegistry(
		registry.Addrs("192.168.8.100:2379"),
	)
	service := micro.NewService(
		micro.Registry(etcdReg), //设置注册中心
	)
    //...
}

 类似资料: