├── .github └── workflows │ └── codeql-analysis.yml ├── LICENSE ├── README.md ├── go.mod ├── go.sum ├── p1 └── main.go ├── p10 ├── client │ └── main.go ├── main.go └── prodModels.go ├── p11 ├── client │ └── main.go ├── gen.sh ├── main.go ├── models │ ├── prods.pb.go │ ├── prods.pb.micro.go │ └── protos │ │ └── prods.proto └── prodModels.go ├── p12 ├── client │ └── main.go ├── gen.sh ├── main.go ├── models │ ├── prods.pb.go │ ├── prods.pb.micro.go │ └── protos │ │ └── prods.proto └── prodModels.go ├── p13 ├── gen.sh ├── main.go ├── models │ ├── prodService.pb.go │ ├── prodService.pb.micro.go │ └── protos │ │ └── prodService.proto └── prods │ └── prodService.go ├── p14 ├── client │ └── main.go ├── gen.sh ├── main.go ├── models │ ├── prodService.pb.go │ ├── prodService.pb.micro.go │ └── protos │ │ └── prodService.proto └── prods │ └── prodService.go ├── p15 └── grpc_client │ ├── gen.sh │ ├── handlers │ └── handler.go │ ├── main.go │ ├── middlewares │ └── middleware.go │ ├── models │ ├── prodService.pb.go │ ├── prodService.pb.micro.go │ └── protos │ │ └── prodService.proto │ └── routers │ └── router.go ├── p16 └── grpc_client │ ├── gen.sh │ ├── handlers │ └── handler.go │ ├── main.go │ ├── middlewares │ └── middleware.go │ ├── models │ ├── prodService.pb.go │ ├── prodService.pb.micro.go │ └── protos │ │ └── prodService.proto │ └── routers │ └── router.go ├── p17 ├── gen.sh ├── grpc_client │ ├── handlers │ │ └── handler.go │ ├── main.go │ ├── middlewares │ │ └── middleware.go │ └── routers │ │ └── router.go ├── grpc_server │ ├── main.go │ └── prods │ │ └── prodService.go └── models │ ├── prodService.pb.go │ ├── prodService.pb.micro.go │ └── protos │ └── prodService.proto ├── p18 ├── gen.sh ├── grpc_client │ ├── handlers │ │ └── handler.go │ ├── main.go │ ├── middlewares │ │ └── middleware.go │ └── routers │ │ └── router.go ├── grpc_server │ ├── main.go │ └── prods │ │ └── prodService.go └── models │ ├── prodService.pb.go │ ├── prodService.pb.micro.go │ └── protos │ └── prodService.proto ├── p19 ├── gen.sh ├── grpc_client │ ├── handlers │ │ └── handler.go │ ├── main.go │ ├── middlewares │ │ └── middleware.go │ ├── routers │ │ └── router.go │ └── wrappers │ │ └── prodsWrapper.go ├── grpc_server │ ├── main.go │ └── prods │ │ └── prodService.go └── models │ ├── prodService.pb.go │ ├── prodService.pb.micro.go │ └── protos │ └── prodService.proto ├── p2 └── main.go ├── p20 ├── gen.sh ├── grpc_client │ ├── handlers │ │ └── handler.go │ ├── main.go │ ├── middlewares │ │ └── middleware.go │ ├── routers │ │ └── router.go │ └── wrappers │ │ └── prodsWrapper.go ├── grpc_server │ ├── main.go │ └── prods │ │ └── prodService.go └── models │ ├── prodService.pb.go │ ├── prodService.pb.micro.go │ └── protos │ └── prodService.proto ├── p21 ├── gen.sh ├── grpc_client │ ├── handlers │ │ └── handler.go │ ├── main.go │ ├── middlewares │ │ └── middleware.go │ ├── routers │ │ └── router.go │ └── wrappers │ │ └── prodsWrapper.go ├── grpc_server │ ├── main.go │ └── prods │ │ └── prodService.go └── models │ ├── prodService.pb.go │ ├── prodService.pb.micro.go │ └── protos │ └── prodService.proto ├── p22 ├── gen.sh ├── grpc_client │ ├── handlers │ │ └── handler.go │ ├── main.go │ ├── middlewares │ │ └── middleware.go │ ├── routers │ │ └── router.go │ └── wrappers │ │ └── prodsWrapper.go ├── grpc_server │ ├── main.go │ └── prods │ │ └── prodService.go └── models │ ├── prodService.pb.go │ ├── prodService.pb.micro.go │ └── protos │ └── prodService.proto ├── p23 ├── gen.sh ├── main.go ├── models │ ├── protos │ │ └── test.proto │ ├── test.pb.go │ └── test.pb.micro.go └── test │ └── testService.go ├── p24 └── README.md ├── p25 ├── README.md ├── gen.sh ├── main.go ├── models │ ├── protos │ │ └── test.proto │ ├── test.pb.go │ └── test.pb.micro.go └── test │ └── testService.go ├── p27 ├── controllers │ └── user.go ├── gen.sh ├── main.go └── models │ ├── UserService.pb.go │ ├── UserService.pb.micro.go │ └── protos │ ├── UserService.proto │ └── google │ └── protobuf │ └── timestamp.proto ├── p28 ├── api.sh ├── appInit │ └── init.go ├── controllers │ └── user.go ├── gen.sh ├── main.go └── models │ ├── UserService.pb.go │ ├── UserService.pb.micro.go │ └── protos │ ├── UserService.proto │ └── google │ └── protobuf │ └── timestamp.proto ├── p29 ├── api.sh ├── appInit │ └── init.go ├── controllers │ └── user.go ├── gen.sh ├── main.go ├── models │ ├── UserService.pb.go │ ├── UserService.pb.micro.go │ └── protos │ │ ├── UserService.proto │ │ └── google │ │ └── protobuf │ │ └── timestamp.proto └── test.go ├── p3 └── main.go ├── p4 ├── main.go └── prodModels.go ├── p5 └── client.go ├── p6 ├── main.go └── prodModels.go ├── p7 ├── client │ └── client.go ├── main.go └── prodModels.go ├── p8 ├── client │ └── client.go ├── main.go └── prodModels.go └── p9 ├── client └── main.go ├── main.go └── prodModels.go /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master,v2 ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master,v2 ] 20 | schedule: 21 | - cron: '16 2 * * 0' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'go' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v1 72 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 黄忠德 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-micro学习笔记 2 | 3 | master分支是micro/v3版本的,v2分支是micro/v2分支的。 4 | 5 | ## 第一章:热身和http api篇 6 | 7 | - 第1讲:开张课、安装框架、创建第一个web api 8 | - 第2讲:引入外部框架gin生成web API 9 | - 第3讲:服务注册:快速把服务注册到Consul中 10 | - 第4讲:[准备工作课]模拟运行API(主站API、商品API) 11 | - 第5讲:服务发现(1):获取consul服务列表、selector随机选择 12 | - 第6讲:穿插知识点:使用内置命令参数启动、注册多个服务 13 | - 第7讲:服务发现(2):开启多个服务、用轮询方式获取服务 14 | - 第8讲:服务调用:基本方式调用 Api(http api) 15 | - 第9讲:服务调用: 使用插件、调用http api的正规姿势(初步) 16 | - 第10讲:调用http api的姿势:带参数调用(有思考题) 17 | - 第11讲:调用http api:引入protobuf、生成参数和响应模型 18 | - 第12讲:处理参数模型中的json tag不一致问题 19 | 20 | ## 第二章:rpc和微服务 21 | 22 | - 第13讲:使用rpc构建一个简易商品服务、注册到consul 23 | - 第14讲:在gin中调用上节课构建的rpc服务(获取商品列表) 24 | - 第15讲:在gin中调用rpc服务(参数名处理、代码基本封装) 25 | - 第16讲:Go-micro的装饰器wrapper的初步使用(中间件) 26 | - 第17讲:熔断器使用(1):hystrix初步、捕获超时报错 27 | - 第18讲:熔断器使用(2):服务降级的使用 28 | - 第19讲:熔断器使用(3):初步整合hystrix到go-micro中 29 | - 第20讲:上节课课后作业:增加商品详细API(rpc) 30 | - 第21讲:熔断器使用(4):通用降级方法的编写姿势 31 | - 第22讲:熔断器使用(5):熔断器的参数设置 32 | 33 | ## 第三章:Micro工具篇 34 | 35 | - 第23讲:微服务工具箱(运行时)学习:了解Micro、复习、列出所有服务 36 | - 第24讲:使用Micro工具查看和调用我们的服务 37 | - 第25讲:使用Micro为我们的rpc服务创建http api网关 38 | - 第26讲:(选学)创建grpc网关的基本设置和运行方法 39 | 40 | ## 第四章:场景练习之用户注册 41 | 42 | - 第27讲:复习课、基本接口(用户注册接口) 43 | - 第28讲:引入gorm、用户数据入库 44 | - 第29讲:用户注册场景:数据验证(1):第三方验证库、自定义错误信息 45 | - 第30讲:用户注册场景:数据验证(2):自定义验证tag、正则验证 46 | - 第31讲:用户注册场景:数据验证(3) :切片属性的验证(string切片) 47 | 48 | [Go-micro学习笔记(1)http调用](https://huangzhongde.cn/post/Golang/go-micro_note1/) 49 | 50 | [Go-micro学习笔记(2)gRPC使用](https://huangzhongde.cn/post/Golang/go-micro_note2/) 51 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module gomicro_note 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 7 | github.com/asim/go-micro/plugins/client/http/v3 v3.0.0-20210630091305-70ed9bf15486 8 | github.com/asim/go-micro/plugins/registry/etcd/v3 v3.0.0-20210630091305-70ed9bf15486 9 | github.com/asim/go-micro/plugins/server/http/v3 v3.0.0-20210630091305-70ed9bf15486 10 | github.com/asim/go-micro/v3 v3.5.2-0.20210630062103-c13bb07171bc 11 | github.com/gin-gonic/gin v1.7.2 12 | github.com/go-playground/universal-translator v0.17.0 // indirect 13 | github.com/go-playground/validator/v10 v10.6.1 // indirect 14 | github.com/golang/protobuf v1.5.2 15 | github.com/jinzhu/gorm v1.9.16 16 | github.com/leodido/go-urn v1.2.1 // indirect 17 | github.com/lib/pq v1.3.0 // indirect 18 | github.com/mattn/go-isatty v0.0.13 // indirect 19 | github.com/ugorji/go v1.2.6 // indirect 20 | golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect 21 | golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect 22 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect 23 | google.golang.org/protobuf v1.27.1 24 | gopkg.in/go-playground/assert.v1 v1.2.1 // indirect 25 | gopkg.in/go-playground/validator.v9 v9.31.0 // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /p1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | 7 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/server" 10 | ) 11 | 12 | // go-micro 体验 13 | 14 | func main() { 15 | service := httpServer.NewServer(server.Address(":8000")) 16 | 17 | mux := http.NewServeMux() 18 | mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 19 | w.Write([]byte("hello world")) 20 | }) 21 | 22 | hd := service.NewHandler(mux) 23 | service.Handle(hd) 24 | srv := micro.NewService( 25 | micro.Server(service), 26 | ) 27 | srv.Init() 28 | err := srv.Run() 29 | if err != nil { 30 | fmt.Println(err) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /p10/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "log" 6 | 7 | http "github.com/asim/go-micro/plugins/client/http/v3" 8 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 9 | "github.com/asim/go-micro/v3/client" 10 | "github.com/asim/go-micro/v3/registry" 11 | "github.com/asim/go-micro/v3/selector" 12 | ) 13 | 14 | // etcd 通过轮询获取服务 15 | // 使用插件 调用http api 带参数调用 16 | func callAPI(s selector.Selector) { 17 | myClient := http.NewClient( 18 | client.Selector(s), 19 | client.ContentType("application/json"), 20 | ) 21 | req := myClient.NewRequest("ProdSrv", "/v1/prods", map[string]interface{}{"size": 4}) 22 | var rsp map[string]interface{} 23 | err := myClient.Call(context.Background(), req, &rsp) 24 | if err != nil { 25 | log.Fatal(err) 26 | return 27 | } 28 | log.Println(rsp["data"]) 29 | } 30 | 31 | func main() { 32 | // etcd 连接句柄 33 | etcdReg := etcd.NewRegistry( 34 | registry.Addrs("127.0.0.1:2379")) 35 | 36 | sel := selector.NewSelector( 37 | selector.Registry(etcdReg), 38 | selector.SetStrategy(selector.RoundRobin), 39 | ) 40 | callAPI(sel) 41 | 42 | } 43 | -------------------------------------------------------------------------------- /p10/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 9 | "github.com/asim/go-micro/v3" 10 | "github.com/asim/go-micro/v3/registry" 11 | "github.com/asim/go-micro/v3/server" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | // 商品服务 16 | func main() { 17 | 18 | etcdReg := etcd.NewRegistry( 19 | registry.Addrs("127.0.0.1:2379")) 20 | 21 | r := gin.Default() 22 | // 路由分组 23 | v1Group := r.Group("/v1") 24 | { 25 | v1Group.Handle("POST", "/prods", func(c *gin.Context) { 26 | var pr ProdsRequest 27 | // 给默认值 28 | err := c.Bind(&pr) 29 | if err != nil || pr.Size <= 0 { 30 | log.Println(err) 31 | pr = ProdsRequest{Size: 2} 32 | } 33 | c.JSON(http.StatusOK, gin.H{ 34 | "data": NewProdList(pr.Size), 35 | }) 36 | }) 37 | } 38 | 39 | service := httpServer.NewServer( 40 | server.Name("ProdSrv"), 41 | server.Registry(etcdReg), 42 | ) 43 | 44 | hd := service.NewHandler(r) 45 | service.Handle(hd) 46 | 47 | srv := micro.NewService( 48 | micro.Server(service), 49 | ) 50 | // 通过命令行参数启动 51 | // --server_address 指定地址端口,或者环境变量$MICRO_SERVER_ADDRESS] 52 | // 运行2个服务 53 | // go run main.go prodModels.go --server_address 127.0.0.1:8000 54 | // go run main.go prodModels.go --server_address 127.0.0.1:8001 55 | srv.Init() 56 | srv.Run() 57 | } 58 | -------------------------------------------------------------------------------- /p10/prodModels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "strconv" 4 | 5 | // ProdModel 商品模型 6 | type ProdModel struct { 7 | ProdID int `json:"prod_id"` 8 | ProdName string `json:"prod_name"` 9 | } 10 | 11 | // ProdsRequest 请求信息打tag 12 | type ProdsRequest struct { 13 | Size int `form:"size"` 14 | } 15 | 16 | // NewProd 新增商品 17 | func NewProd(id int, name string) *ProdModel { 18 | return &ProdModel{ProdID: id, ProdName: name} 19 | } 20 | 21 | // NewProdList 根据前端请求的size返回商品数量 22 | func NewProdList(n int) []*ProdModel { 23 | ret := make([]*ProdModel, 0) 24 | for i := 0; i < n; i++ { 25 | ret = append(ret, NewProd(100+i, "Prod"+strconv.Itoa(100+i))) 26 | } 27 | return ret 28 | } 29 | -------------------------------------------------------------------------------- /p11/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p11/models" 6 | "log" 7 | 8 | httpServer "github.com/asim/go-micro/plugins/client/http/v3" 9 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 10 | "github.com/asim/go-micro/v3/client" 11 | "github.com/asim/go-micro/v3/registry" 12 | "github.com/asim/go-micro/v3/selector" 13 | ) 14 | 15 | // etcd 通过轮询获取服务 16 | // 调用http api 引入protobuf生成请求响应模型 17 | func callAPI(s selector.Selector) { 18 | myClient := httpServer.NewClient( 19 | client.Selector(s), 20 | client.ContentType("application/json"), 21 | ) 22 | req := myClient.NewRequest("ProdSrv", "/v1/prods", 23 | models.ProdRequest{Size: 6}) 24 | var rsp models.ProdListResponse 25 | err := myClient.Call(context.Background(), req, &rsp) 26 | if err != nil { 27 | log.Fatal(err) 28 | return 29 | } 30 | log.Println(rsp.GetData()) 31 | } 32 | 33 | func main() { 34 | // etcd 连接句柄 35 | etcdReg := etcd.NewRegistry( 36 | registry.Addrs("127.0.0.1:2379")) 37 | 38 | sel := selector.NewSelector( 39 | selector.Registry(etcdReg), 40 | selector.SetStrategy(selector.RoundRobin), 41 | ) 42 | callAPI(sel) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /p11/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/*.proto 4 | -------------------------------------------------------------------------------- /p11/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 9 | "github.com/asim/go-micro/v3" 10 | "github.com/asim/go-micro/v3/registry" 11 | "github.com/asim/go-micro/v3/server" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | // 商品服务 16 | func main() { 17 | 18 | etcdReg := etcd.NewRegistry( 19 | registry.Addrs("127.0.0.1:2379")) 20 | 21 | r := gin.Default() 22 | // 路由分组 23 | v1Group := r.Group("/v1") 24 | { 25 | v1Group.Handle("POST", "/prods", func(c *gin.Context) { 26 | var pr ProdsRequest 27 | // 给默认值 28 | err := c.Bind(&pr) 29 | if err != nil || pr.Size <= 0 { 30 | log.Println(err) 31 | pr = ProdsRequest{Size: 2} 32 | } 33 | c.JSON(http.StatusOK, gin.H{ 34 | "data": NewProdList(pr.Size), 35 | }) 36 | }) 37 | } 38 | 39 | service := httpServer.NewServer( 40 | server.Name("ProdSrv"), 41 | server.Registry(etcdReg), 42 | ) 43 | 44 | hd := service.NewHandler(r) 45 | service.Handle(hd) 46 | 47 | srv := micro.NewService( 48 | micro.Server(service), 49 | ) 50 | // 通过命令行参数启动 51 | // --server_address 指定地址端口,或者环境变量$MICRO_SERVER_ADDRESS] 52 | // 运行2个服务 53 | // go run main.go prodModels.go --server_address 127.0.0.1:8000 54 | // go run main.go prodModels.go --server_address 127.0.0.1:8001 55 | srv.Init() 56 | srv.Run() 57 | } 58 | -------------------------------------------------------------------------------- /p11/models/prods.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.27.0 4 | // protoc v3.17.2 5 | // source: models/protos/prods.proto 6 | 7 | package models 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type ProdModel struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | ProdId int32 `protobuf:"varint,1,opt,name=ProdId,proto3" json:"ProdId,omitempty"` 29 | ProdName string `protobuf:"bytes,2,opt,name=ProdName,proto3" json:"ProdName,omitempty"` 30 | } 31 | 32 | func (x *ProdModel) Reset() { 33 | *x = ProdModel{} 34 | if protoimpl.UnsafeEnabled { 35 | mi := &file_models_protos_prods_proto_msgTypes[0] 36 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 37 | ms.StoreMessageInfo(mi) 38 | } 39 | } 40 | 41 | func (x *ProdModel) String() string { 42 | return protoimpl.X.MessageStringOf(x) 43 | } 44 | 45 | func (*ProdModel) ProtoMessage() {} 46 | 47 | func (x *ProdModel) ProtoReflect() protoreflect.Message { 48 | mi := &file_models_protos_prods_proto_msgTypes[0] 49 | if protoimpl.UnsafeEnabled && x != nil { 50 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 51 | if ms.LoadMessageInfo() == nil { 52 | ms.StoreMessageInfo(mi) 53 | } 54 | return ms 55 | } 56 | return mi.MessageOf(x) 57 | } 58 | 59 | // Deprecated: Use ProdModel.ProtoReflect.Descriptor instead. 60 | func (*ProdModel) Descriptor() ([]byte, []int) { 61 | return file_models_protos_prods_proto_rawDescGZIP(), []int{0} 62 | } 63 | 64 | func (x *ProdModel) GetProdId() int32 { 65 | if x != nil { 66 | return x.ProdId 67 | } 68 | return 0 69 | } 70 | 71 | func (x *ProdModel) GetProdName() string { 72 | if x != nil { 73 | return x.ProdName 74 | } 75 | return "" 76 | } 77 | 78 | // 休闲鞋 79 | type ProdRequest struct { 80 | state protoimpl.MessageState 81 | sizeCache protoimpl.SizeCache 82 | unknownFields protoimpl.UnknownFields 83 | 84 | Size int32 `protobuf:"varint,1,opt,name=size,proto3" json:"size,omitempty"` 85 | } 86 | 87 | func (x *ProdRequest) Reset() { 88 | *x = ProdRequest{} 89 | if protoimpl.UnsafeEnabled { 90 | mi := &file_models_protos_prods_proto_msgTypes[1] 91 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 92 | ms.StoreMessageInfo(mi) 93 | } 94 | } 95 | 96 | func (x *ProdRequest) String() string { 97 | return protoimpl.X.MessageStringOf(x) 98 | } 99 | 100 | func (*ProdRequest) ProtoMessage() {} 101 | 102 | func (x *ProdRequest) ProtoReflect() protoreflect.Message { 103 | mi := &file_models_protos_prods_proto_msgTypes[1] 104 | if protoimpl.UnsafeEnabled && x != nil { 105 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 106 | if ms.LoadMessageInfo() == nil { 107 | ms.StoreMessageInfo(mi) 108 | } 109 | return ms 110 | } 111 | return mi.MessageOf(x) 112 | } 113 | 114 | // Deprecated: Use ProdRequest.ProtoReflect.Descriptor instead. 115 | func (*ProdRequest) Descriptor() ([]byte, []int) { 116 | return file_models_protos_prods_proto_rawDescGZIP(), []int{1} 117 | } 118 | 119 | func (x *ProdRequest) GetSize() int32 { 120 | if x != nil { 121 | return x.Size 122 | } 123 | return 0 124 | } 125 | 126 | type ProdListResponse struct { 127 | state protoimpl.MessageState 128 | sizeCache protoimpl.SizeCache 129 | unknownFields protoimpl.UnknownFields 130 | 131 | Data []*ProdModel `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"` 132 | } 133 | 134 | func (x *ProdListResponse) Reset() { 135 | *x = ProdListResponse{} 136 | if protoimpl.UnsafeEnabled { 137 | mi := &file_models_protos_prods_proto_msgTypes[2] 138 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 139 | ms.StoreMessageInfo(mi) 140 | } 141 | } 142 | 143 | func (x *ProdListResponse) String() string { 144 | return protoimpl.X.MessageStringOf(x) 145 | } 146 | 147 | func (*ProdListResponse) ProtoMessage() {} 148 | 149 | func (x *ProdListResponse) ProtoReflect() protoreflect.Message { 150 | mi := &file_models_protos_prods_proto_msgTypes[2] 151 | if protoimpl.UnsafeEnabled && x != nil { 152 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 153 | if ms.LoadMessageInfo() == nil { 154 | ms.StoreMessageInfo(mi) 155 | } 156 | return ms 157 | } 158 | return mi.MessageOf(x) 159 | } 160 | 161 | // Deprecated: Use ProdListResponse.ProtoReflect.Descriptor instead. 162 | func (*ProdListResponse) Descriptor() ([]byte, []int) { 163 | return file_models_protos_prods_proto_rawDescGZIP(), []int{2} 164 | } 165 | 166 | func (x *ProdListResponse) GetData() []*ProdModel { 167 | if x != nil { 168 | return x.Data 169 | } 170 | return nil 171 | } 172 | 173 | var File_models_protos_prods_proto protoreflect.FileDescriptor 174 | 175 | var file_models_protos_prods_proto_rawDesc = []byte{ 176 | 0x0a, 0x19, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 177 | 0x70, 0x72, 0x6f, 0x64, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6d, 0x6f, 0x64, 178 | 0x65, 0x6c, 0x73, 0x22, 0x3f, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 179 | 0x12, 0x16, 0x0a, 0x06, 0x50, 0x72, 0x6f, 0x64, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 180 | 0x52, 0x06, 0x50, 0x72, 0x6f, 0x64, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x64, 181 | 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x64, 182 | 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x21, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 183 | 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 184 | 0x05, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x39, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x64, 0x4c, 185 | 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x64, 186 | 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 187 | 0x6c, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x04, 0x64, 0x61, 188 | 0x74, 0x61, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x62, 0x06, 189 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 190 | } 191 | 192 | var ( 193 | file_models_protos_prods_proto_rawDescOnce sync.Once 194 | file_models_protos_prods_proto_rawDescData = file_models_protos_prods_proto_rawDesc 195 | ) 196 | 197 | func file_models_protos_prods_proto_rawDescGZIP() []byte { 198 | file_models_protos_prods_proto_rawDescOnce.Do(func() { 199 | file_models_protos_prods_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_protos_prods_proto_rawDescData) 200 | }) 201 | return file_models_protos_prods_proto_rawDescData 202 | } 203 | 204 | var file_models_protos_prods_proto_msgTypes = make([]protoimpl.MessageInfo, 3) 205 | var file_models_protos_prods_proto_goTypes = []interface{}{ 206 | (*ProdModel)(nil), // 0: models.ProdModel 207 | (*ProdRequest)(nil), // 1: models.ProdRequest 208 | (*ProdListResponse)(nil), // 2: models.ProdListResponse 209 | } 210 | var file_models_protos_prods_proto_depIdxs = []int32{ 211 | 0, // 0: models.ProdListResponse.data:type_name -> models.ProdModel 212 | 1, // [1:1] is the sub-list for method output_type 213 | 1, // [1:1] is the sub-list for method input_type 214 | 1, // [1:1] is the sub-list for extension type_name 215 | 1, // [1:1] is the sub-list for extension extendee 216 | 0, // [0:1] is the sub-list for field type_name 217 | } 218 | 219 | func init() { file_models_protos_prods_proto_init() } 220 | func file_models_protos_prods_proto_init() { 221 | if File_models_protos_prods_proto != nil { 222 | return 223 | } 224 | if !protoimpl.UnsafeEnabled { 225 | file_models_protos_prods_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 226 | switch v := v.(*ProdModel); i { 227 | case 0: 228 | return &v.state 229 | case 1: 230 | return &v.sizeCache 231 | case 2: 232 | return &v.unknownFields 233 | default: 234 | return nil 235 | } 236 | } 237 | file_models_protos_prods_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 238 | switch v := v.(*ProdRequest); i { 239 | case 0: 240 | return &v.state 241 | case 1: 242 | return &v.sizeCache 243 | case 2: 244 | return &v.unknownFields 245 | default: 246 | return nil 247 | } 248 | } 249 | file_models_protos_prods_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 250 | switch v := v.(*ProdListResponse); i { 251 | case 0: 252 | return &v.state 253 | case 1: 254 | return &v.sizeCache 255 | case 2: 256 | return &v.unknownFields 257 | default: 258 | return nil 259 | } 260 | } 261 | } 262 | type x struct{} 263 | out := protoimpl.TypeBuilder{ 264 | File: protoimpl.DescBuilder{ 265 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 266 | RawDescriptor: file_models_protos_prods_proto_rawDesc, 267 | NumEnums: 0, 268 | NumMessages: 3, 269 | NumExtensions: 0, 270 | NumServices: 0, 271 | }, 272 | GoTypes: file_models_protos_prods_proto_goTypes, 273 | DependencyIndexes: file_models_protos_prods_proto_depIdxs, 274 | MessageInfos: file_models_protos_prods_proto_msgTypes, 275 | }.Build() 276 | File_models_protos_prods_proto = out.File 277 | file_models_protos_prods_proto_rawDesc = nil 278 | file_models_protos_prods_proto_goTypes = nil 279 | file_models_protos_prods_proto_depIdxs = nil 280 | } 281 | -------------------------------------------------------------------------------- /p11/models/prods.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prods.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | // Reference imports to suppress errors if they are not otherwise used. 13 | var _ = proto.Marshal 14 | var _ = fmt.Errorf 15 | var _ = math.Inf 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the proto package it is being compiled against. 19 | // A compilation error at this line likely means your copy of the 20 | // proto package needs to be updated. 21 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 22 | -------------------------------------------------------------------------------- /p11/models/protos/prods.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package models; 4 | 5 | option go_package = "./models"; 6 | 7 | message ProdModel{ 8 | int32 ProdId = 1; 9 | string ProdName = 2; 10 | } 11 | 12 | // 休闲鞋 13 | message ProdRequest{ 14 | int32 size = 1; 15 | } 16 | 17 | message ProdListResponse{ 18 | repeated ProdModel data = 1; 19 | } -------------------------------------------------------------------------------- /p11/prodModels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "strconv" 4 | 5 | // ProdModel 商品模型 6 | type ProdModel struct { 7 | ProdID int 8 | ProdName string 9 | } 10 | 11 | // ProdsRequest form请求 12 | type ProdsRequest struct { 13 | Size int `form:"size"` 14 | } 15 | 16 | // NewProd 新增商品 17 | func NewProd(id int, name string) *ProdModel { 18 | return &ProdModel{ProdID: id, ProdName: name} 19 | } 20 | 21 | // NewProdList 根据前端请求的size返回商品数量 22 | func NewProdList(n int) []*ProdModel { 23 | ret := make([]*ProdModel, 0) 24 | for i := 0; i < n; i++ { 25 | ret = append(ret, NewProd(100+i, "Prod"+strconv.Itoa(100+i))) 26 | } 27 | return ret 28 | } 29 | -------------------------------------------------------------------------------- /p12/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p12/models" 6 | "log" 7 | 8 | httpServer "github.com/asim/go-micro/plugins/client/http/v3" 9 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 10 | "github.com/asim/go-micro/v3/client" 11 | "github.com/asim/go-micro/v3/registry" 12 | "github.com/asim/go-micro/v3/selector" 13 | ) 14 | 15 | // etcd 通过轮询获取服务 16 | // 调用http api json tag不一致处理 17 | // 使用第三方包 github.com/favadi/protoc-go-inject-tag 18 | func callAPI(s selector.Selector) { 19 | myClient := httpServer.NewClient( 20 | client.Selector(s), 21 | client.ContentType("application/json"), 22 | ) 23 | req := myClient.NewRequest("ProdSrv", "/v1/prods", 24 | models.ProdRequest{Size: 6}) 25 | var rsp models.ProdListResponse 26 | err := myClient.Call(context.Background(), req, &rsp) 27 | if err != nil { 28 | log.Fatal(err) 29 | return 30 | } 31 | log.Println(rsp.GetData()) 32 | } 33 | 34 | func main() { 35 | // etcd 连接句柄 36 | etcdReg := etcd.NewRegistry( 37 | registry.Addrs("127.0.0.1:2379")) 38 | 39 | sel := selector.NewSelector( 40 | selector.Registry(etcdReg), 41 | selector.SetStrategy(selector.RoundRobin), 42 | ) 43 | callAPI(sel) 44 | 45 | } 46 | -------------------------------------------------------------------------------- /p12/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # go get -u github.com/favadi/protoc-go-inject-tag 4 | protoc --micro_out=./ --go_out=./ models/protos/prods.proto && \ 5 | protoc-go-inject-tag --input=./models/prods.pb.go 6 | -------------------------------------------------------------------------------- /p12/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 9 | "github.com/asim/go-micro/v3" 10 | "github.com/asim/go-micro/v3/registry" 11 | "github.com/asim/go-micro/v3/server" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | // 商品服务 16 | func main() { 17 | 18 | etcdReg := etcd.NewRegistry( 19 | registry.Addrs("127.0.0.1:2379")) 20 | 21 | r := gin.Default() 22 | // 路由分组 23 | v1Group := r.Group("/v1") 24 | { 25 | v1Group.Handle("POST", "/prods", func(c *gin.Context) { 26 | var pr ProdsRequest 27 | // 给默认值 28 | err := c.Bind(&pr) 29 | if err != nil || pr.Size <= 0 { 30 | log.Println(err) 31 | pr = ProdsRequest{Size: 2} 32 | } 33 | c.JSON(http.StatusOK, gin.H{ 34 | "data": NewProdList(pr.Size), 35 | }) 36 | }) 37 | } 38 | 39 | service := httpServer.NewServer( 40 | server.Name("ProdSrv"), 41 | server.Registry(etcdReg), 42 | ) 43 | 44 | hd := service.NewHandler(r) 45 | service.Handle(hd) 46 | 47 | srv := micro.NewService( 48 | micro.Server(service), 49 | ) 50 | // 通过命令行参数启动 51 | // --server_address 指定地址端口,或者环境变量$MICRO_SERVER_ADDRESS] 52 | // 运行2个服务 53 | // go run main.go prodModels.go --server_address 127.0.0.1:8000 54 | // go run main.go prodModels.go --server_address 127.0.0.1:8001 55 | srv.Init() 56 | srv.Run() 57 | } 58 | -------------------------------------------------------------------------------- /p12/models/prods.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.27.0 4 | // protoc v3.17.2 5 | // source: models/protos/prods.proto 6 | 7 | package models 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type ProdModel struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | // @inject_tag: json:"prod_id" 29 | ProdId int32 `protobuf:"varint,1,opt,name=ProdId,proto3" json:"prod_id"` 30 | // @inject_tag: json:"prod_name" 31 | ProdName string `protobuf:"bytes,2,opt,name=ProdName,proto3" json:"prod_name"` 32 | } 33 | 34 | func (x *ProdModel) Reset() { 35 | *x = ProdModel{} 36 | if protoimpl.UnsafeEnabled { 37 | mi := &file_models_protos_prods_proto_msgTypes[0] 38 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 39 | ms.StoreMessageInfo(mi) 40 | } 41 | } 42 | 43 | func (x *ProdModel) String() string { 44 | return protoimpl.X.MessageStringOf(x) 45 | } 46 | 47 | func (*ProdModel) ProtoMessage() {} 48 | 49 | func (x *ProdModel) ProtoReflect() protoreflect.Message { 50 | mi := &file_models_protos_prods_proto_msgTypes[0] 51 | if protoimpl.UnsafeEnabled && x != nil { 52 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 53 | if ms.LoadMessageInfo() == nil { 54 | ms.StoreMessageInfo(mi) 55 | } 56 | return ms 57 | } 58 | return mi.MessageOf(x) 59 | } 60 | 61 | // Deprecated: Use ProdModel.ProtoReflect.Descriptor instead. 62 | func (*ProdModel) Descriptor() ([]byte, []int) { 63 | return file_models_protos_prods_proto_rawDescGZIP(), []int{0} 64 | } 65 | 66 | func (x *ProdModel) GetProdId() int32 { 67 | if x != nil { 68 | return x.ProdId 69 | } 70 | return 0 71 | } 72 | 73 | func (x *ProdModel) GetProdName() string { 74 | if x != nil { 75 | return x.ProdName 76 | } 77 | return "" 78 | } 79 | 80 | type ProdRequest struct { 81 | state protoimpl.MessageState 82 | sizeCache protoimpl.SizeCache 83 | unknownFields protoimpl.UnknownFields 84 | 85 | Size int32 `protobuf:"varint,1,opt,name=size,proto3" json:"size,omitempty"` 86 | } 87 | 88 | func (x *ProdRequest) Reset() { 89 | *x = ProdRequest{} 90 | if protoimpl.UnsafeEnabled { 91 | mi := &file_models_protos_prods_proto_msgTypes[1] 92 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 93 | ms.StoreMessageInfo(mi) 94 | } 95 | } 96 | 97 | func (x *ProdRequest) String() string { 98 | return protoimpl.X.MessageStringOf(x) 99 | } 100 | 101 | func (*ProdRequest) ProtoMessage() {} 102 | 103 | func (x *ProdRequest) ProtoReflect() protoreflect.Message { 104 | mi := &file_models_protos_prods_proto_msgTypes[1] 105 | if protoimpl.UnsafeEnabled && x != nil { 106 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 107 | if ms.LoadMessageInfo() == nil { 108 | ms.StoreMessageInfo(mi) 109 | } 110 | return ms 111 | } 112 | return mi.MessageOf(x) 113 | } 114 | 115 | // Deprecated: Use ProdRequest.ProtoReflect.Descriptor instead. 116 | func (*ProdRequest) Descriptor() ([]byte, []int) { 117 | return file_models_protos_prods_proto_rawDescGZIP(), []int{1} 118 | } 119 | 120 | func (x *ProdRequest) GetSize() int32 { 121 | if x != nil { 122 | return x.Size 123 | } 124 | return 0 125 | } 126 | 127 | type ProdListResponse struct { 128 | state protoimpl.MessageState 129 | sizeCache protoimpl.SizeCache 130 | unknownFields protoimpl.UnknownFields 131 | 132 | Data []*ProdModel `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"` 133 | } 134 | 135 | func (x *ProdListResponse) Reset() { 136 | *x = ProdListResponse{} 137 | if protoimpl.UnsafeEnabled { 138 | mi := &file_models_protos_prods_proto_msgTypes[2] 139 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 140 | ms.StoreMessageInfo(mi) 141 | } 142 | } 143 | 144 | func (x *ProdListResponse) String() string { 145 | return protoimpl.X.MessageStringOf(x) 146 | } 147 | 148 | func (*ProdListResponse) ProtoMessage() {} 149 | 150 | func (x *ProdListResponse) ProtoReflect() protoreflect.Message { 151 | mi := &file_models_protos_prods_proto_msgTypes[2] 152 | if protoimpl.UnsafeEnabled && x != nil { 153 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 154 | if ms.LoadMessageInfo() == nil { 155 | ms.StoreMessageInfo(mi) 156 | } 157 | return ms 158 | } 159 | return mi.MessageOf(x) 160 | } 161 | 162 | // Deprecated: Use ProdListResponse.ProtoReflect.Descriptor instead. 163 | func (*ProdListResponse) Descriptor() ([]byte, []int) { 164 | return file_models_protos_prods_proto_rawDescGZIP(), []int{2} 165 | } 166 | 167 | func (x *ProdListResponse) GetData() []*ProdModel { 168 | if x != nil { 169 | return x.Data 170 | } 171 | return nil 172 | } 173 | 174 | var File_models_protos_prods_proto protoreflect.FileDescriptor 175 | 176 | var file_models_protos_prods_proto_rawDesc = []byte{ 177 | 0x0a, 0x19, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 178 | 0x70, 0x72, 0x6f, 0x64, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6d, 0x6f, 0x64, 179 | 0x65, 0x6c, 0x73, 0x22, 0x3f, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 180 | 0x12, 0x16, 0x0a, 0x06, 0x50, 0x72, 0x6f, 0x64, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 181 | 0x52, 0x06, 0x50, 0x72, 0x6f, 0x64, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x64, 182 | 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x64, 183 | 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x21, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 184 | 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 185 | 0x05, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x39, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x64, 0x4c, 186 | 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x64, 187 | 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 188 | 0x6c, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x04, 0x64, 0x61, 189 | 0x74, 0x61, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x62, 0x06, 190 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 191 | } 192 | 193 | var ( 194 | file_models_protos_prods_proto_rawDescOnce sync.Once 195 | file_models_protos_prods_proto_rawDescData = file_models_protos_prods_proto_rawDesc 196 | ) 197 | 198 | func file_models_protos_prods_proto_rawDescGZIP() []byte { 199 | file_models_protos_prods_proto_rawDescOnce.Do(func() { 200 | file_models_protos_prods_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_protos_prods_proto_rawDescData) 201 | }) 202 | return file_models_protos_prods_proto_rawDescData 203 | } 204 | 205 | var file_models_protos_prods_proto_msgTypes = make([]protoimpl.MessageInfo, 3) 206 | var file_models_protos_prods_proto_goTypes = []interface{}{ 207 | (*ProdModel)(nil), // 0: models.ProdModel 208 | (*ProdRequest)(nil), // 1: models.ProdRequest 209 | (*ProdListResponse)(nil), // 2: models.ProdListResponse 210 | } 211 | var file_models_protos_prods_proto_depIdxs = []int32{ 212 | 0, // 0: models.ProdListResponse.data:type_name -> models.ProdModel 213 | 1, // [1:1] is the sub-list for method output_type 214 | 1, // [1:1] is the sub-list for method input_type 215 | 1, // [1:1] is the sub-list for extension type_name 216 | 1, // [1:1] is the sub-list for extension extendee 217 | 0, // [0:1] is the sub-list for field type_name 218 | } 219 | 220 | func init() { file_models_protos_prods_proto_init() } 221 | func file_models_protos_prods_proto_init() { 222 | if File_models_protos_prods_proto != nil { 223 | return 224 | } 225 | if !protoimpl.UnsafeEnabled { 226 | file_models_protos_prods_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 227 | switch v := v.(*ProdModel); i { 228 | case 0: 229 | return &v.state 230 | case 1: 231 | return &v.sizeCache 232 | case 2: 233 | return &v.unknownFields 234 | default: 235 | return nil 236 | } 237 | } 238 | file_models_protos_prods_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 239 | switch v := v.(*ProdRequest); i { 240 | case 0: 241 | return &v.state 242 | case 1: 243 | return &v.sizeCache 244 | case 2: 245 | return &v.unknownFields 246 | default: 247 | return nil 248 | } 249 | } 250 | file_models_protos_prods_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 251 | switch v := v.(*ProdListResponse); i { 252 | case 0: 253 | return &v.state 254 | case 1: 255 | return &v.sizeCache 256 | case 2: 257 | return &v.unknownFields 258 | default: 259 | return nil 260 | } 261 | } 262 | } 263 | type x struct{} 264 | out := protoimpl.TypeBuilder{ 265 | File: protoimpl.DescBuilder{ 266 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 267 | RawDescriptor: file_models_protos_prods_proto_rawDesc, 268 | NumEnums: 0, 269 | NumMessages: 3, 270 | NumExtensions: 0, 271 | NumServices: 0, 272 | }, 273 | GoTypes: file_models_protos_prods_proto_goTypes, 274 | DependencyIndexes: file_models_protos_prods_proto_depIdxs, 275 | MessageInfos: file_models_protos_prods_proto_msgTypes, 276 | }.Build() 277 | File_models_protos_prods_proto = out.File 278 | file_models_protos_prods_proto_rawDesc = nil 279 | file_models_protos_prods_proto_goTypes = nil 280 | file_models_protos_prods_proto_depIdxs = nil 281 | } 282 | -------------------------------------------------------------------------------- /p12/models/prods.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prods.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | // Reference imports to suppress errors if they are not otherwise used. 13 | var _ = proto.Marshal 14 | var _ = fmt.Errorf 15 | var _ = math.Inf 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the proto package it is being compiled against. 19 | // A compilation error at this line likely means your copy of the 20 | // proto package needs to be updated. 21 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 22 | -------------------------------------------------------------------------------- /p12/models/protos/prods.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package models; 4 | 5 | option go_package = "./models"; 6 | 7 | message ProdModel{ 8 | // @inject_tag: json:"prod_id" 9 | int32 ProdId = 1; 10 | // @inject_tag: json:"prod_name" 11 | string ProdName = 2; 12 | } 13 | 14 | message ProdRequest{ 15 | int32 size = 1; 16 | } 17 | 18 | message ProdListResponse{ 19 | repeated ProdModel data = 1; 20 | } -------------------------------------------------------------------------------- /p12/prodModels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "strconv" 4 | 5 | // ProdModel 商品模型 6 | type ProdModel struct { 7 | ProdID int `json:"prod_id"` 8 | ProdName string `json:"prod_name"` 9 | } 10 | 11 | // ProdsRequest form请求 12 | type ProdsRequest struct { 13 | Size int `form:"size"` 14 | } 15 | 16 | // NewProd 新增商品 17 | func NewProd(id int, name string) *ProdModel { 18 | return &ProdModel{ProdID: id, ProdName: name} 19 | } 20 | 21 | // NewProdList 根据前端请求的size返回商品数量 22 | func NewProdList(n int) []*ProdModel { 23 | ret := make([]*ProdModel, 0) 24 | for i := 0; i < n; i++ { 25 | ret = append(ret, NewProd(100+i, "Prod"+strconv.Itoa(100+i))) 26 | } 27 | return ret 28 | } 29 | -------------------------------------------------------------------------------- /p13/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/prodService.proto && \ 4 | protoc-go-inject-tag --input=./models/prodService.pb.go 5 | -------------------------------------------------------------------------------- /p13/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p13/models" 5 | "gomicro_note/p13/prods" 6 | "log" 7 | 8 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 9 | "github.com/asim/go-micro/v3" 10 | "github.com/asim/go-micro/v3/registry" 11 | ) 12 | 13 | func main() { 14 | 15 | etcdReg := etcd.NewRegistry( 16 | registry.Addrs("127.0.0.1:2379"), 17 | ) 18 | 19 | app := micro.NewService( 20 | micro.Name("ProdService"), 21 | micro.Address(":8000"), 22 | micro.Registry(etcdReg), 23 | ) 24 | 25 | app.Init() 26 | err := models.RegisterProdServiceHandler(app.Server(), new(prods.ProdService)) 27 | if err != nil { 28 | panic(err) 29 | } 30 | if err := app.Run(); err != nil { 31 | log.Fatal(err) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /p13/models/prodService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prodService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for ProdService service 37 | 38 | func NewProdServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for ProdService service 43 | 44 | type ProdService interface { 45 | GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) 46 | } 47 | 48 | type prodService struct { 49 | c client.Client 50 | name string 51 | } 52 | 53 | func NewProdService(name string, c client.Client) ProdService { 54 | return &prodService{ 55 | c: c, 56 | name: name, 57 | } 58 | } 59 | 60 | func (c *prodService) GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) { 61 | req := c.c.NewRequest(c.name, "ProdService.GetProdList", in) 62 | out := new(ProdListResponse) 63 | err := c.c.Call(ctx, req, out, opts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | // Server API for ProdService service 71 | 72 | type ProdServiceHandler interface { 73 | GetProdList(context.Context, *ProdRequest, *ProdListResponse) error 74 | } 75 | 76 | func RegisterProdServiceHandler(s server.Server, hdlr ProdServiceHandler, opts ...server.HandlerOption) error { 77 | type prodService interface { 78 | GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error 79 | } 80 | type ProdService struct { 81 | prodService 82 | } 83 | h := &prodServiceHandler{hdlr} 84 | return s.Handle(s.NewHandler(&ProdService{h}, opts...)) 85 | } 86 | 87 | type prodServiceHandler struct { 88 | ProdServiceHandler 89 | } 90 | 91 | func (h *prodServiceHandler) GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error { 92 | return h.ProdServiceHandler.GetProdList(ctx, in, out) 93 | } 94 | -------------------------------------------------------------------------------- /p13/models/protos/prodService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package models; 3 | 4 | option go_package = "./models"; 5 | 6 | message ProdRequest{ 7 | int32 size = 1; 8 | } 9 | 10 | // 商品模型 11 | message ProdModel{ 12 | // @inject_tag: json:"pid" 13 | int32 ProdId = 1; 14 | // @inject_tag: json:"pname" 15 | string ProdName = 2; 16 | } 17 | 18 | message ProdListResponse{ 19 | repeated ProdModel data = 1; 20 | } 21 | 22 | service ProdService{ 23 | rpc GetProdList(ProdRequest) returns (ProdListResponse); 24 | } -------------------------------------------------------------------------------- /p13/prods/prodService.go: -------------------------------------------------------------------------------- 1 | package prods 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p13/models" 6 | "strconv" 7 | ) 8 | 9 | // ProdService 商品服务 10 | type ProdService struct{} 11 | 12 | func newProd(id int32, pname string) *models.ProdModel { 13 | return &models.ProdModel{ProdId: id, ProdName: pname} 14 | } 15 | 16 | // GetProdList 返回商品列表 17 | func (*ProdService) GetProdList(ctx context.Context, in *models.ProdRequest, res *models.ProdListResponse) error { 18 | models := make([]*models.ProdModel, 0) 19 | var i int32 20 | for i = 0; i < in.Size; i++ { 21 | models = append(models, newProd(100+i, "prodName"+strconv.Itoa(100+int(i)))) 22 | } 23 | res.Data = models 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /p14/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 作为客户端,调用p13的rpc服务 4 | 5 | import ( 6 | "context" 7 | "gomicro_note/p14/models" 8 | 9 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 10 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 11 | "github.com/asim/go-micro/v3" 12 | "github.com/asim/go-micro/v3/registry" 13 | "github.com/asim/go-micro/v3/server" 14 | "github.com/gin-gonic/gin" 15 | ) 16 | 17 | func main() { 18 | r := gin.Default() 19 | etcdReg := etcd.NewRegistry( 20 | registry.Addrs("127.0.0.1:2379"), 21 | ) 22 | 23 | service := httpServer.NewServer( 24 | server.Name("ProdService.client"), 25 | server.Address(":9000"), 26 | server.Registry(etcdReg), 27 | ) 28 | 29 | myService := micro.NewService( 30 | micro.Name("ProdService.client"), 31 | micro.Registry(etcdReg), 32 | ) 33 | prodService := models.NewProdService("ProdService", myService.Client()) 34 | v1Group := r.Group("/v1") 35 | { 36 | v1Group.Handle("POST", "/prods", func(c *gin.Context) { 37 | var prodReq models.ProdRequest 38 | err := c.Bind(&prodReq) 39 | if err != nil { 40 | c.JSON(500, gin.H{ 41 | "status": err.Error()}) 42 | return 43 | } 44 | if prodReq.Size == 0 { 45 | prodReq.Size = 2 46 | } 47 | prodRes, err := prodService.GetProdList(context.Background(), &prodReq) 48 | if err != nil { 49 | c.JSON(500, gin.H{ 50 | "status": err.Error()}) 51 | return 52 | } 53 | c.JSON(200, gin.H{ 54 | "data": prodRes.Data, 55 | }) 56 | }) 57 | } 58 | 59 | hd := service.NewHandler(r) 60 | service.Handle(hd) 61 | 62 | srv := micro.NewService( 63 | micro.Server(service), 64 | ) 65 | 66 | srv.Init() 67 | srv.Run() 68 | } 69 | -------------------------------------------------------------------------------- /p14/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/prodService.proto && \ 4 | protoc-go-inject-tag --input=./models/prodService.pb.go 5 | -------------------------------------------------------------------------------- /p14/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p13/models" 5 | "gomicro_note/p13/prods" 6 | "log" 7 | 8 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 9 | "github.com/asim/go-micro/v3" 10 | "github.com/asim/go-micro/v3/registry" 11 | ) 12 | 13 | func main() { 14 | 15 | etcdReg := etcd.NewRegistry( 16 | registry.Addrs("127.0.0.1:2379"), 17 | ) 18 | 19 | app := micro.NewService( 20 | micro.Name("ProdService"), 21 | micro.Address(":8000"), 22 | micro.Registry(etcdReg), 23 | ) 24 | 25 | app.Init() 26 | err := models.RegisterProdServiceHandler(app.Server(), new(prods.ProdService)) 27 | if err != nil { 28 | panic(err) 29 | } 30 | if err := app.Run(); err != nil { 31 | log.Fatal(err) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /p14/models/prodService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prodService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for ProdService service 37 | 38 | func NewProdServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for ProdService service 43 | 44 | type ProdService interface { 45 | GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) 46 | } 47 | 48 | type prodService struct { 49 | c client.Client 50 | name string 51 | } 52 | 53 | func NewProdService(name string, c client.Client) ProdService { 54 | return &prodService{ 55 | c: c, 56 | name: name, 57 | } 58 | } 59 | 60 | func (c *prodService) GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) { 61 | req := c.c.NewRequest(c.name, "ProdService.GetProdList", in) 62 | out := new(ProdListResponse) 63 | err := c.c.Call(ctx, req, out, opts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | // Server API for ProdService service 71 | 72 | type ProdServiceHandler interface { 73 | GetProdList(context.Context, *ProdRequest, *ProdListResponse) error 74 | } 75 | 76 | func RegisterProdServiceHandler(s server.Server, hdlr ProdServiceHandler, opts ...server.HandlerOption) error { 77 | type prodService interface { 78 | GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error 79 | } 80 | type ProdService struct { 81 | prodService 82 | } 83 | h := &prodServiceHandler{hdlr} 84 | return s.Handle(s.NewHandler(&ProdService{h}, opts...)) 85 | } 86 | 87 | type prodServiceHandler struct { 88 | ProdServiceHandler 89 | } 90 | 91 | func (h *prodServiceHandler) GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error { 92 | return h.ProdServiceHandler.GetProdList(ctx, in, out) 93 | } 94 | -------------------------------------------------------------------------------- /p14/models/protos/prodService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package models; 3 | 4 | option go_package = "./models"; 5 | 6 | message ProdRequest{ 7 | // @inject_tag: json:"size" form:"size" 8 | int32 size = 1; 9 | } 10 | 11 | // 商品模型 12 | message ProdModel{ 13 | // @inject_tag: json:"pid" 14 | int32 ProdId = 1; 15 | // @inject_tag: json:"pname" 16 | string ProdName = 2; 17 | } 18 | 19 | message ProdListResponse{ 20 | repeated ProdModel data = 1; 21 | } 22 | 23 | service ProdService{ 24 | rpc GetProdList(ProdRequest) returns (ProdListResponse); 25 | } -------------------------------------------------------------------------------- /p14/prods/prodService.go: -------------------------------------------------------------------------------- 1 | package prods 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p13/models" 6 | "strconv" 7 | ) 8 | 9 | // ProdService 商品服务 10 | type ProdService struct{} 11 | 12 | func newProd(id int32, pname string) *models.ProdModel { 13 | return &models.ProdModel{ProdId: id, ProdName: pname} 14 | } 15 | 16 | // GetProdList 返回商品列表 17 | func (*ProdService) GetProdList(ctx context.Context, in *models.ProdRequest, res *models.ProdListResponse) error { 18 | models := make([]*models.ProdModel, 0) 19 | var i int32 20 | for i = 0; i < in.Size; i++ { 21 | models = append(models, newProd(100+i, "prodName"+strconv.Itoa(100+int(i)))) 22 | } 23 | res.Data = models 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /p15/grpc_client/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/prodService.proto && \ 4 | protoc-go-inject-tag --input=models/prodService.pb.go -------------------------------------------------------------------------------- /p15/grpc_client/handlers/handler.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p15/grpc_client/models" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | // GetProdList 显示商品列表 11 | func GetProdList(c *gin.Context) { 12 | prodService := c.Keys["prodservice"].(models.ProdService) 13 | var prodReq models.ProdRequest 14 | err := c.Bind(&prodReq) 15 | if err != nil { 16 | c.JSON(500, gin.H{ 17 | "status": err.Error()}) 18 | return 19 | } 20 | if prodReq.Size == 0 { 21 | prodReq.Size = 2 22 | } 23 | prodRes, err := prodService.GetProdList(context.Background(), &prodReq) 24 | if err != nil { 25 | c.JSON(500, gin.H{ 26 | "status": err.Error()}) 27 | return 28 | } 29 | c.JSON(200, gin.H{ 30 | "data": prodRes.Data, 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /p15/grpc_client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p15/grpc_client/models" 5 | "gomicro_note/p15/grpc_client/routers" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 9 | "github.com/asim/go-micro/v3" 10 | "github.com/asim/go-micro/v3/registry" 11 | "github.com/asim/go-micro/v3/server" 12 | ) 13 | 14 | func main() { 15 | 16 | etcdReg := etcd.NewRegistry( 17 | registry.Addrs("127.0.0.1:2379"), 18 | ) 19 | 20 | service := httpServer.NewServer( 21 | server.Name("ProdService.client"), 22 | server.Address(":9000"), 23 | server.Registry(etcdReg), 24 | ) 25 | 26 | myService := micro.NewService( 27 | micro.Name("ProdService.client"), 28 | micro.Registry(etcdReg), 29 | ) 30 | prodService := models.NewProdService("ProdService", myService.Client()) 31 | 32 | hd := service.NewHandler(routers.InitRouter(prodService)) 33 | service.Handle(hd) 34 | 35 | srv := micro.NewService( 36 | micro.Server(service), 37 | ) 38 | 39 | srv.Init() 40 | srv.Run() 41 | } 42 | -------------------------------------------------------------------------------- /p15/grpc_client/middlewares/middleware.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "gomicro_note/p15/grpc_client/models" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // InitMiddleware 注入prodService中间件 10 | func InitMiddleware(prodService models.ProdService) gin.HandlerFunc { 11 | return func(c *gin.Context) { 12 | c.Keys = make(map[string]interface{}) 13 | c.Keys["prodservice"] = prodService 14 | c.Next() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /p15/grpc_client/models/prodService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prodService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for ProdService service 37 | 38 | func NewProdServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for ProdService service 43 | 44 | type ProdService interface { 45 | GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) 46 | } 47 | 48 | type prodService struct { 49 | c client.Client 50 | name string 51 | } 52 | 53 | func NewProdService(name string, c client.Client) ProdService { 54 | return &prodService{ 55 | c: c, 56 | name: name, 57 | } 58 | } 59 | 60 | func (c *prodService) GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) { 61 | req := c.c.NewRequest(c.name, "ProdService.GetProdList", in) 62 | out := new(ProdListResponse) 63 | err := c.c.Call(ctx, req, out, opts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | // Server API for ProdService service 71 | 72 | type ProdServiceHandler interface { 73 | GetProdList(context.Context, *ProdRequest, *ProdListResponse) error 74 | } 75 | 76 | func RegisterProdServiceHandler(s server.Server, hdlr ProdServiceHandler, opts ...server.HandlerOption) error { 77 | type prodService interface { 78 | GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error 79 | } 80 | type ProdService struct { 81 | prodService 82 | } 83 | h := &prodServiceHandler{hdlr} 84 | return s.Handle(s.NewHandler(&ProdService{h}, opts...)) 85 | } 86 | 87 | type prodServiceHandler struct { 88 | ProdServiceHandler 89 | } 90 | 91 | func (h *prodServiceHandler) GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error { 92 | return h.ProdServiceHandler.GetProdList(ctx, in, out) 93 | } 94 | -------------------------------------------------------------------------------- /p15/grpc_client/models/protos/prodService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package models; 3 | 4 | option go_package = "./models"; 5 | 6 | // 商品模型 7 | message ProdModel{ 8 | // @inject_tag: json:"pid" 9 | int32 ProdId = 1; 10 | // @inject_tag: json:"pname" 11 | string ProdName = 2; 12 | } 13 | 14 | message ProdRequest{ 15 | // @inject_tag: json:"size", form:"size" 16 | int32 size = 1; 17 | } 18 | 19 | message ProdListResponse{ 20 | repeated ProdModel data = 1; 21 | } 22 | 23 | service ProdService{ 24 | rpc GetProdList(ProdRequest) returns (ProdListResponse); 25 | } -------------------------------------------------------------------------------- /p15/grpc_client/routers/router.go: -------------------------------------------------------------------------------- 1 | package routers 2 | 3 | import ( 4 | "gomicro_note/p15/grpc_client/handlers" 5 | "gomicro_note/p15/grpc_client/middlewares" 6 | "gomicro_note/p15/grpc_client/models" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // InitRouter 路由 12 | func InitRouter(prodService models.ProdService) *gin.Engine { 13 | r := gin.Default() 14 | r.Use(middlewares.InitMiddleware(prodService)) 15 | v1Group := r.Group("/v1") 16 | { 17 | v1Group.Handle("POST", "/prods", handlers.GetProdList) 18 | } 19 | return r 20 | } 21 | -------------------------------------------------------------------------------- /p16/grpc_client/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/prodService.proto && \ 4 | protoc-go-inject-tag --input=./models/prodService.pb.go -------------------------------------------------------------------------------- /p16/grpc_client/handlers/handler.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p16/grpc_client/models" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | // GetProdList 显示商品列表 11 | func GetProdList(c *gin.Context) { 12 | prodService := c.Keys["prodservice"].(models.ProdService) 13 | var prodReq models.ProdRequest 14 | err := c.Bind(&prodReq) 15 | if err != nil { 16 | c.JSON(500, gin.H{ 17 | "status": err.Error()}) 18 | return 19 | } 20 | if prodReq.Size == 0 { 21 | prodReq.Size = 2 22 | } 23 | prodRes, _ := prodService.GetProdList(context.Background(), &prodReq) 24 | c.JSON(200, gin.H{ 25 | "data": prodRes.Data, 26 | }) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /p16/grpc_client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 装饰器的使用 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "gomicro_note/p16/grpc_client/models" 9 | "gomicro_note/p16/grpc_client/routers" 10 | 11 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 12 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 13 | "github.com/asim/go-micro/v3" 14 | "github.com/asim/go-micro/v3/client" 15 | "github.com/asim/go-micro/v3/metadata" 16 | "github.com/asim/go-micro/v3/registry" 17 | "github.com/asim/go-micro/v3/server" 18 | ) 19 | 20 | type logWrapper struct { 21 | client.Client 22 | } 23 | 24 | func (l *logWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 25 | md, _ := metadata.FromContext(ctx) 26 | fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Endpoint()) 27 | return l.Client.Call(ctx, req, rsp) 28 | } 29 | 30 | func newLogWrapper(c client.Client) client.Client { 31 | return &logWrapper{c} 32 | } 33 | 34 | func main() { 35 | 36 | etcdReg := etcd.NewRegistry( 37 | registry.Addrs("127.0.0.1:2379"), 38 | ) 39 | 40 | myService := micro.NewService( 41 | micro.Name("ProdService.client"), 42 | micro.WrapClient(newLogWrapper), 43 | ) 44 | prodService := models.NewProdService("ProdService", myService.Client()) 45 | 46 | service := httpServer.NewServer( 47 | server.Name("ProdService.client"), 48 | server.Address(":9000"), 49 | server.Registry(etcdReg), 50 | ) 51 | 52 | hd := service.NewHandler(routers.InitRouter(prodService)) 53 | service.Handle(hd) 54 | 55 | srv := micro.NewService( 56 | micro.Server(service), 57 | micro.Registry(etcdReg), 58 | ) 59 | 60 | srv.Init() 61 | srv.Run() 62 | } 63 | -------------------------------------------------------------------------------- /p16/grpc_client/middlewares/middleware.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "gomicro_note/p16/grpc_client/models" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // InitMiddleware 注入prodService中间件 10 | func InitMiddleware(prodService models.ProdService) gin.HandlerFunc { 11 | return func(c *gin.Context) { 12 | c.Keys = make(map[string]interface{}) 13 | c.Keys["prodservice"] = prodService 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /p16/grpc_client/models/prodService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prodService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for ProdService service 37 | 38 | func NewProdServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for ProdService service 43 | 44 | type ProdService interface { 45 | GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) 46 | } 47 | 48 | type prodService struct { 49 | c client.Client 50 | name string 51 | } 52 | 53 | func NewProdService(name string, c client.Client) ProdService { 54 | return &prodService{ 55 | c: c, 56 | name: name, 57 | } 58 | } 59 | 60 | func (c *prodService) GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) { 61 | req := c.c.NewRequest(c.name, "ProdService.GetProdList", in) 62 | out := new(ProdListResponse) 63 | err := c.c.Call(ctx, req, out, opts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | // Server API for ProdService service 71 | 72 | type ProdServiceHandler interface { 73 | GetProdList(context.Context, *ProdRequest, *ProdListResponse) error 74 | } 75 | 76 | func RegisterProdServiceHandler(s server.Server, hdlr ProdServiceHandler, opts ...server.HandlerOption) error { 77 | type prodService interface { 78 | GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error 79 | } 80 | type ProdService struct { 81 | prodService 82 | } 83 | h := &prodServiceHandler{hdlr} 84 | return s.Handle(s.NewHandler(&ProdService{h}, opts...)) 85 | } 86 | 87 | type prodServiceHandler struct { 88 | ProdServiceHandler 89 | } 90 | 91 | func (h *prodServiceHandler) GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error { 92 | return h.ProdServiceHandler.GetProdList(ctx, in, out) 93 | } 94 | -------------------------------------------------------------------------------- /p16/grpc_client/models/protos/prodService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package models; 3 | 4 | option go_package = "./models"; 5 | 6 | // 商品模型 7 | message ProdModel{ 8 | // @inject_tag: json:"pid" 9 | int32 ProdId = 1; 10 | // @inject_tag: json:"pname" 11 | string ProdName = 2; 12 | } 13 | 14 | message ProdRequest{ 15 | // @inject_tag: json:"size", form:"size" 16 | int32 size = 1; 17 | } 18 | 19 | message ProdListResponse{ 20 | repeated ProdModel data = 1; 21 | } 22 | 23 | service ProdService{ 24 | rpc GetProdList(ProdRequest) returns (ProdListResponse); 25 | } -------------------------------------------------------------------------------- /p16/grpc_client/routers/router.go: -------------------------------------------------------------------------------- 1 | package routers 2 | 3 | import ( 4 | "gomicro_note/p16/grpc_client/handlers" 5 | "gomicro_note/p16/grpc_client/middlewares" 6 | "gomicro_note/p16/grpc_client/models" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // InitRouter 路由 12 | func InitRouter(prodService models.ProdService) *gin.Engine { 13 | r := gin.Default() 14 | r.Use(middlewares.InitMiddleware(prodService)) 15 | v1Group := r.Group("/v1") 16 | { 17 | v1Group.Handle("POST", "/prods", handlers.GetProdList) 18 | } 19 | return r 20 | } 21 | -------------------------------------------------------------------------------- /p17/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/prodService.proto && \ 4 | protoc-go-inject-tag --input=./models/prodService.pb.go -------------------------------------------------------------------------------- /p17/grpc_client/handlers/handler.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p17/models" 6 | 7 | "github.com/afex/hystrix-go/hystrix" 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // GetProdList 显示商品列表 12 | func GetProdList(c *gin.Context) { 13 | prodService := c.Keys["prodservice"].(models.ProdService) 14 | var prodReq models.ProdRequest 15 | err := c.Bind(&prodReq) 16 | if err != nil { 17 | c.JSON(500, gin.H{ 18 | "status": err.Error()}) 19 | return 20 | } 21 | if prodReq.Size == 0 { 22 | prodReq.Size = 2 23 | } 24 | // 超时代码 25 | // 1.配置config 26 | configA := hystrix.CommandConfig{ 27 | Timeout: 5000, 28 | } 29 | // 2.配置command 30 | hystrix.ConfigureCommand("getProds", configA) 31 | // 3.执行Do方法 32 | var prodRes *models.ProdListResponse 33 | err = hystrix.Do("getProds", func() error { 34 | prodRes, err = prodService.GetProdList(context.Background(), &prodReq) 35 | return err 36 | }, nil) 37 | if err != nil { 38 | c.JSON(500, gin.H{"status": err.Error()}) 39 | } else { 40 | c.JSON(200, gin.H{"data": prodRes.Data}) 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /p17/grpc_client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 装饰器的使用 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "gomicro_note/p17/grpc_client/routers" 9 | "gomicro_note/p17/models" 10 | 11 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 12 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 13 | "github.com/asim/go-micro/v3" 14 | "github.com/asim/go-micro/v3/client" 15 | "github.com/asim/go-micro/v3/metadata" 16 | "github.com/asim/go-micro/v3/registry" 17 | "github.com/asim/go-micro/v3/server" 18 | ) 19 | 20 | type logWrapper struct { 21 | client.Client 22 | } 23 | 24 | func (l *logWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 25 | md, _ := metadata.FromContext(ctx) 26 | fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Endpoint()) 27 | return l.Client.Call(ctx, req, rsp) 28 | } 29 | 30 | func newLogWrapper(c client.Client) client.Client { 31 | return &logWrapper{c} 32 | } 33 | 34 | func main() { 35 | 36 | etcdReg := etcd.NewRegistry( 37 | registry.Addrs("127.0.0.1:2379"), 38 | ) 39 | 40 | myService := micro.NewService( 41 | micro.Name("ProdService.client"), 42 | micro.WrapClient(newLogWrapper), 43 | ) 44 | prodService := models.NewProdService("ProdService", myService.Client()) 45 | 46 | service := httpServer.NewServer( 47 | server.Name("ProdService.client"), 48 | server.Address(":9000"), 49 | ) 50 | 51 | hd := service.NewHandler(routers.InitRouter(prodService)) 52 | service.Handle(hd) 53 | 54 | srv := micro.NewService( 55 | micro.Server(service), 56 | micro.Registry(etcdReg), 57 | ) 58 | 59 | srv.Init() 60 | srv.Run() 61 | } 62 | -------------------------------------------------------------------------------- /p17/grpc_client/middlewares/middleware.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "gomicro_note/p17/models" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // InitMiddleware 注入prodService中间件 10 | func InitMiddleware(prodService models.ProdService) gin.HandlerFunc { 11 | return func(c *gin.Context) { 12 | c.Keys = make(map[string]interface{}) 13 | c.Keys["prodservice"] = prodService 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /p17/grpc_client/routers/router.go: -------------------------------------------------------------------------------- 1 | package routers 2 | 3 | import ( 4 | "gomicro_note/p17/grpc_client/handlers" 5 | "gomicro_note/p17/grpc_client/middlewares" 6 | "gomicro_note/p17/models" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // InitRouter 路由 12 | func InitRouter(prodService models.ProdService) *gin.Engine { 13 | r := gin.Default() 14 | r.Use(middlewares.InitMiddleware(prodService)) 15 | v1Group := r.Group("/v1") 16 | { 17 | v1Group.Handle("POST", "/prods", handlers.GetProdList) 18 | } 19 | return r 20 | } 21 | -------------------------------------------------------------------------------- /p17/grpc_server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p17/grpc_server/prods" 5 | "gomicro_note/p17/models" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | ) 11 | 12 | func main() { 13 | 14 | etcdReg := etcd.NewRegistry( 15 | registry.Addrs("127.0.0.1:2379"), 16 | ) 17 | 18 | app := micro.NewService( 19 | micro.Name("ProdService"), 20 | micro.Address(":8000"), 21 | micro.Registry(etcdReg), 22 | ) 23 | 24 | app.Init() 25 | err := models.RegisterProdServiceHandler(app.Server(), new(prods.ProdService)) 26 | if err != nil { 27 | panic(err) 28 | } 29 | app.Run() 30 | } 31 | -------------------------------------------------------------------------------- /p17/grpc_server/prods/prodService.go: -------------------------------------------------------------------------------- 1 | package prods 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p17/models" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | // ProdService 商品服务 11 | type ProdService struct{} 12 | 13 | func newProd(id int32, pname string) *models.ProdModel { 14 | return &models.ProdModel{ProdId: id, ProdName: pname} 15 | } 16 | 17 | // GetProdList 返回商品列表 18 | func (*ProdService) GetProdList(ctx context.Context, in *models.ProdRequest, res *models.ProdListResponse) error { 19 | // 超时测试 20 | time.Sleep(time.Second * 3) 21 | models := make([]*models.ProdModel, 0) 22 | var i int32 23 | for i = 0; i < in.Size; i++ { 24 | models = append(models, newProd(100+i, "prodName"+strconv.Itoa(100+int(i)))) 25 | } 26 | res.Data = models 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /p17/models/prodService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prodService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for ProdService service 37 | 38 | func NewProdServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for ProdService service 43 | 44 | type ProdService interface { 45 | GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) 46 | } 47 | 48 | type prodService struct { 49 | c client.Client 50 | name string 51 | } 52 | 53 | func NewProdService(name string, c client.Client) ProdService { 54 | return &prodService{ 55 | c: c, 56 | name: name, 57 | } 58 | } 59 | 60 | func (c *prodService) GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) { 61 | req := c.c.NewRequest(c.name, "ProdService.GetProdList", in) 62 | out := new(ProdListResponse) 63 | err := c.c.Call(ctx, req, out, opts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | // Server API for ProdService service 71 | 72 | type ProdServiceHandler interface { 73 | GetProdList(context.Context, *ProdRequest, *ProdListResponse) error 74 | } 75 | 76 | func RegisterProdServiceHandler(s server.Server, hdlr ProdServiceHandler, opts ...server.HandlerOption) error { 77 | type prodService interface { 78 | GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error 79 | } 80 | type ProdService struct { 81 | prodService 82 | } 83 | h := &prodServiceHandler{hdlr} 84 | return s.Handle(s.NewHandler(&ProdService{h}, opts...)) 85 | } 86 | 87 | type prodServiceHandler struct { 88 | ProdServiceHandler 89 | } 90 | 91 | func (h *prodServiceHandler) GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error { 92 | return h.ProdServiceHandler.GetProdList(ctx, in, out) 93 | } 94 | -------------------------------------------------------------------------------- /p17/models/protos/prodService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package models; 3 | 4 | option go_package = "./models"; 5 | 6 | // 商品模型 7 | message ProdModel{ 8 | // @inject_tag: json:"pid" 9 | int32 ProdId = 1; 10 | // @inject_tag: json:"pname" 11 | string ProdName = 2; 12 | } 13 | 14 | message ProdRequest{ 15 | // @inject_tag: json:"size" form:"size" 16 | int32 size = 1; 17 | } 18 | 19 | message ProdListResponse{ 20 | repeated ProdModel data = 1; 21 | } 22 | 23 | service ProdService{ 24 | rpc GetProdList(ProdRequest) returns (ProdListResponse); 25 | } -------------------------------------------------------------------------------- /p18/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/prodService.proto && \ 4 | protoc-go-inject-tag --input=./models/prodService.pb.go 5 | -------------------------------------------------------------------------------- /p18/grpc_client/handlers/handler.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p18/models" 6 | "strconv" 7 | 8 | "github.com/afex/hystrix-go/hystrix" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func newProd(id int32, pname string) *models.ProdModel { 13 | return &models.ProdModel{ProdId: id, ProdName: pname} 14 | } 15 | 16 | func defaultProds() (*models.ProdListResponse, error) { 17 | model := make([]*models.ProdModel, 0) 18 | var i int32 19 | for i = 0; i < 5; i++ { 20 | model = append(model, newProd(20+i, "prodName"+strconv.Itoa(20+int(i)))) 21 | } 22 | res := &models.ProdListResponse{} 23 | res.Data = model 24 | return res, nil 25 | } 26 | 27 | // GetProdList 显示商品列表 28 | func GetProdList(c *gin.Context) { 29 | prodService := c.Keys["prodservice"].(models.ProdService) 30 | var prodReq models.ProdRequest 31 | err := c.Bind(&prodReq) 32 | if err != nil { 33 | c.JSON(500, gin.H{ 34 | "status": err.Error()}) 35 | } else { 36 | // 超时代码 37 | // 1.配置config 38 | configA := hystrix.CommandConfig{ 39 | Timeout: 1000, 40 | } 41 | // 2.配置command 42 | hystrix.ConfigureCommand("getProds", configA) 43 | // 3.执行Do方法 44 | var prodRes *models.ProdListResponse 45 | err := hystrix.Do("getProds", func() error { 46 | prodRes, err = prodService.GetProdList(context.Background(), &prodReq) 47 | return err 48 | }, func(e error) error { 49 | // 降级 显示默认产品 50 | prodRes, err = defaultProds() 51 | return err 52 | }) 53 | if err != nil { 54 | c.JSON(500, gin.H{"status": err.Error()}) 55 | } else { 56 | c.JSON(200, gin.H{"data": prodRes.Data}) 57 | } 58 | 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /p18/grpc_client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 降级的使用 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "gomicro_note/p18/grpc_client/routers" 9 | "gomicro_note/p18/models" 10 | 11 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 12 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 13 | "github.com/asim/go-micro/v3" 14 | "github.com/asim/go-micro/v3/client" 15 | "github.com/asim/go-micro/v3/metadata" 16 | "github.com/asim/go-micro/v3/registry" 17 | "github.com/asim/go-micro/v3/server" 18 | ) 19 | 20 | type logWrapper struct { 21 | client.Client 22 | } 23 | 24 | func (l *logWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 25 | md, _ := metadata.FromContext(ctx) 26 | fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Endpoint()) 27 | return l.Client.Call(ctx, req, rsp) 28 | } 29 | 30 | func newLogWrapper(c client.Client) client.Client { 31 | return &logWrapper{c} 32 | } 33 | 34 | func main() { 35 | 36 | etcdReg := etcd.NewRegistry( 37 | registry.Addrs("127.0.0.1:2379"), 38 | ) 39 | 40 | myService := micro.NewService( 41 | micro.Name("ProdService.client"), 42 | micro.WrapClient(newLogWrapper), 43 | ) 44 | prodService := models.NewProdService("ProdService", myService.Client()) 45 | 46 | service := httpServer.NewServer( 47 | server.Name("ProdService.client"), 48 | server.Address(":9000"), 49 | server.Registry(etcdReg), 50 | ) 51 | 52 | hd := service.NewHandler(routers.InitRouter(prodService)) 53 | service.Handle(hd) 54 | 55 | srv := micro.NewService( 56 | micro.Server(service), 57 | ) 58 | 59 | srv.Init() 60 | srv.Run() 61 | } 62 | -------------------------------------------------------------------------------- /p18/grpc_client/middlewares/middleware.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "gomicro_note/p18/models" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // InitMiddleware 注入prodService中间件 10 | func InitMiddleware(prodService models.ProdService) gin.HandlerFunc { 11 | return func(c *gin.Context) { 12 | c.Keys = make(map[string]interface{}) 13 | c.Keys["prodservice"] = prodService 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /p18/grpc_client/routers/router.go: -------------------------------------------------------------------------------- 1 | package routers 2 | 3 | import ( 4 | "gomicro_note/p18/grpc_client/handlers" 5 | "gomicro_note/p18/grpc_client/middlewares" 6 | "gomicro_note/p18/models" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // InitRouter 路由 12 | func InitRouter(prodService models.ProdService) *gin.Engine { 13 | r := gin.Default() 14 | r.Use(middlewares.InitMiddleware(prodService)) 15 | v1Group := r.Group("/v1") 16 | { 17 | v1Group.Handle("POST", "/prods", handlers.GetProdList) 18 | } 19 | return r 20 | } 21 | -------------------------------------------------------------------------------- /p18/grpc_server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p18/grpc_server/prods" 5 | "gomicro_note/p18/models" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | ) 11 | 12 | func main() { 13 | 14 | etcdReg := etcd.NewRegistry( 15 | registry.Addrs("127.0.0.1:2379"), 16 | ) 17 | 18 | app := micro.NewService( 19 | micro.Name("ProdService"), 20 | micro.Address(":8000"), 21 | micro.Registry(etcdReg), 22 | ) 23 | 24 | app.Init() 25 | err := models.RegisterProdServiceHandler(app.Server(), new(prods.ProdService)) 26 | if err != nil { 27 | panic(err) 28 | } 29 | app.Run() 30 | } 31 | -------------------------------------------------------------------------------- /p18/grpc_server/prods/prodService.go: -------------------------------------------------------------------------------- 1 | package prods 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p18/models" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | // ProdService 商品服务 11 | type ProdService struct{} 12 | 13 | func newProd(id int32, pname string) *models.ProdModel { 14 | return &models.ProdModel{ProdId: id, ProdName: pname} 15 | } 16 | 17 | // GetProdList 返回商品列表 18 | func (*ProdService) GetProdList(ctx context.Context, in *models.ProdRequest, res *models.ProdListResponse) error { 19 | // 超时测试 20 | time.Sleep(time.Second * 3) 21 | models := make([]*models.ProdModel, 0) 22 | var i int32 23 | for i = 0; i < in.Size; i++ { 24 | models = append(models, newProd(100+i, "prodName"+strconv.Itoa(100+int(i)))) 25 | } 26 | res.Data = models 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /p18/models/prodService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prodService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for ProdService service 37 | 38 | func NewProdServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for ProdService service 43 | 44 | type ProdService interface { 45 | GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) 46 | } 47 | 48 | type prodService struct { 49 | c client.Client 50 | name string 51 | } 52 | 53 | func NewProdService(name string, c client.Client) ProdService { 54 | return &prodService{ 55 | c: c, 56 | name: name, 57 | } 58 | } 59 | 60 | func (c *prodService) GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) { 61 | req := c.c.NewRequest(c.name, "ProdService.GetProdList", in) 62 | out := new(ProdListResponse) 63 | err := c.c.Call(ctx, req, out, opts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | // Server API for ProdService service 71 | 72 | type ProdServiceHandler interface { 73 | GetProdList(context.Context, *ProdRequest, *ProdListResponse) error 74 | } 75 | 76 | func RegisterProdServiceHandler(s server.Server, hdlr ProdServiceHandler, opts ...server.HandlerOption) error { 77 | type prodService interface { 78 | GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error 79 | } 80 | type ProdService struct { 81 | prodService 82 | } 83 | h := &prodServiceHandler{hdlr} 84 | return s.Handle(s.NewHandler(&ProdService{h}, opts...)) 85 | } 86 | 87 | type prodServiceHandler struct { 88 | ProdServiceHandler 89 | } 90 | 91 | func (h *prodServiceHandler) GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error { 92 | return h.ProdServiceHandler.GetProdList(ctx, in, out) 93 | } 94 | -------------------------------------------------------------------------------- /p18/models/protos/prodService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package models; 3 | 4 | option go_package = "./models"; 5 | 6 | // 商品模型 7 | message ProdModel{ 8 | // @inject_tag: json:"pid" 9 | int32 ProdId = 1; 10 | // @inject_tag: json:"pname" 11 | string ProdName = 2; 12 | } 13 | 14 | message ProdRequest{ 15 | int32 size = 1; 16 | } 17 | 18 | message ProdListResponse{ 19 | repeated ProdModel data = 1; 20 | } 21 | 22 | service ProdService{ 23 | rpc GetProdList(ProdRequest) returns (ProdListResponse); 24 | } -------------------------------------------------------------------------------- /p19/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/prodService.proto && \ 4 | protoc-go-inject-tag --input=./models/prodService.pb.go -------------------------------------------------------------------------------- /p19/grpc_client/handlers/handler.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p19/models" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | // GetProdList 显示商品列表 11 | func GetProdList(c *gin.Context) { 12 | prodService := c.Keys["prodservice"].(models.ProdService) 13 | var prodReq models.ProdRequest 14 | err := c.Bind(&prodReq) 15 | if err != nil { 16 | c.JSON(500, gin.H{ 17 | "status": err.Error()}) 18 | } else { 19 | prodRes, _ := prodService.GetProdList(context.Background(), &prodReq) 20 | 21 | c.JSON(200, gin.H{"data": prodRes.Data}) 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /p19/grpc_client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 降级的使用 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "gomicro_note/p19/grpc_client/routers" 9 | "gomicro_note/p19/grpc_client/wrappers" 10 | "gomicro_note/p19/models" 11 | 12 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 13 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 14 | "github.com/asim/go-micro/v3" 15 | "github.com/asim/go-micro/v3/client" 16 | "github.com/asim/go-micro/v3/metadata" 17 | "github.com/asim/go-micro/v3/registry" 18 | "github.com/asim/go-micro/v3/server" 19 | ) 20 | 21 | type logWrapper struct { 22 | client.Client 23 | } 24 | 25 | func (l *logWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 26 | md, _ := metadata.FromContext(ctx) 27 | fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Endpoint()) 28 | return l.Client.Call(ctx, req, rsp) 29 | } 30 | 31 | func newLogWrapper(c client.Client) client.Client { 32 | return &logWrapper{c} 33 | } 34 | 35 | func main() { 36 | 37 | etcdReg := etcd.NewRegistry( 38 | registry.Addrs("127.0.0.1:2379"), 39 | ) 40 | 41 | myService := micro.NewService( 42 | micro.Name("ProdService.client"), 43 | micro.WrapClient(newLogWrapper), 44 | micro.WrapClient(wrappers.NewProdsWrapper), 45 | ) 46 | prodService := models.NewProdService("ProdService", myService.Client()) 47 | 48 | service := httpServer.NewServer( 49 | server.Name("ProdService.client"), 50 | server.Address(":9000"), 51 | server.Registry(etcdReg), 52 | ) 53 | 54 | hd := service.NewHandler(routers.InitRouter(prodService)) 55 | service.Handle(hd) 56 | 57 | srv := micro.NewService( 58 | micro.Server(service), 59 | ) 60 | 61 | srv.Init() 62 | srv.Run() 63 | } 64 | -------------------------------------------------------------------------------- /p19/grpc_client/middlewares/middleware.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "gomicro_note/p19/models" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // InitMiddleware 注入prodService中间件 10 | func InitMiddleware(prodService models.ProdService) gin.HandlerFunc { 11 | return func(c *gin.Context) { 12 | c.Keys = make(map[string]interface{}) 13 | c.Keys["prodservice"] = prodService 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /p19/grpc_client/routers/router.go: -------------------------------------------------------------------------------- 1 | package routers 2 | 3 | import ( 4 | "gomicro_note/p19/grpc_client/handlers" 5 | "gomicro_note/p19/grpc_client/middlewares" 6 | "gomicro_note/p19/models" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // InitRouter 路由 12 | func InitRouter(prodService models.ProdService) *gin.Engine { 13 | r := gin.Default() 14 | r.Use(middlewares.InitMiddleware(prodService)) 15 | v1Group := r.Group("/v1") 16 | { 17 | v1Group.Handle("POST", "/prods", handlers.GetProdList) 18 | } 19 | return r 20 | } 21 | -------------------------------------------------------------------------------- /p19/grpc_client/wrappers/prodsWrapper.go: -------------------------------------------------------------------------------- 1 | package wrappers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p19/models" 6 | "strconv" 7 | 8 | "github.com/afex/hystrix-go/hystrix" 9 | "github.com/asim/go-micro/v3/client" 10 | ) 11 | 12 | func newProd(id int32, pname string) *models.ProdModel { 13 | return &models.ProdModel{ProdId: id, ProdName: pname} 14 | } 15 | 16 | func defaultProds(rsp interface{}) (*models.ProdListResponse, error) { 17 | model := make([]*models.ProdModel, 0) 18 | var i int32 19 | for i = 0; i < 5; i++ { 20 | model = append(model, newProd(20+i, "prodName"+strconv.Itoa(20+int(i)))) 21 | } 22 | res := rsp.(*models.ProdListResponse) 23 | res.Data = model 24 | return res, nil 25 | } 26 | 27 | // ProdsWrapper 商品装饰器 28 | type ProdsWrapper struct { 29 | client.Client 30 | } 31 | 32 | // Call 调用方法 33 | func (p *ProdsWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 34 | cmdName := req.Service() + "." + req.Endpoint() 35 | configA := hystrix.CommandConfig{Timeout: 1000} 36 | hystrix.ConfigureCommand(cmdName, configA) 37 | return hystrix.Do(cmdName, func() error { 38 | return p.Client.Call(ctx, req, rsp) 39 | }, func(e error) error { 40 | defaultProds(rsp) 41 | return nil 42 | }) 43 | return p.Client.Call(ctx, req, rsp) 44 | } 45 | 46 | // NewProdsWrapper 初始化一个商品装饰器 47 | func NewProdsWrapper(c client.Client) client.Client { 48 | return &ProdsWrapper{c} 49 | } 50 | -------------------------------------------------------------------------------- /p19/grpc_server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p19/grpc_server/prods" 5 | "gomicro_note/p19/models" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | ) 11 | 12 | func main() { 13 | 14 | etcdReg := etcd.NewRegistry( 15 | registry.Addrs("127.0.0.1:2379"), 16 | ) 17 | 18 | app := micro.NewService( 19 | micro.Name("ProdService"), 20 | micro.Address(":8000"), 21 | micro.Registry(etcdReg), 22 | ) 23 | 24 | app.Init() 25 | err := models.RegisterProdServiceHandler(app.Server(), new(prods.ProdService)) 26 | if err != nil { 27 | panic(err) 28 | } 29 | app.Run() 30 | } 31 | -------------------------------------------------------------------------------- /p19/grpc_server/prods/prodService.go: -------------------------------------------------------------------------------- 1 | package prods 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p19/models" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | // ProdService 商品服务 11 | type ProdService struct{} 12 | 13 | func newProd(id int32, pname string) *models.ProdModel { 14 | return &models.ProdModel{ProdId: id, ProdName: pname} 15 | } 16 | 17 | // GetProdList 返回商品列表 18 | func (*ProdService) GetProdList(ctx context.Context, in *models.ProdRequest, res *models.ProdListResponse) error { 19 | // 超时测试 20 | time.Sleep(time.Second * 3) 21 | models := make([]*models.ProdModel, 0) 22 | var i int32 23 | for i = 0; i < in.Size; i++ { 24 | models = append(models, newProd(100+i, "prodName"+strconv.Itoa(100+int(i)))) 25 | } 26 | res.Data = models 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /p19/models/prodService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prodService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for ProdService service 37 | 38 | func NewProdServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for ProdService service 43 | 44 | type ProdService interface { 45 | GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) 46 | } 47 | 48 | type prodService struct { 49 | c client.Client 50 | name string 51 | } 52 | 53 | func NewProdService(name string, c client.Client) ProdService { 54 | return &prodService{ 55 | c: c, 56 | name: name, 57 | } 58 | } 59 | 60 | func (c *prodService) GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) { 61 | req := c.c.NewRequest(c.name, "ProdService.GetProdList", in) 62 | out := new(ProdListResponse) 63 | err := c.c.Call(ctx, req, out, opts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | // Server API for ProdService service 71 | 72 | type ProdServiceHandler interface { 73 | GetProdList(context.Context, *ProdRequest, *ProdListResponse) error 74 | } 75 | 76 | func RegisterProdServiceHandler(s server.Server, hdlr ProdServiceHandler, opts ...server.HandlerOption) error { 77 | type prodService interface { 78 | GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error 79 | } 80 | type ProdService struct { 81 | prodService 82 | } 83 | h := &prodServiceHandler{hdlr} 84 | return s.Handle(s.NewHandler(&ProdService{h}, opts...)) 85 | } 86 | 87 | type prodServiceHandler struct { 88 | ProdServiceHandler 89 | } 90 | 91 | func (h *prodServiceHandler) GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error { 92 | return h.ProdServiceHandler.GetProdList(ctx, in, out) 93 | } 94 | -------------------------------------------------------------------------------- /p19/models/protos/prodService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package models; 3 | 4 | option go_package = "./models"; 5 | 6 | // 商品模型 7 | message ProdModel{ 8 | // @inject_tag: json:"pid" 9 | int32 ProdId = 1; 10 | // @inject_tag: json:"pname" 11 | string ProdName = 2; 12 | } 13 | 14 | message ProdRequest{ 15 | int32 size = 1; 16 | } 17 | 18 | message ProdListResponse{ 19 | repeated ProdModel data = 1; 20 | } 21 | 22 | service ProdService{ 23 | rpc GetProdList(ProdRequest) returns (ProdListResponse); 24 | } -------------------------------------------------------------------------------- /p2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | 7 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/server" 10 | "github.com/gin-gonic/gin" 11 | ) 12 | 13 | // 使用gin框架 14 | 15 | func main() { 16 | r := gin.Default() 17 | r.Handle("GET", "/", func(c *gin.Context) { 18 | c.JSON(http.StatusOK, gin.H{ 19 | "code": http.StatusOK, 20 | }) 21 | }) 22 | service := httpServer.NewServer( 23 | server.Name("demo_service"), 24 | server.Address(":8000"), 25 | ) 26 | hd := service.NewHandler(r) 27 | service.Handle(hd) 28 | srv := micro.NewService( 29 | micro.Server(service), 30 | ) 31 | srv.Init() 32 | if err := srv.Run(); err != nil { 33 | log.Print(err.Error()) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /p20/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/prodService.proto && \ 4 | protoc-go-inject-tag --input=./models/prodService.pb.go 5 | -------------------------------------------------------------------------------- /p20/grpc_client/handlers/handler.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p20/models" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | // PanicIfError panic异常处理 11 | func PanicIfError(err error) { 12 | if err != nil { 13 | panic(err) 14 | } 15 | } 16 | 17 | // GetProdDetail 显示商品详情 18 | func GetProdDetail(c *gin.Context) { 19 | var prodReq models.ProdRequest 20 | PanicIfError(c.BindUri(&prodReq)) 21 | prodService := c.Keys["prodservice"].(models.ProdService) 22 | res, _ := prodService.GetProdDetail(context.Background(), &prodReq) 23 | 24 | c.JSON(200, gin.H{"data": res.Data}) 25 | } 26 | 27 | // GetProdList 显示商品列表 28 | func GetProdList(c *gin.Context) { 29 | prodService := c.Keys["prodservice"].(models.ProdService) 30 | var prodReq models.ProdRequest 31 | err := c.Bind(&prodReq) 32 | if err != nil { 33 | c.JSON(500, gin.H{ 34 | "status": err.Error()}) 35 | } else { 36 | prodRes, _ := prodService.GetProdList(context.Background(), &prodReq) 37 | 38 | c.JSON(200, gin.H{"data": prodRes.Data}) 39 | 40 | // 超时代码 41 | // 1.配置config 42 | //configA := hystrix.CommandConfig{ 43 | // Timeout: 1000, 44 | //} 45 | //// 2.配置command 46 | //hystrix.ConfigureCommand("getProds", configA) 47 | //// 3.执行Do方法 48 | //var prodRes *models.ProdListResponse 49 | //err := hystrix.Do("getProds", func() error { 50 | // prodRes, err = prodService.GetProdList(context.Background(), &prodReq) 51 | // return err 52 | //}, func(e error) error { 53 | // // 降级 显示默认产品 54 | // prodRes, err = defaultProds() 55 | // return err 56 | //}) 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /p20/grpc_client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 降级的使用 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "gomicro_note/p20/grpc_client/routers" 9 | "gomicro_note/p20/grpc_client/wrappers" 10 | "gomicro_note/p20/models" 11 | 12 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 13 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 14 | "github.com/asim/go-micro/v3" 15 | "github.com/asim/go-micro/v3/client" 16 | "github.com/asim/go-micro/v3/metadata" 17 | "github.com/asim/go-micro/v3/registry" 18 | "github.com/asim/go-micro/v3/server" 19 | ) 20 | 21 | type logWrapper struct { 22 | client.Client 23 | } 24 | 25 | func (l *logWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 26 | md, _ := metadata.FromContext(ctx) 27 | fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Endpoint()) 28 | return l.Client.Call(ctx, req, rsp) 29 | } 30 | 31 | func newLogWrapper(c client.Client) client.Client { 32 | return &logWrapper{c} 33 | } 34 | 35 | func main() { 36 | 37 | etcdReg := etcd.NewRegistry( 38 | registry.Addrs("127.0.0.1:2379"), 39 | ) 40 | 41 | myService := micro.NewService( 42 | micro.Name("ProdService.client"), 43 | micro.WrapClient(newLogWrapper), 44 | micro.WrapClient(wrappers.NewProdsWrapper), 45 | ) 46 | prodService := models.NewProdService("ProdService", myService.Client()) 47 | 48 | service := httpServer.NewServer( 49 | server.Name("ProdService.client"), 50 | server.Address(":9000"), 51 | server.Registry(etcdReg), 52 | ) 53 | 54 | hd := service.NewHandler(routers.InitRouter(prodService)) 55 | service.Handle(hd) 56 | 57 | srv := micro.NewService( 58 | micro.Server(service), 59 | ) 60 | 61 | srv.Init() 62 | srv.Run() 63 | } 64 | -------------------------------------------------------------------------------- /p20/grpc_client/middlewares/middleware.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "fmt" 5 | "gomicro_note/p20/models" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | // InitMiddleware 注入prodService中间件 11 | func InitMiddleware(prodService models.ProdService) gin.HandlerFunc { 12 | return func(c *gin.Context) { 13 | c.Keys = make(map[string]interface{}) 14 | c.Keys["prodservice"] = prodService 15 | } 16 | } 17 | 18 | // ErrorMiddleware 异常处理 19 | func ErrorMiddleware() gin.HandlerFunc { 20 | return func(c *gin.Context) { 21 | defer func() { 22 | if r := recover(); r != nil { 23 | c.JSON(500, gin.H{"status": fmt.Sprintf("%s", r)}) 24 | c.Abort() 25 | } 26 | }() 27 | c.Next() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /p20/grpc_client/routers/router.go: -------------------------------------------------------------------------------- 1 | package routers 2 | 3 | import ( 4 | "gomicro_note/p20/grpc_client/handlers" 5 | "gomicro_note/p20/grpc_client/middlewares" 6 | "gomicro_note/p20/models" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // InitRouter 路由 12 | func InitRouter(prodService models.ProdService) *gin.Engine { 13 | r := gin.Default() 14 | r.Use(middlewares.InitMiddleware(prodService), middlewares.ErrorMiddleware()) 15 | v1Group := r.Group("/v1") 16 | { 17 | v1Group.Handle("POST", "/prods", handlers.GetProdList) 18 | v1Group.Handle("GET", "/prods/:pid", handlers.GetProdDetail) 19 | } 20 | return r 21 | } 22 | -------------------------------------------------------------------------------- /p20/grpc_client/wrappers/prodsWrapper.go: -------------------------------------------------------------------------------- 1 | package wrappers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p20/models" 6 | "strconv" 7 | 8 | "github.com/afex/hystrix-go/hystrix" 9 | "github.com/asim/go-micro/v3/client" 10 | ) 11 | 12 | func newProd(id int32, pname string) *models.ProdModel { 13 | return &models.ProdModel{ProdId: id, ProdName: pname} 14 | } 15 | 16 | func defaultProds(rsp interface{}) (*models.ProdListResponse, error) { 17 | model := make([]*models.ProdModel, 0) 18 | var i int32 19 | for i = 0; i < 5; i++ { 20 | model = append(model, newProd(20+i, "prodName"+strconv.Itoa(20+int(i)))) 21 | } 22 | res := rsp.(*models.ProdListResponse) 23 | res.Data = model 24 | return res, nil 25 | } 26 | 27 | // ProdsWrapper 商品装饰器 28 | type ProdsWrapper struct { 29 | client.Client 30 | } 31 | 32 | // Call 调用方法 33 | func (p *ProdsWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 34 | cmdName := req.Service() + "." + req.Endpoint() 35 | configA := hystrix.CommandConfig{Timeout: 1000} 36 | hystrix.ConfigureCommand(cmdName, configA) 37 | return hystrix.Do(cmdName, func() error { 38 | return p.Client.Call(ctx, req, rsp) 39 | }, func(e error) error { 40 | defaultProds(rsp) 41 | return nil 42 | }) 43 | return p.Client.Call(ctx, req, rsp) 44 | } 45 | 46 | // NewProdsWrapper 初始化一个商品装饰器 47 | func NewProdsWrapper(c client.Client) client.Client { 48 | return &ProdsWrapper{c} 49 | } 50 | -------------------------------------------------------------------------------- /p20/grpc_server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p20/grpc_server/prods" 5 | "gomicro_note/p20/models" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | ) 11 | 12 | func main() { 13 | 14 | etcdReg := etcd.NewRegistry( 15 | registry.Addrs("127.0.0.1:2379"), 16 | ) 17 | 18 | app := micro.NewService( 19 | micro.Name("ProdService"), 20 | micro.Address(":8000"), 21 | micro.Registry(etcdReg), 22 | ) 23 | 24 | app.Init() 25 | err := models.RegisterProdServiceHandler(app.Server(), new(prods.ProdService)) 26 | if err != nil { 27 | panic(err) 28 | } 29 | app.Run() 30 | } 31 | -------------------------------------------------------------------------------- /p20/grpc_server/prods/prodService.go: -------------------------------------------------------------------------------- 1 | package prods 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p20/models" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | // ProdService 商品服务 11 | type ProdService struct{} 12 | 13 | func newProd(id int32, pname string) *models.ProdModel { 14 | return &models.ProdModel{ProdId: id, ProdName: pname} 15 | } 16 | 17 | // GetProdList 返回商品列表 18 | func (*ProdService) GetProdList(ctx context.Context, in *models.ProdRequest, res *models.ProdListResponse) error { 19 | // 超时测试 20 | time.Sleep(time.Second * 3) 21 | models := make([]*models.ProdModel, 0) 22 | var i int32 23 | for i = 0; i < in.Size; i++ { 24 | models = append(models, newProd(100+i, "prodName"+strconv.Itoa(100+int(i)))) 25 | } 26 | res.Data = models 27 | return nil 28 | } 29 | 30 | // GetProdDetail 获取单个商品 31 | func (*ProdService) GetProdDetail(ctx context.Context, in *models.ProdRequest, res *models.ProdDetailResponse) error { 32 | res.Data = newProd(in.ProdId, "测试商品") 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /p20/models/prodService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prodService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for ProdService service 37 | 38 | func NewProdServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for ProdService service 43 | 44 | type ProdService interface { 45 | GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) 46 | GetProdDetail(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdDetailResponse, error) 47 | } 48 | 49 | type prodService struct { 50 | c client.Client 51 | name string 52 | } 53 | 54 | func NewProdService(name string, c client.Client) ProdService { 55 | return &prodService{ 56 | c: c, 57 | name: name, 58 | } 59 | } 60 | 61 | func (c *prodService) GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) { 62 | req := c.c.NewRequest(c.name, "ProdService.GetProdList", in) 63 | out := new(ProdListResponse) 64 | err := c.c.Call(ctx, req, out, opts...) 65 | if err != nil { 66 | return nil, err 67 | } 68 | return out, nil 69 | } 70 | 71 | func (c *prodService) GetProdDetail(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdDetailResponse, error) { 72 | req := c.c.NewRequest(c.name, "ProdService.GetProdDetail", in) 73 | out := new(ProdDetailResponse) 74 | err := c.c.Call(ctx, req, out, opts...) 75 | if err != nil { 76 | return nil, err 77 | } 78 | return out, nil 79 | } 80 | 81 | // Server API for ProdService service 82 | 83 | type ProdServiceHandler interface { 84 | GetProdList(context.Context, *ProdRequest, *ProdListResponse) error 85 | GetProdDetail(context.Context, *ProdRequest, *ProdDetailResponse) error 86 | } 87 | 88 | func RegisterProdServiceHandler(s server.Server, hdlr ProdServiceHandler, opts ...server.HandlerOption) error { 89 | type prodService interface { 90 | GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error 91 | GetProdDetail(ctx context.Context, in *ProdRequest, out *ProdDetailResponse) error 92 | } 93 | type ProdService struct { 94 | prodService 95 | } 96 | h := &prodServiceHandler{hdlr} 97 | return s.Handle(s.NewHandler(&ProdService{h}, opts...)) 98 | } 99 | 100 | type prodServiceHandler struct { 101 | ProdServiceHandler 102 | } 103 | 104 | func (h *prodServiceHandler) GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error { 105 | return h.ProdServiceHandler.GetProdList(ctx, in, out) 106 | } 107 | 108 | func (h *prodServiceHandler) GetProdDetail(ctx context.Context, in *ProdRequest, out *ProdDetailResponse) error { 109 | return h.ProdServiceHandler.GetProdDetail(ctx, in, out) 110 | } 111 | -------------------------------------------------------------------------------- /p20/models/protos/prodService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package models; 3 | 4 | option go_package = "./models"; 5 | 6 | // 商品模型 7 | message ProdModel{ 8 | // @inject_tag: json:"pid" 9 | int32 ProdId = 1; 10 | // @inject_tag: json:"pname" 11 | string ProdName = 2; 12 | } 13 | 14 | message ProdRequest{ 15 | // @inject_tag: json:"size", form:"size" 16 | int32 size = 1; 17 | // @inject_tag: uri:"pid" 18 | int32 prod_id =2; 19 | } 20 | 21 | message ProdListResponse{ 22 | repeated ProdModel data = 1; 23 | } 24 | 25 | message ProdDetailResponse{ 26 | ProdModel data = 1; 27 | } 28 | 29 | service ProdService{ 30 | rpc GetProdList(ProdRequest) returns (ProdListResponse); 31 | rpc GetProdDetail(ProdRequest) returns (ProdDetailResponse); 32 | } -------------------------------------------------------------------------------- /p21/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/prodService.proto && \ 4 | protoc-go-inject-tag --input=./models/prodService.pb.go 5 | -------------------------------------------------------------------------------- /p21/grpc_client/handlers/handler.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p21/models" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | // PanicIfError panic异常处理 11 | func PanicIfError(err error) { 12 | if err != nil { 13 | panic(err) 14 | } 15 | } 16 | 17 | // GetProdDetail 显示商品详情 18 | func GetProdDetail(c *gin.Context) { 19 | var prodReq models.ProdRequest 20 | PanicIfError(c.BindUri(&prodReq)) 21 | prodService := c.Keys["prodservice"].(models.ProdService) 22 | res, _ := prodService.GetProdDetail(context.Background(), &prodReq) 23 | 24 | c.JSON(200, gin.H{"data": res.Data}) 25 | } 26 | 27 | // GetProdList 显示商品列表 28 | func GetProdList(c *gin.Context) { 29 | prodService := c.Keys["prodservice"].(models.ProdService) 30 | var prodReq models.ProdRequest 31 | err := c.Bind(&prodReq) 32 | if err != nil { 33 | c.JSON(500, gin.H{ 34 | "status": err.Error()}) 35 | } else { 36 | prodRes, _ := prodService.GetProdList(context.Background(), &prodReq) 37 | 38 | c.JSON(200, gin.H{"data": prodRes.Data}) 39 | 40 | // 超时代码 41 | // 1.配置config 42 | //configA := hystrix.CommandConfig{ 43 | // Timeout: 1000, 44 | //} 45 | //// 2.配置command 46 | //hystrix.ConfigureCommand("getProds", configA) 47 | //// 3.执行Do方法 48 | //var prodRes *models.ProdListResponse 49 | //err := hystrix.Do("getProds", func() error { 50 | // prodRes, err = prodService.GetProdList(context.Background(), &prodReq) 51 | // return err 52 | //}, func(e error) error { 53 | // // 降级 显示默认产品 54 | // prodRes, err = defaultProds() 55 | // return err 56 | //}) 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /p21/grpc_client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 降级的使用 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "gomicro_note/p21/grpc_client/routers" 9 | "gomicro_note/p21/grpc_client/wrappers" 10 | "gomicro_note/p21/models" 11 | 12 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 13 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 14 | "github.com/asim/go-micro/v3" 15 | "github.com/asim/go-micro/v3/client" 16 | "github.com/asim/go-micro/v3/metadata" 17 | "github.com/asim/go-micro/v3/registry" 18 | "github.com/asim/go-micro/v3/server" 19 | ) 20 | 21 | type logWrapper struct { 22 | client.Client 23 | } 24 | 25 | func (l *logWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 26 | md, _ := metadata.FromContext(ctx) 27 | fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Endpoint()) 28 | return l.Client.Call(ctx, req, rsp) 29 | } 30 | 31 | func newLogWrapper(c client.Client) client.Client { 32 | return &logWrapper{c} 33 | } 34 | 35 | func main() { 36 | 37 | etcdReg := etcd.NewRegistry( 38 | registry.Addrs("127.0.0.1:2379"), 39 | ) 40 | 41 | myService := micro.NewService( 42 | micro.Name("ProdService.client"), 43 | micro.WrapClient(newLogWrapper), 44 | micro.WrapClient(wrappers.NewProdsWrapper), 45 | ) 46 | prodService := models.NewProdService("ProdService", myService.Client()) 47 | 48 | service := httpServer.NewServer( 49 | server.Name("ProdService.client"), 50 | server.Address(":9000"), 51 | server.Registry(etcdReg), 52 | ) 53 | 54 | hd := service.NewHandler(routers.InitRouter(prodService)) 55 | service.Handle(hd) 56 | 57 | srv := micro.NewService( 58 | micro.Server(service), 59 | ) 60 | 61 | srv.Init() 62 | srv.Run() 63 | } 64 | -------------------------------------------------------------------------------- /p21/grpc_client/middlewares/middleware.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "fmt" 5 | "gomicro_note/p21/models" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | // InitMiddleware 注入prodService中间件 11 | func InitMiddleware(prodService models.ProdService) gin.HandlerFunc { 12 | return func(c *gin.Context) { 13 | c.Keys = make(map[string]interface{}) 14 | c.Keys["prodservice"] = prodService 15 | } 16 | } 17 | 18 | // ErrorMiddleware 异常处理 19 | func ErrorMiddleware() gin.HandlerFunc { 20 | return func(c *gin.Context) { 21 | defer func() { 22 | if r := recover(); r != nil { 23 | c.JSON(500, gin.H{"status": fmt.Sprintf("%s", r)}) 24 | c.Abort() 25 | } 26 | }() 27 | c.Next() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /p21/grpc_client/routers/router.go: -------------------------------------------------------------------------------- 1 | package routers 2 | 3 | import ( 4 | "gomicro_note/p21/grpc_client/handlers" 5 | "gomicro_note/p21/grpc_client/middlewares" 6 | "gomicro_note/p21/models" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // InitRouter 路由 12 | func InitRouter(prodService models.ProdService) *gin.Engine { 13 | r := gin.Default() 14 | r.Use(middlewares.InitMiddleware(prodService), middlewares.ErrorMiddleware()) 15 | v1Group := r.Group("/v1") 16 | { 17 | v1Group.Handle("POST", "/prods", handlers.GetProdList) 18 | v1Group.Handle("GET", "/prods/:pid", handlers.GetProdDetail) 19 | } 20 | return r 21 | } 22 | -------------------------------------------------------------------------------- /p21/grpc_client/wrappers/prodsWrapper.go: -------------------------------------------------------------------------------- 1 | package wrappers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p21/models" 6 | "strconv" 7 | 8 | "github.com/afex/hystrix-go/hystrix" 9 | "github.com/asim/go-micro/v3/client" 10 | ) 11 | 12 | func newProd(id int32, pname string) *models.ProdModel { 13 | return &models.ProdModel{ProdId: id, ProdName: pname} 14 | } 15 | 16 | // 通用降级方法 17 | func defaultData(rsp interface{}) { 18 | switch t := rsp.(type) { 19 | case *models.ProdListResponse: 20 | defaultProds(rsp) 21 | case *models.ProdDetailResponse: 22 | t.Data = newProd(10, "降级商品") 23 | } 24 | } 25 | 26 | // 商品列表降级方法 27 | func defaultProds(rsp interface{}) (*models.ProdListResponse, error) { 28 | model := make([]*models.ProdModel, 0) 29 | var i int32 30 | for i = 0; i < 5; i++ { 31 | model = append(model, newProd(20+i, "prodName"+strconv.Itoa(20+int(i)))) 32 | } 33 | res := rsp.(*models.ProdListResponse) 34 | res.Data = model 35 | return res, nil 36 | } 37 | 38 | // ProdsWrapper 商品装饰器 39 | type ProdsWrapper struct { 40 | client.Client 41 | } 42 | 43 | // Call 调用方法 44 | func (p *ProdsWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 45 | cmdName := req.Service() + "." + req.Endpoint() 46 | configA := hystrix.CommandConfig{ 47 | Timeout: 1000, 48 | } 49 | hystrix.ConfigureCommand(cmdName, configA) 50 | return hystrix.Do(cmdName, func() error { 51 | return p.Client.Call(ctx, req, rsp) 52 | }, func(e error) error { 53 | defaultData(rsp) 54 | return nil 55 | }) 56 | return p.Client.Call(ctx, req, rsp) 57 | } 58 | 59 | // NewProdsWrapper 初始化一个商品装饰器 60 | func NewProdsWrapper(c client.Client) client.Client { 61 | return &ProdsWrapper{c} 62 | } 63 | -------------------------------------------------------------------------------- /p21/grpc_server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p21/grpc_server/prods" 5 | "gomicro_note/p21/models" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | ) 11 | 12 | func main() { 13 | 14 | etcdReg := etcd.NewRegistry( 15 | registry.Addrs("127.0.0.1:2379"), 16 | ) 17 | 18 | app := micro.NewService( 19 | micro.Name("ProdService"), 20 | micro.Address(":8000"), 21 | micro.Registry(etcdReg), 22 | ) 23 | 24 | app.Init() 25 | err := models.RegisterProdServiceHandler(app.Server(), new(prods.ProdService)) 26 | if err != nil { 27 | panic(err) 28 | } 29 | app.Run() 30 | } 31 | -------------------------------------------------------------------------------- /p21/grpc_server/prods/prodService.go: -------------------------------------------------------------------------------- 1 | package prods 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p21/models" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | // ProdService 商品服务 11 | type ProdService struct{} 12 | 13 | func newProd(id int32, pname string) *models.ProdModel { 14 | return &models.ProdModel{ProdId: id, ProdName: pname} 15 | } 16 | 17 | // GetProdList 返回商品列表 18 | func (*ProdService) GetProdList(ctx context.Context, in *models.ProdRequest, res *models.ProdListResponse) error { 19 | // 超时测试 20 | time.Sleep(time.Second * 3) 21 | models := make([]*models.ProdModel, 0) 22 | var i int32 23 | for i = 0; i < in.Size; i++ { 24 | models = append(models, newProd(100+i, "prodName"+strconv.Itoa(100+int(i)))) 25 | } 26 | res.Data = models 27 | return nil 28 | } 29 | 30 | // GetProdDetail 获取单个商品 31 | func (*ProdService) GetProdDetail(ctx context.Context, in *models.ProdRequest, res *models.ProdDetailResponse) error { 32 | // 超时测试 33 | time.Sleep(time.Second * 3) 34 | res.Data = newProd(in.ProdId, "测试商品") 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /p21/models/prodService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prodService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for ProdService service 37 | 38 | func NewProdServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for ProdService service 43 | 44 | type ProdService interface { 45 | GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) 46 | GetProdDetail(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdDetailResponse, error) 47 | } 48 | 49 | type prodService struct { 50 | c client.Client 51 | name string 52 | } 53 | 54 | func NewProdService(name string, c client.Client) ProdService { 55 | return &prodService{ 56 | c: c, 57 | name: name, 58 | } 59 | } 60 | 61 | func (c *prodService) GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) { 62 | req := c.c.NewRequest(c.name, "ProdService.GetProdList", in) 63 | out := new(ProdListResponse) 64 | err := c.c.Call(ctx, req, out, opts...) 65 | if err != nil { 66 | return nil, err 67 | } 68 | return out, nil 69 | } 70 | 71 | func (c *prodService) GetProdDetail(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdDetailResponse, error) { 72 | req := c.c.NewRequest(c.name, "ProdService.GetProdDetail", in) 73 | out := new(ProdDetailResponse) 74 | err := c.c.Call(ctx, req, out, opts...) 75 | if err != nil { 76 | return nil, err 77 | } 78 | return out, nil 79 | } 80 | 81 | // Server API for ProdService service 82 | 83 | type ProdServiceHandler interface { 84 | GetProdList(context.Context, *ProdRequest, *ProdListResponse) error 85 | GetProdDetail(context.Context, *ProdRequest, *ProdDetailResponse) error 86 | } 87 | 88 | func RegisterProdServiceHandler(s server.Server, hdlr ProdServiceHandler, opts ...server.HandlerOption) error { 89 | type prodService interface { 90 | GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error 91 | GetProdDetail(ctx context.Context, in *ProdRequest, out *ProdDetailResponse) error 92 | } 93 | type ProdService struct { 94 | prodService 95 | } 96 | h := &prodServiceHandler{hdlr} 97 | return s.Handle(s.NewHandler(&ProdService{h}, opts...)) 98 | } 99 | 100 | type prodServiceHandler struct { 101 | ProdServiceHandler 102 | } 103 | 104 | func (h *prodServiceHandler) GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error { 105 | return h.ProdServiceHandler.GetProdList(ctx, in, out) 106 | } 107 | 108 | func (h *prodServiceHandler) GetProdDetail(ctx context.Context, in *ProdRequest, out *ProdDetailResponse) error { 109 | return h.ProdServiceHandler.GetProdDetail(ctx, in, out) 110 | } 111 | -------------------------------------------------------------------------------- /p21/models/protos/prodService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package models; 3 | 4 | option go_package = "./models"; 5 | 6 | // 商品模型 7 | message ProdModel{ 8 | // @inject_tag: json:"pid" 9 | int32 ProdId = 1; 10 | // @inject_tag: json:"pname" 11 | string ProdName = 2; 12 | } 13 | 14 | message ProdRequest{ 15 | // @inject_tag: json:"size", form:"size" 16 | int32 size = 1; 17 | // @inject_tag: uri:"pid" 18 | int32 prod_id =2; 19 | } 20 | 21 | message ProdListResponse{ 22 | repeated ProdModel data = 1; 23 | } 24 | 25 | message ProdDetailResponse{ 26 | ProdModel data = 1; 27 | } 28 | 29 | service ProdService{ 30 | rpc GetProdList(ProdRequest) returns (ProdListResponse); 31 | rpc GetProdDetail(ProdRequest) returns (ProdDetailResponse); 32 | } -------------------------------------------------------------------------------- /p22/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/prodService.proto && \ 4 | protoc-go-inject-tag --input=./models/prodService.pb.go 5 | -------------------------------------------------------------------------------- /p22/grpc_client/handlers/handler.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p22/models" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | // PanicIfError panic异常处理 11 | func PanicIfError(err error) { 12 | if err != nil { 13 | panic(err) 14 | } 15 | } 16 | 17 | // GetProdDetail 显示商品详情 18 | func GetProdDetail(c *gin.Context) { 19 | var prodReq models.ProdRequest 20 | PanicIfError(c.BindUri(&prodReq)) 21 | prodService := c.Keys["prodservice"].(models.ProdService) 22 | res, _ := prodService.GetProdDetail(context.Background(), &prodReq) 23 | 24 | c.JSON(200, gin.H{"data": res.Data}) 25 | } 26 | 27 | // GetProdList 显示商品列表 28 | func GetProdList(c *gin.Context) { 29 | prodService := c.Keys["prodservice"].(models.ProdService) 30 | var prodReq models.ProdRequest 31 | err := c.Bind(&prodReq) 32 | if err != nil { 33 | c.JSON(500, gin.H{ 34 | "status": err.Error()}) 35 | } else { 36 | prodRes, _ := prodService.GetProdList(context.Background(), &prodReq) 37 | 38 | c.JSON(200, gin.H{"data": prodRes.Data}) 39 | 40 | // 超时代码 41 | // 1.配置config 42 | //configA := hystrix.CommandConfig{ 43 | // Timeout: 1000, 44 | //} 45 | //// 2.配置command 46 | //hystrix.ConfigureCommand("getProds", configA) 47 | //// 3.执行Do方法 48 | //var prodRes *models.ProdListResponse 49 | //err := hystrix.Do("getProds", func() error { 50 | // prodRes, err = prodService.GetProdList(context.Background(), &prodReq) 51 | // return err 52 | //}, func(e error) error { 53 | // // 降级 显示默认产品 54 | // prodRes, err = defaultProds() 55 | // return err 56 | //}) 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /p22/grpc_client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 熔断的使用 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "gomicro_note/p22/grpc_client/routers" 9 | "gomicro_note/p22/grpc_client/wrappers" 10 | "gomicro_note/p22/models" 11 | 12 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 13 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 14 | "github.com/asim/go-micro/v3" 15 | "github.com/asim/go-micro/v3/client" 16 | "github.com/asim/go-micro/v3/metadata" 17 | "github.com/asim/go-micro/v3/registry" 18 | "github.com/asim/go-micro/v3/server" 19 | ) 20 | 21 | type logWrapper struct { 22 | client.Client 23 | } 24 | 25 | func (l *logWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 26 | md, _ := metadata.FromContext(ctx) 27 | fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Endpoint()) 28 | return l.Client.Call(ctx, req, rsp) 29 | } 30 | 31 | func newLogWrapper(c client.Client) client.Client { 32 | return &logWrapper{c} 33 | } 34 | 35 | func main() { 36 | 37 | etcdReg := etcd.NewRegistry( 38 | registry.Addrs("127.0.0.1:2379"), 39 | ) 40 | 41 | myService := micro.NewService( 42 | micro.Name("ProdService.client"), 43 | micro.WrapClient(newLogWrapper), 44 | micro.WrapClient(wrappers.NewProdsWrapper), 45 | ) 46 | prodService := models.NewProdService("ProdService", myService.Client()) 47 | 48 | service := httpServer.NewServer( 49 | server.Name("ProdService.client"), 50 | server.Address(":9000"), 51 | server.Registry(etcdReg), 52 | ) 53 | 54 | hd := service.NewHandler(routers.InitRouter(prodService)) 55 | service.Handle(hd) 56 | 57 | srv := micro.NewService( 58 | micro.Server(service), 59 | ) 60 | 61 | srv.Init() 62 | srv.Run() 63 | } 64 | -------------------------------------------------------------------------------- /p22/grpc_client/middlewares/middleware.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "fmt" 5 | "gomicro_note/p22/models" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | // InitMiddleware 注入prodService中间件 11 | func InitMiddleware(prodService models.ProdService) gin.HandlerFunc { 12 | return func(c *gin.Context) { 13 | c.Keys = make(map[string]interface{}) 14 | c.Keys["prodservice"] = prodService 15 | } 16 | } 17 | 18 | // ErrorMiddleware 异常处理 19 | func ErrorMiddleware() gin.HandlerFunc { 20 | return func(c *gin.Context) { 21 | defer func() { 22 | if r := recover(); r != nil { 23 | c.JSON(500, gin.H{"status": fmt.Sprintf("%s", r)}) 24 | c.Abort() 25 | } 26 | }() 27 | c.Next() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /p22/grpc_client/routers/router.go: -------------------------------------------------------------------------------- 1 | package routers 2 | 3 | import ( 4 | "gomicro_note/p22/grpc_client/handlers" 5 | "gomicro_note/p22/grpc_client/middlewares" 6 | "gomicro_note/p22/models" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // InitRouter 路由 12 | func InitRouter(prodService models.ProdService) *gin.Engine { 13 | r := gin.Default() 14 | r.Use(middlewares.InitMiddleware(prodService), middlewares.ErrorMiddleware()) 15 | v1Group := r.Group("/v1") 16 | { 17 | v1Group.Handle("POST", "/prods", handlers.GetProdList) 18 | v1Group.Handle("GET", "/prods/:pid", handlers.GetProdDetail) 19 | } 20 | return r 21 | } 22 | -------------------------------------------------------------------------------- /p22/grpc_client/wrappers/prodsWrapper.go: -------------------------------------------------------------------------------- 1 | package wrappers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p22/models" 6 | "strconv" 7 | 8 | "github.com/afex/hystrix-go/hystrix" 9 | "github.com/asim/go-micro/v3/client" 10 | ) 11 | 12 | func newProd(id int32, pname string) *models.ProdModel { 13 | return &models.ProdModel{ProdId: id, ProdName: pname} 14 | } 15 | 16 | // 通用降级方法 17 | func defaultData(rsp interface{}) { 18 | switch t := rsp.(type) { 19 | case *models.ProdListResponse: 20 | defaultProds(rsp) 21 | case *models.ProdDetailResponse: 22 | t.Data = newProd(10, "降级商品") 23 | } 24 | } 25 | 26 | // 商品列表降级方法 27 | func defaultProds(rsp interface{}) (*models.ProdListResponse, error) { 28 | model := make([]*models.ProdModel, 0) 29 | var i int32 30 | for i = 0; i < 5; i++ { 31 | model = append(model, newProd(20+i, "prodName"+strconv.Itoa(20+int(i)))) 32 | } 33 | res := rsp.(*models.ProdListResponse) 34 | res.Data = model 35 | return res, nil 36 | } 37 | 38 | // ProdsWrapper 商品装饰器 39 | type ProdsWrapper struct { 40 | client.Client 41 | } 42 | 43 | // Call 调用方法 44 | func (p *ProdsWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { 45 | cmdName := req.Service() + "." + req.Endpoint() 46 | configA := hystrix.CommandConfig{ 47 | Timeout: 1000, // 超时时间 单位毫秒 48 | RequestVolumeThreshold: 5, // 请求数量 49 | ErrorPercentThreshold: 50, // 错误百分比 50 | SleepWindow: 5000, //尝试正常请求时间 单位毫秒 默认为5秒 51 | } 52 | hystrix.ConfigureCommand(cmdName, configA) 53 | return hystrix.Do(cmdName, func() error { 54 | return p.Client.Call(ctx, req, rsp) 55 | }, func(e error) error { 56 | defaultData(rsp) 57 | return nil 58 | }) 59 | return p.Client.Call(ctx, req, rsp) 60 | } 61 | 62 | // NewProdsWrapper 初始化一个商品装饰器 63 | func NewProdsWrapper(c client.Client) client.Client { 64 | return &ProdsWrapper{c} 65 | } 66 | -------------------------------------------------------------------------------- /p22/grpc_server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p22/grpc_server/prods" 5 | "gomicro_note/p22/models" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | ) 11 | 12 | func main() { 13 | 14 | etcdReg := etcd.NewRegistry( 15 | registry.Addrs("127.0.0.1:2379"), 16 | ) 17 | 18 | app := micro.NewService( 19 | micro.Name("ProdService"), 20 | micro.Address(":8000"), 21 | micro.Registry(etcdReg), 22 | ) 23 | 24 | app.Init() 25 | err := models.RegisterProdServiceHandler(app.Server(), new(prods.ProdService)) 26 | if err != nil { 27 | panic(err) 28 | } 29 | app.Run() 30 | } 31 | -------------------------------------------------------------------------------- /p22/grpc_server/prods/prodService.go: -------------------------------------------------------------------------------- 1 | package prods 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p22/models" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | // ProdService 商品服务 11 | type ProdService struct{} 12 | 13 | func newProd(id int32, pname string) *models.ProdModel { 14 | return &models.ProdModel{ProdId: id, ProdName: pname} 15 | } 16 | 17 | // GetProdList 返回商品列表 18 | func (*ProdService) GetProdList(ctx context.Context, in *models.ProdRequest, res *models.ProdListResponse) error { 19 | // 超时测试 20 | time.Sleep(time.Second * 3) 21 | models := make([]*models.ProdModel, 0) 22 | var i int32 23 | for i = 0; i < in.Size; i++ { 24 | models = append(models, newProd(100+i, "prodName"+strconv.Itoa(100+int(i)))) 25 | } 26 | res.Data = models 27 | return nil 28 | } 29 | 30 | // GetProdDetail 获取单个商品 31 | func (*ProdService) GetProdDetail(ctx context.Context, in *models.ProdRequest, res *models.ProdDetailResponse) error { 32 | // 超时测试 33 | time.Sleep(time.Second * 3) 34 | res.Data = newProd(in.ProdId, "测试商品") 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /p22/models/prodService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/prodService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for ProdService service 37 | 38 | func NewProdServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for ProdService service 43 | 44 | type ProdService interface { 45 | GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) 46 | GetProdDetail(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdDetailResponse, error) 47 | } 48 | 49 | type prodService struct { 50 | c client.Client 51 | name string 52 | } 53 | 54 | func NewProdService(name string, c client.Client) ProdService { 55 | return &prodService{ 56 | c: c, 57 | name: name, 58 | } 59 | } 60 | 61 | func (c *prodService) GetProdList(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdListResponse, error) { 62 | req := c.c.NewRequest(c.name, "ProdService.GetProdList", in) 63 | out := new(ProdListResponse) 64 | err := c.c.Call(ctx, req, out, opts...) 65 | if err != nil { 66 | return nil, err 67 | } 68 | return out, nil 69 | } 70 | 71 | func (c *prodService) GetProdDetail(ctx context.Context, in *ProdRequest, opts ...client.CallOption) (*ProdDetailResponse, error) { 72 | req := c.c.NewRequest(c.name, "ProdService.GetProdDetail", in) 73 | out := new(ProdDetailResponse) 74 | err := c.c.Call(ctx, req, out, opts...) 75 | if err != nil { 76 | return nil, err 77 | } 78 | return out, nil 79 | } 80 | 81 | // Server API for ProdService service 82 | 83 | type ProdServiceHandler interface { 84 | GetProdList(context.Context, *ProdRequest, *ProdListResponse) error 85 | GetProdDetail(context.Context, *ProdRequest, *ProdDetailResponse) error 86 | } 87 | 88 | func RegisterProdServiceHandler(s server.Server, hdlr ProdServiceHandler, opts ...server.HandlerOption) error { 89 | type prodService interface { 90 | GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error 91 | GetProdDetail(ctx context.Context, in *ProdRequest, out *ProdDetailResponse) error 92 | } 93 | type ProdService struct { 94 | prodService 95 | } 96 | h := &prodServiceHandler{hdlr} 97 | return s.Handle(s.NewHandler(&ProdService{h}, opts...)) 98 | } 99 | 100 | type prodServiceHandler struct { 101 | ProdServiceHandler 102 | } 103 | 104 | func (h *prodServiceHandler) GetProdList(ctx context.Context, in *ProdRequest, out *ProdListResponse) error { 105 | return h.ProdServiceHandler.GetProdList(ctx, in, out) 106 | } 107 | 108 | func (h *prodServiceHandler) GetProdDetail(ctx context.Context, in *ProdRequest, out *ProdDetailResponse) error { 109 | return h.ProdServiceHandler.GetProdDetail(ctx, in, out) 110 | } 111 | -------------------------------------------------------------------------------- /p22/models/protos/prodService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package models; 3 | 4 | option go_package = "./models"; 5 | 6 | // 商品模型 7 | message ProdModel{ 8 | // @inject_tag: json:"pid" 9 | int32 ProdId = 1; 10 | // @inject_tag: json:"pname" 11 | string ProdName = 2; 12 | } 13 | 14 | message ProdRequest{ 15 | // @inject_tag: json:"size", form:"size" 16 | int32 size = 1; 17 | // @inject_tag: uri:"pid" 18 | int32 prod_id =2; 19 | } 20 | 21 | message ProdListResponse{ 22 | repeated ProdModel data = 1; 23 | } 24 | 25 | message ProdDetailResponse{ 26 | ProdModel data = 1; 27 | } 28 | 29 | service ProdService{ 30 | rpc GetProdList(ProdRequest) returns (ProdListResponse); 31 | rpc GetProdDetail(ProdRequest) returns (ProdDetailResponse); 32 | } -------------------------------------------------------------------------------- /p23/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/test.proto -------------------------------------------------------------------------------- /p23/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p23/models" 5 | "gomicro_note/p23/test" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | ) 11 | 12 | func main() { 13 | etcdReg := etcd.NewRegistry( 14 | registry.Addrs("127.0.0.1:2379"), 15 | ) 16 | 17 | myService := micro.NewService( 18 | micro.Name("test.hzde.com"), 19 | micro.Address(":8000"), 20 | micro.Registry(etcdReg), 21 | ) 22 | 23 | models.RegisterTestServiceHandler(myService.Server(), new(test.TestService)) 24 | 25 | myService.Init() 26 | 27 | myService.Run() 28 | } 29 | -------------------------------------------------------------------------------- /p23/models/protos/test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package models; 4 | 5 | option go_package = "./models"; 6 | 7 | message TestRequest{ 8 | int32 id = 1; 9 | } 10 | 11 | message TestResponse{ 12 | string data=1; 13 | } 14 | service TestService{ 15 | rpc Call(TestRequest) returns(TestResponse); 16 | } -------------------------------------------------------------------------------- /p23/models/test.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.27.0 4 | // protoc v3.17.2 5 | // source: models/protos/test.proto 6 | 7 | package models 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type TestRequest struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` 29 | } 30 | 31 | func (x *TestRequest) Reset() { 32 | *x = TestRequest{} 33 | if protoimpl.UnsafeEnabled { 34 | mi := &file_models_protos_test_proto_msgTypes[0] 35 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 36 | ms.StoreMessageInfo(mi) 37 | } 38 | } 39 | 40 | func (x *TestRequest) String() string { 41 | return protoimpl.X.MessageStringOf(x) 42 | } 43 | 44 | func (*TestRequest) ProtoMessage() {} 45 | 46 | func (x *TestRequest) ProtoReflect() protoreflect.Message { 47 | mi := &file_models_protos_test_proto_msgTypes[0] 48 | if protoimpl.UnsafeEnabled && x != nil { 49 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 50 | if ms.LoadMessageInfo() == nil { 51 | ms.StoreMessageInfo(mi) 52 | } 53 | return ms 54 | } 55 | return mi.MessageOf(x) 56 | } 57 | 58 | // Deprecated: Use TestRequest.ProtoReflect.Descriptor instead. 59 | func (*TestRequest) Descriptor() ([]byte, []int) { 60 | return file_models_protos_test_proto_rawDescGZIP(), []int{0} 61 | } 62 | 63 | func (x *TestRequest) GetId() int32 { 64 | if x != nil { 65 | return x.Id 66 | } 67 | return 0 68 | } 69 | 70 | type TestResponse struct { 71 | state protoimpl.MessageState 72 | sizeCache protoimpl.SizeCache 73 | unknownFields protoimpl.UnknownFields 74 | 75 | Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` 76 | } 77 | 78 | func (x *TestResponse) Reset() { 79 | *x = TestResponse{} 80 | if protoimpl.UnsafeEnabled { 81 | mi := &file_models_protos_test_proto_msgTypes[1] 82 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 83 | ms.StoreMessageInfo(mi) 84 | } 85 | } 86 | 87 | func (x *TestResponse) String() string { 88 | return protoimpl.X.MessageStringOf(x) 89 | } 90 | 91 | func (*TestResponse) ProtoMessage() {} 92 | 93 | func (x *TestResponse) ProtoReflect() protoreflect.Message { 94 | mi := &file_models_protos_test_proto_msgTypes[1] 95 | if protoimpl.UnsafeEnabled && x != nil { 96 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 97 | if ms.LoadMessageInfo() == nil { 98 | ms.StoreMessageInfo(mi) 99 | } 100 | return ms 101 | } 102 | return mi.MessageOf(x) 103 | } 104 | 105 | // Deprecated: Use TestResponse.ProtoReflect.Descriptor instead. 106 | func (*TestResponse) Descriptor() ([]byte, []int) { 107 | return file_models_protos_test_proto_rawDescGZIP(), []int{1} 108 | } 109 | 110 | func (x *TestResponse) GetData() string { 111 | if x != nil { 112 | return x.Data 113 | } 114 | return "" 115 | } 116 | 117 | var File_models_protos_test_proto protoreflect.FileDescriptor 118 | 119 | var file_models_protos_test_proto_rawDesc = []byte{ 120 | 0x0a, 0x18, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 121 | 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6d, 0x6f, 0x64, 0x65, 122 | 0x6c, 0x73, 0x22, 0x1d, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 123 | 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 124 | 0x64, 0x22, 0x22, 0x0a, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 125 | 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 126 | 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0x40, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x53, 0x65, 0x72, 127 | 0x76, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x13, 0x2e, 0x6d, 128 | 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 129 | 0x74, 0x1a, 0x14, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 130 | 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x6d, 0x6f, 0x64, 131 | 0x65, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 132 | } 133 | 134 | var ( 135 | file_models_protos_test_proto_rawDescOnce sync.Once 136 | file_models_protos_test_proto_rawDescData = file_models_protos_test_proto_rawDesc 137 | ) 138 | 139 | func file_models_protos_test_proto_rawDescGZIP() []byte { 140 | file_models_protos_test_proto_rawDescOnce.Do(func() { 141 | file_models_protos_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_protos_test_proto_rawDescData) 142 | }) 143 | return file_models_protos_test_proto_rawDescData 144 | } 145 | 146 | var file_models_protos_test_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 147 | var file_models_protos_test_proto_goTypes = []interface{}{ 148 | (*TestRequest)(nil), // 0: models.TestRequest 149 | (*TestResponse)(nil), // 1: models.TestResponse 150 | } 151 | var file_models_protos_test_proto_depIdxs = []int32{ 152 | 0, // 0: models.TestService.Call:input_type -> models.TestRequest 153 | 1, // 1: models.TestService.Call:output_type -> models.TestResponse 154 | 1, // [1:2] is the sub-list for method output_type 155 | 0, // [0:1] is the sub-list for method input_type 156 | 0, // [0:0] is the sub-list for extension type_name 157 | 0, // [0:0] is the sub-list for extension extendee 158 | 0, // [0:0] is the sub-list for field type_name 159 | } 160 | 161 | func init() { file_models_protos_test_proto_init() } 162 | func file_models_protos_test_proto_init() { 163 | if File_models_protos_test_proto != nil { 164 | return 165 | } 166 | if !protoimpl.UnsafeEnabled { 167 | file_models_protos_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 168 | switch v := v.(*TestRequest); i { 169 | case 0: 170 | return &v.state 171 | case 1: 172 | return &v.sizeCache 173 | case 2: 174 | return &v.unknownFields 175 | default: 176 | return nil 177 | } 178 | } 179 | file_models_protos_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 180 | switch v := v.(*TestResponse); i { 181 | case 0: 182 | return &v.state 183 | case 1: 184 | return &v.sizeCache 185 | case 2: 186 | return &v.unknownFields 187 | default: 188 | return nil 189 | } 190 | } 191 | } 192 | type x struct{} 193 | out := protoimpl.TypeBuilder{ 194 | File: protoimpl.DescBuilder{ 195 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 196 | RawDescriptor: file_models_protos_test_proto_rawDesc, 197 | NumEnums: 0, 198 | NumMessages: 2, 199 | NumExtensions: 0, 200 | NumServices: 1, 201 | }, 202 | GoTypes: file_models_protos_test_proto_goTypes, 203 | DependencyIndexes: file_models_protos_test_proto_depIdxs, 204 | MessageInfos: file_models_protos_test_proto_msgTypes, 205 | }.Build() 206 | File_models_protos_test_proto = out.File 207 | file_models_protos_test_proto_rawDesc = nil 208 | file_models_protos_test_proto_goTypes = nil 209 | file_models_protos_test_proto_depIdxs = nil 210 | } 211 | -------------------------------------------------------------------------------- /p23/models/test.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/test.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for TestService service 37 | 38 | func NewTestServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for TestService service 43 | 44 | type TestService interface { 45 | Call(ctx context.Context, in *TestRequest, opts ...client.CallOption) (*TestResponse, error) 46 | } 47 | 48 | type testService struct { 49 | c client.Client 50 | name string 51 | } 52 | 53 | func NewTestService(name string, c client.Client) TestService { 54 | return &testService{ 55 | c: c, 56 | name: name, 57 | } 58 | } 59 | 60 | func (c *testService) Call(ctx context.Context, in *TestRequest, opts ...client.CallOption) (*TestResponse, error) { 61 | req := c.c.NewRequest(c.name, "TestService.Call", in) 62 | out := new(TestResponse) 63 | err := c.c.Call(ctx, req, out, opts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | // Server API for TestService service 71 | 72 | type TestServiceHandler interface { 73 | Call(context.Context, *TestRequest, *TestResponse) error 74 | } 75 | 76 | func RegisterTestServiceHandler(s server.Server, hdlr TestServiceHandler, opts ...server.HandlerOption) error { 77 | type testService interface { 78 | Call(ctx context.Context, in *TestRequest, out *TestResponse) error 79 | } 80 | type TestService struct { 81 | testService 82 | } 83 | h := &testServiceHandler{hdlr} 84 | return s.Handle(s.NewHandler(&TestService{h}, opts...)) 85 | } 86 | 87 | type testServiceHandler struct { 88 | TestServiceHandler 89 | } 90 | 91 | func (h *testServiceHandler) Call(ctx context.Context, in *TestRequest, out *TestResponse) error { 92 | return h.TestServiceHandler.Call(ctx, in, out) 93 | } 94 | -------------------------------------------------------------------------------- /p23/test/testService.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p23/models" 6 | "strconv" 7 | ) 8 | 9 | // TestService 结构体 10 | type TestService struct { 11 | } 12 | 13 | // Call 方法 14 | func (*TestService) Call(ctx context.Context, req *models.TestRequest, rsp *models.TestResponse) error { 15 | rsp.Data = "test" + strconv.Itoa(int(req.Id)) 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /p24/README.md: -------------------------------------------------------------------------------- 1 | # 第24讲:使用Micro工具查看和调用我们的服务 2 | 3 | ## 环境变量设置 4 | 5 | ```bash 6 | export MICRO_REGISTRY=etcd 7 | export MICRO_REGISTRY_ADDRESS=127.0.0.1:2379 8 | ``` 9 | 10 | ## 安装micro客户端 11 | 12 | ```bash 13 | go get github.com/micro/micro/v3 14 | ``` 15 | 16 | ## 运行server 17 | 18 | ```bash 19 | micro server 20 | ``` 21 | 22 | ## 登录 23 | 24 | ```bash 25 | micro login 26 | ``` 27 | 28 | 默认账号`admin` 29 | 默认密码`micro` 30 | 31 | ## 获取服务的详细信息 32 | 33 | ```bash 34 | micro get service test.hzde.com 35 | ``` 36 | 37 | 输出结果 38 | 39 | ```bash 40 | service test.hzde.com 41 | 42 | version latest 43 | 44 | ID Address Metadata 45 | test.hzde.com-7e8c75dd-75e9-49a3-a415-48dbfad893ac [fdf8:292:d5e9:0:ccc:f210:43a8:3f2b]:8000 transport=grpc,broker=eats,protocol=grpc,registry=etcd,server=grpc 46 | 47 | Endpoint: TestService.Call 48 | 49 | Request: { 50 | id int32 51 | } 52 | 53 | Response: { 54 | data string 55 | } 56 | ``` 57 | 58 | ## 通过micro工具箱请求后端服务 59 | 60 | ```bash 61 | micro call test.hzde.com TestService.Call '{"id": 123}' 62 | ``` 63 | 64 | 输出结果 65 | 66 | ```bash 67 | { 68 | "data": "test123" 69 | } 70 | ``` 71 | -------------------------------------------------------------------------------- /p25/README.md: -------------------------------------------------------------------------------- 1 | # 使用micro api进行接口测试 2 | 3 | 运行micro api 4 | 5 | ```bash 6 | #!/bin/bash 7 | 8 | export MICRO_REGISTRY=etcd 9 | export MICRO_REGISTRY_ADDRESS=127.0.0.1:2379 10 | export MICRO_API_HANDLER=rpc 11 | export MICRO_API_NAMESPACE=api.hzde.com 12 | 13 | micro api 14 | ``` 15 | 16 | 发送POST请求 17 | 18 | ```bash 19 | curl -X POST "http://localhost:8080/test/TestService/Call" -d '{"id": 1}' 20 | ``` 21 | 22 | 输出结果 23 | 24 | ```json 25 | {"data":"test1"} 26 | ``` 27 | -------------------------------------------------------------------------------- /p25/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/test.proto -------------------------------------------------------------------------------- /p25/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "gomicro_note/p25/models" 5 | "gomicro_note/p25/test" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | ) 11 | 12 | func main() { 13 | etcdReg := etcd.NewRegistry( 14 | registry.Addrs("127.0.0.1:2379"), 15 | ) 16 | 17 | myService := micro.NewService( 18 | micro.Name("api.hzde.com.test"), 19 | micro.Address(":8000"), 20 | micro.Registry(etcdReg), 21 | ) 22 | 23 | models.RegisterTestServiceHandler(myService.Server(), new(test.TestService)) 24 | 25 | myService.Init() 26 | 27 | myService.Run() 28 | } 29 | -------------------------------------------------------------------------------- /p25/models/protos/test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package models; 4 | 5 | option go_package = "./models"; 6 | 7 | message TestRequest{ 8 | int32 id = 1; 9 | } 10 | 11 | message TestResponse{ 12 | string data=1; 13 | } 14 | service TestService{ 15 | rpc Call(TestRequest) returns(TestResponse); 16 | } -------------------------------------------------------------------------------- /p25/models/test.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.27.0 4 | // protoc v3.17.2 5 | // source: models/protos/test.proto 6 | 7 | package models 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type TestRequest struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` 29 | } 30 | 31 | func (x *TestRequest) Reset() { 32 | *x = TestRequest{} 33 | if protoimpl.UnsafeEnabled { 34 | mi := &file_models_protos_test_proto_msgTypes[0] 35 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 36 | ms.StoreMessageInfo(mi) 37 | } 38 | } 39 | 40 | func (x *TestRequest) String() string { 41 | return protoimpl.X.MessageStringOf(x) 42 | } 43 | 44 | func (*TestRequest) ProtoMessage() {} 45 | 46 | func (x *TestRequest) ProtoReflect() protoreflect.Message { 47 | mi := &file_models_protos_test_proto_msgTypes[0] 48 | if protoimpl.UnsafeEnabled && x != nil { 49 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 50 | if ms.LoadMessageInfo() == nil { 51 | ms.StoreMessageInfo(mi) 52 | } 53 | return ms 54 | } 55 | return mi.MessageOf(x) 56 | } 57 | 58 | // Deprecated: Use TestRequest.ProtoReflect.Descriptor instead. 59 | func (*TestRequest) Descriptor() ([]byte, []int) { 60 | return file_models_protos_test_proto_rawDescGZIP(), []int{0} 61 | } 62 | 63 | func (x *TestRequest) GetId() int32 { 64 | if x != nil { 65 | return x.Id 66 | } 67 | return 0 68 | } 69 | 70 | type TestResponse struct { 71 | state protoimpl.MessageState 72 | sizeCache protoimpl.SizeCache 73 | unknownFields protoimpl.UnknownFields 74 | 75 | Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` 76 | } 77 | 78 | func (x *TestResponse) Reset() { 79 | *x = TestResponse{} 80 | if protoimpl.UnsafeEnabled { 81 | mi := &file_models_protos_test_proto_msgTypes[1] 82 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 83 | ms.StoreMessageInfo(mi) 84 | } 85 | } 86 | 87 | func (x *TestResponse) String() string { 88 | return protoimpl.X.MessageStringOf(x) 89 | } 90 | 91 | func (*TestResponse) ProtoMessage() {} 92 | 93 | func (x *TestResponse) ProtoReflect() protoreflect.Message { 94 | mi := &file_models_protos_test_proto_msgTypes[1] 95 | if protoimpl.UnsafeEnabled && x != nil { 96 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 97 | if ms.LoadMessageInfo() == nil { 98 | ms.StoreMessageInfo(mi) 99 | } 100 | return ms 101 | } 102 | return mi.MessageOf(x) 103 | } 104 | 105 | // Deprecated: Use TestResponse.ProtoReflect.Descriptor instead. 106 | func (*TestResponse) Descriptor() ([]byte, []int) { 107 | return file_models_protos_test_proto_rawDescGZIP(), []int{1} 108 | } 109 | 110 | func (x *TestResponse) GetData() string { 111 | if x != nil { 112 | return x.Data 113 | } 114 | return "" 115 | } 116 | 117 | var File_models_protos_test_proto protoreflect.FileDescriptor 118 | 119 | var file_models_protos_test_proto_rawDesc = []byte{ 120 | 0x0a, 0x18, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 121 | 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6d, 0x6f, 0x64, 0x65, 122 | 0x6c, 0x73, 0x22, 0x1d, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 123 | 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 124 | 0x64, 0x22, 0x22, 0x0a, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 125 | 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 126 | 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0x40, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x53, 0x65, 0x72, 127 | 0x76, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x13, 0x2e, 0x6d, 128 | 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 129 | 0x74, 0x1a, 0x14, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 130 | 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x6d, 0x6f, 0x64, 131 | 0x65, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 132 | } 133 | 134 | var ( 135 | file_models_protos_test_proto_rawDescOnce sync.Once 136 | file_models_protos_test_proto_rawDescData = file_models_protos_test_proto_rawDesc 137 | ) 138 | 139 | func file_models_protos_test_proto_rawDescGZIP() []byte { 140 | file_models_protos_test_proto_rawDescOnce.Do(func() { 141 | file_models_protos_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_protos_test_proto_rawDescData) 142 | }) 143 | return file_models_protos_test_proto_rawDescData 144 | } 145 | 146 | var file_models_protos_test_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 147 | var file_models_protos_test_proto_goTypes = []interface{}{ 148 | (*TestRequest)(nil), // 0: models.TestRequest 149 | (*TestResponse)(nil), // 1: models.TestResponse 150 | } 151 | var file_models_protos_test_proto_depIdxs = []int32{ 152 | 0, // 0: models.TestService.Call:input_type -> models.TestRequest 153 | 1, // 1: models.TestService.Call:output_type -> models.TestResponse 154 | 1, // [1:2] is the sub-list for method output_type 155 | 0, // [0:1] is the sub-list for method input_type 156 | 0, // [0:0] is the sub-list for extension type_name 157 | 0, // [0:0] is the sub-list for extension extendee 158 | 0, // [0:0] is the sub-list for field type_name 159 | } 160 | 161 | func init() { file_models_protos_test_proto_init() } 162 | func file_models_protos_test_proto_init() { 163 | if File_models_protos_test_proto != nil { 164 | return 165 | } 166 | if !protoimpl.UnsafeEnabled { 167 | file_models_protos_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 168 | switch v := v.(*TestRequest); i { 169 | case 0: 170 | return &v.state 171 | case 1: 172 | return &v.sizeCache 173 | case 2: 174 | return &v.unknownFields 175 | default: 176 | return nil 177 | } 178 | } 179 | file_models_protos_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 180 | switch v := v.(*TestResponse); i { 181 | case 0: 182 | return &v.state 183 | case 1: 184 | return &v.sizeCache 185 | case 2: 186 | return &v.unknownFields 187 | default: 188 | return nil 189 | } 190 | } 191 | } 192 | type x struct{} 193 | out := protoimpl.TypeBuilder{ 194 | File: protoimpl.DescBuilder{ 195 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 196 | RawDescriptor: file_models_protos_test_proto_rawDesc, 197 | NumEnums: 0, 198 | NumMessages: 2, 199 | NumExtensions: 0, 200 | NumServices: 1, 201 | }, 202 | GoTypes: file_models_protos_test_proto_goTypes, 203 | DependencyIndexes: file_models_protos_test_proto_depIdxs, 204 | MessageInfos: file_models_protos_test_proto_msgTypes, 205 | }.Build() 206 | File_models_protos_test_proto = out.File 207 | file_models_protos_test_proto_rawDesc = nil 208 | file_models_protos_test_proto_goTypes = nil 209 | file_models_protos_test_proto_depIdxs = nil 210 | } 211 | -------------------------------------------------------------------------------- /p25/models/test.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/test.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | import ( 13 | context "context" 14 | api "github.com/asim/go-micro/v3/api" 15 | client "github.com/asim/go-micro/v3/client" 16 | server "github.com/asim/go-micro/v3/server" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 29 | 30 | // Reference imports to suppress errors if they are not otherwise used. 31 | var _ api.Endpoint 32 | var _ context.Context 33 | var _ client.Option 34 | var _ server.Option 35 | 36 | // Api Endpoints for TestService service 37 | 38 | func NewTestServiceEndpoints() []*api.Endpoint { 39 | return []*api.Endpoint{} 40 | } 41 | 42 | // Client API for TestService service 43 | 44 | type TestService interface { 45 | Call(ctx context.Context, in *TestRequest, opts ...client.CallOption) (*TestResponse, error) 46 | } 47 | 48 | type testService struct { 49 | c client.Client 50 | name string 51 | } 52 | 53 | func NewTestService(name string, c client.Client) TestService { 54 | return &testService{ 55 | c: c, 56 | name: name, 57 | } 58 | } 59 | 60 | func (c *testService) Call(ctx context.Context, in *TestRequest, opts ...client.CallOption) (*TestResponse, error) { 61 | req := c.c.NewRequest(c.name, "TestService.Call", in) 62 | out := new(TestResponse) 63 | err := c.c.Call(ctx, req, out, opts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | // Server API for TestService service 71 | 72 | type TestServiceHandler interface { 73 | Call(context.Context, *TestRequest, *TestResponse) error 74 | } 75 | 76 | func RegisterTestServiceHandler(s server.Server, hdlr TestServiceHandler, opts ...server.HandlerOption) error { 77 | type testService interface { 78 | Call(ctx context.Context, in *TestRequest, out *TestResponse) error 79 | } 80 | type TestService struct { 81 | testService 82 | } 83 | h := &testServiceHandler{hdlr} 84 | return s.Handle(s.NewHandler(&TestService{h}, opts...)) 85 | } 86 | 87 | type testServiceHandler struct { 88 | TestServiceHandler 89 | } 90 | 91 | func (h *testServiceHandler) Call(ctx context.Context, in *TestRequest, out *TestResponse) error { 92 | return h.TestServiceHandler.Call(ctx, in, out) 93 | } 94 | -------------------------------------------------------------------------------- /p25/test/testService.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p25/models" 6 | "strconv" 7 | ) 8 | 9 | type TestService struct { 10 | } 11 | 12 | func (*TestService) Call(ctx context.Context, req *models.TestRequest, rsp *models.TestResponse) error { 13 | rsp.Data = "test" + strconv.Itoa(int(req.Id)) 14 | return nil 15 | } 16 | -------------------------------------------------------------------------------- /p27/controllers/user.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p27/models" 6 | ) 7 | 8 | type UserService struct { 9 | } 10 | 11 | func (*UserService) UserReg(ctx context.Context, req *models.UserModel, rsp *models.RegResponse) error { 12 | rsp.Message = "" 13 | rsp.Status = "success" 14 | return nil 15 | } 16 | -------------------------------------------------------------------------------- /p27/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/UserService.proto 4 | protoc-go-inject-tag --input=models/UserService.pb.go 5 | -------------------------------------------------------------------------------- /p27/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 5 | "github.com/asim/go-micro/v3" 6 | "github.com/asim/go-micro/v3/registry" 7 | 8 | "gomicro_note/p27/controllers" 9 | "gomicro_note/p27/models" 10 | ) 11 | 12 | func main() { 13 | etcdReg := etcd.NewRegistry( 14 | registry.Addrs("127.0.0.1:2379"), 15 | ) 16 | 17 | app := micro.NewService( 18 | micro.Name("api.hzde.com.user"), 19 | micro.Address(":8000"), 20 | micro.Registry(etcdReg), 21 | ) 22 | 23 | models.RegisterUserServiceHandler(app.Server(), new(controllers.UserService)) 24 | app.Init() 25 | 26 | app.Run() 27 | } 28 | -------------------------------------------------------------------------------- /p27/models/UserService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/UserService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | _ "google.golang.org/protobuf/types/known/timestamppb" 10 | math "math" 11 | ) 12 | 13 | import ( 14 | context "context" 15 | api "github.com/asim/go-micro/v3/api" 16 | client "github.com/asim/go-micro/v3/client" 17 | server "github.com/asim/go-micro/v3/server" 18 | ) 19 | 20 | // Reference imports to suppress errors if they are not otherwise used. 21 | var _ = proto.Marshal 22 | var _ = fmt.Errorf 23 | var _ = math.Inf 24 | 25 | // This is a compile-time assertion to ensure that this generated file 26 | // is compatible with the proto package it is being compiled against. 27 | // A compilation error at this line likely means your copy of the 28 | // proto package needs to be updated. 29 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 30 | 31 | // Reference imports to suppress errors if they are not otherwise used. 32 | var _ api.Endpoint 33 | var _ context.Context 34 | var _ client.Option 35 | var _ server.Option 36 | 37 | // Api Endpoints for UserService service 38 | 39 | func NewUserServiceEndpoints() []*api.Endpoint { 40 | return []*api.Endpoint{} 41 | } 42 | 43 | // Client API for UserService service 44 | 45 | type UserService interface { 46 | UserReg(ctx context.Context, in *UserModel, opts ...client.CallOption) (*RegResponse, error) 47 | } 48 | 49 | type userService struct { 50 | c client.Client 51 | name string 52 | } 53 | 54 | func NewUserService(name string, c client.Client) UserService { 55 | return &userService{ 56 | c: c, 57 | name: name, 58 | } 59 | } 60 | 61 | func (c *userService) UserReg(ctx context.Context, in *UserModel, opts ...client.CallOption) (*RegResponse, error) { 62 | req := c.c.NewRequest(c.name, "UserService.UserReg", in) 63 | out := new(RegResponse) 64 | err := c.c.Call(ctx, req, out, opts...) 65 | if err != nil { 66 | return nil, err 67 | } 68 | return out, nil 69 | } 70 | 71 | // Server API for UserService service 72 | 73 | type UserServiceHandler interface { 74 | UserReg(context.Context, *UserModel, *RegResponse) error 75 | } 76 | 77 | func RegisterUserServiceHandler(s server.Server, hdlr UserServiceHandler, opts ...server.HandlerOption) error { 78 | type userService interface { 79 | UserReg(ctx context.Context, in *UserModel, out *RegResponse) error 80 | } 81 | type UserService struct { 82 | userService 83 | } 84 | h := &userServiceHandler{hdlr} 85 | return s.Handle(s.NewHandler(&UserService{h}, opts...)) 86 | } 87 | 88 | type userServiceHandler struct { 89 | UserServiceHandler 90 | } 91 | 92 | func (h *userServiceHandler) UserReg(ctx context.Context, in *UserModel, out *RegResponse) error { 93 | return h.UserServiceHandler.UserReg(ctx, in, out) 94 | } 95 | -------------------------------------------------------------------------------- /p27/models/protos/UserService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package models; 4 | 5 | option go_package = "./models"; 6 | 7 | import "google/protobuf/timestamp.proto"; 8 | 9 | message UserModel{ 10 | int32 user_id = 1; 11 | string user_name = 2; 12 | string user_pwd = 3; 13 | google.protobuf.Timestamp user_date = 4; 14 | } 15 | 16 | message RegResponse{ 17 | string status = 1; 18 | string message = 2; 19 | } 20 | 21 | service UserService{ 22 | rpc UserReg(UserModel) returns(RegResponse); 23 | } -------------------------------------------------------------------------------- /p27/models/protos/google/protobuf/timestamp.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option cc_enable_arenas = true; 37 | option go_package = "github.com/golang/protobuf/ptypes/timestamp"; 38 | option java_package = "com.google.protobuf"; 39 | option java_outer_classname = "TimestampProto"; 40 | option java_multiple_files = true; 41 | option objc_class_prefix = "GPB"; 42 | 43 | // A Timestamp represents a point in time independent of any time zone or local 44 | // calendar, encoded as a count of seconds and fractions of seconds at 45 | // nanosecond resolution. The count is relative to an epoch at UTC midnight on 46 | // January 1, 1970, in the proleptic Gregorian calendar which extends the 47 | // Gregorian calendar backwards to year one. 48 | // 49 | // All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap 50 | // second table is needed for interpretation, using a [24-hour linear 51 | // smear](https://developers.google.com/time/smear). 52 | // 53 | // The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By 54 | // restricting to that range, we ensure that we can convert to and from [RFC 55 | // 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. 56 | // 57 | // # Examples 58 | // 59 | // Example 1: Compute Timestamp from POSIX `time()`. 60 | // 61 | // Timestamp timestamp; 62 | // timestamp.set_seconds(time(NULL)); 63 | // timestamp.set_nanos(0); 64 | // 65 | // Example 2: Compute Timestamp from POSIX `gettimeofday()`. 66 | // 67 | // struct timeval tv; 68 | // gettimeofday(&tv, NULL); 69 | // 70 | // Timestamp timestamp; 71 | // timestamp.set_seconds(tv.tv_sec); 72 | // timestamp.set_nanos(tv.tv_usec * 1000); 73 | // 74 | // Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. 75 | // 76 | // FILETIME ft; 77 | // GetSystemTimeAsFileTime(&ft); 78 | // UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; 79 | // 80 | // // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z 81 | // // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. 82 | // Timestamp timestamp; 83 | // timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); 84 | // timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); 85 | // 86 | // Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. 87 | // 88 | // long millis = System.currentTimeMillis(); 89 | // 90 | // Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) 91 | // .setNanos((int) ((millis % 1000) * 1000000)).build(); 92 | // 93 | // 94 | // Example 5: Compute Timestamp from current time in Python. 95 | // 96 | // timestamp = Timestamp() 97 | // timestamp.GetCurrentTime() 98 | // 99 | // # JSON Mapping 100 | // 101 | // In JSON format, the Timestamp type is encoded as a string in the 102 | // [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the 103 | // format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" 104 | // where {year} is always expressed using four digits while {month}, {day}, 105 | // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional 106 | // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), 107 | // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone 108 | // is required. A proto3 JSON serializer should always use UTC (as indicated by 109 | // "Z") when printing the Timestamp type and a proto3 JSON parser should be 110 | // able to accept both UTC and other timezones (as indicated by an offset). 111 | // 112 | // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 113 | // 01:30 UTC on January 15, 2017. 114 | // 115 | // In JavaScript, one can convert a Date object to this format using the 116 | // standard 117 | // [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) 118 | // method. In Python, a standard `datetime.datetime` object can be converted 119 | // to this format using 120 | // [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with 121 | // the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use 122 | // the Joda Time's [`ISODateTimeFormat.dateTime()`]( 123 | // http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D 124 | // ) to obtain a formatter capable of generating timestamps in this format. 125 | // 126 | // 127 | message Timestamp { 128 | // Represents seconds of UTC time since Unix epoch 129 | // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 130 | // 9999-12-31T23:59:59Z inclusive. 131 | int64 seconds = 1; 132 | 133 | // Non-negative fractions of a second at nanosecond resolution. Negative 134 | // second values with fractions must still have non-negative nanos values 135 | // that count forward in time. Must be from 0 to 999,999,999 136 | // inclusive. 137 | int32 nanos = 2; 138 | } 139 | -------------------------------------------------------------------------------- /p28/api.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export MICRO_REGISTRY=etcd 4 | export MICRO_REGISTRY_ADDRESS=127.0.0.1:2379 5 | 6 | export MICRO_API_HANDLER=rpc 7 | export MICRO_API_NAMESPACE=api.hzde.com 8 | 9 | micro api 10 | -------------------------------------------------------------------------------- /p28/appInit/init.go: -------------------------------------------------------------------------------- 1 | package appInit 2 | 3 | import ( 4 | "gomicro_note/p28/models" 5 | "log" 6 | 7 | "github.com/jinzhu/gorm" 8 | _ "github.com/jinzhu/gorm/dialects/mysql" 9 | ) 10 | 11 | var db *gorm.DB 12 | 13 | func init() { 14 | var err error 15 | db, err = gorm.Open("mysql", "root:12345678@tcp(127.0.0.1:3306)/user?charset=utf8&parseTime=True&loc=Local") 16 | if err != nil { 17 | log.Fatal(err) 18 | } 19 | db.DB().SetMaxIdleConns(10) 20 | db.DB().SetMaxOpenConns(50) 21 | db.AutoMigrate(&models.UserModel{}) 22 | } 23 | 24 | func GetDB() *gorm.DB { 25 | return db 26 | } 27 | -------------------------------------------------------------------------------- /p28/controllers/user.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p28/appInit" 6 | "gomicro_note/p28/models" 7 | 8 | "google.golang.org/protobuf/types/known/timestamppb" 9 | ) 10 | 11 | type UserService struct { 12 | } 13 | 14 | func (*UserService) UserReg(ctx context.Context, req *models.UserModel, rsp *models.RegResponse) error { 15 | users := models.UserModel{UserName: req.UserName, UserPwd: req.UserPwd, UserDate: timestamppb.Now()} 16 | err := appInit.GetDB().Create(&users).Error 17 | if err != nil { 18 | rsp.Message = err.Error() 19 | rsp.Status = "error" 20 | } else { 21 | rsp.Message = "" 22 | rsp.Status = "success" 23 | } 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /p28/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/UserService.proto 4 | protoc-go-inject-tag --input=models/UserService.pb.go -------------------------------------------------------------------------------- /p28/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 5 | "github.com/asim/go-micro/v3" 6 | "github.com/asim/go-micro/v3/registry" 7 | 8 | _ "gomicro_note/p28/appInit" 9 | "gomicro_note/p28/controllers" 10 | "gomicro_note/p28/models" 11 | ) 12 | 13 | func main() { 14 | etcdReg := etcd.NewRegistry( 15 | registry.Addrs("127.0.0.1:2379"), 16 | ) 17 | 18 | app := micro.NewService( 19 | micro.Name("api.hzde.com.user"), 20 | micro.Address(":8000"), 21 | micro.Registry(etcdReg), 22 | ) 23 | 24 | models.RegisterUserServiceHandler(app.Server(), new(controllers.UserService)) 25 | app.Init() 26 | 27 | app.Run() 28 | } 29 | -------------------------------------------------------------------------------- /p28/models/UserService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/UserService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | _ "google.golang.org/protobuf/types/known/timestamppb" 10 | math "math" 11 | ) 12 | 13 | import ( 14 | context "context" 15 | api "github.com/asim/go-micro/v3/api" 16 | client "github.com/asim/go-micro/v3/client" 17 | server "github.com/asim/go-micro/v3/server" 18 | ) 19 | 20 | // Reference imports to suppress errors if they are not otherwise used. 21 | var _ = proto.Marshal 22 | var _ = fmt.Errorf 23 | var _ = math.Inf 24 | 25 | // This is a compile-time assertion to ensure that this generated file 26 | // is compatible with the proto package it is being compiled against. 27 | // A compilation error at this line likely means your copy of the 28 | // proto package needs to be updated. 29 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 30 | 31 | // Reference imports to suppress errors if they are not otherwise used. 32 | var _ api.Endpoint 33 | var _ context.Context 34 | var _ client.Option 35 | var _ server.Option 36 | 37 | // Api Endpoints for UserService service 38 | 39 | func NewUserServiceEndpoints() []*api.Endpoint { 40 | return []*api.Endpoint{} 41 | } 42 | 43 | // Client API for UserService service 44 | 45 | type UserService interface { 46 | UserReg(ctx context.Context, in *UserModel, opts ...client.CallOption) (*RegResponse, error) 47 | } 48 | 49 | type userService struct { 50 | c client.Client 51 | name string 52 | } 53 | 54 | func NewUserService(name string, c client.Client) UserService { 55 | return &userService{ 56 | c: c, 57 | name: name, 58 | } 59 | } 60 | 61 | func (c *userService) UserReg(ctx context.Context, in *UserModel, opts ...client.CallOption) (*RegResponse, error) { 62 | req := c.c.NewRequest(c.name, "UserService.UserReg", in) 63 | out := new(RegResponse) 64 | err := c.c.Call(ctx, req, out, opts...) 65 | if err != nil { 66 | return nil, err 67 | } 68 | return out, nil 69 | } 70 | 71 | // Server API for UserService service 72 | 73 | type UserServiceHandler interface { 74 | UserReg(context.Context, *UserModel, *RegResponse) error 75 | } 76 | 77 | func RegisterUserServiceHandler(s server.Server, hdlr UserServiceHandler, opts ...server.HandlerOption) error { 78 | type userService interface { 79 | UserReg(ctx context.Context, in *UserModel, out *RegResponse) error 80 | } 81 | type UserService struct { 82 | userService 83 | } 84 | h := &userServiceHandler{hdlr} 85 | return s.Handle(s.NewHandler(&UserService{h}, opts...)) 86 | } 87 | 88 | type userServiceHandler struct { 89 | UserServiceHandler 90 | } 91 | 92 | func (h *userServiceHandler) UserReg(ctx context.Context, in *UserModel, out *RegResponse) error { 93 | return h.UserServiceHandler.UserReg(ctx, in, out) 94 | } 95 | -------------------------------------------------------------------------------- /p28/models/protos/UserService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package models; 4 | 5 | option go_package = "./models"; 6 | 7 | import "google/protobuf/timestamp.proto"; 8 | 9 | message UserModel{ 10 | int32 user_id = 1; 11 | string user_name = 2; 12 | string user_pwd = 3; 13 | google.protobuf.Timestamp user_date = 4; 14 | } 15 | 16 | message RegResponse{ 17 | string status = 1; 18 | string message = 2; 19 | } 20 | 21 | service UserService{ 22 | rpc UserReg(UserModel) returns(RegResponse); 23 | } -------------------------------------------------------------------------------- /p28/models/protos/google/protobuf/timestamp.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option cc_enable_arenas = true; 37 | option go_package = "github.com/golang/protobuf/ptypes/timestamp"; 38 | option java_package = "com.google.protobuf"; 39 | option java_outer_classname = "TimestampProto"; 40 | option java_multiple_files = true; 41 | option objc_class_prefix = "GPB"; 42 | 43 | // A Timestamp represents a point in time independent of any time zone or local 44 | // calendar, encoded as a count of seconds and fractions of seconds at 45 | // nanosecond resolution. The count is relative to an epoch at UTC midnight on 46 | // January 1, 1970, in the proleptic Gregorian calendar which extends the 47 | // Gregorian calendar backwards to year one. 48 | // 49 | // All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap 50 | // second table is needed for interpretation, using a [24-hour linear 51 | // smear](https://developers.google.com/time/smear). 52 | // 53 | // The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By 54 | // restricting to that range, we ensure that we can convert to and from [RFC 55 | // 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. 56 | // 57 | // # Examples 58 | // 59 | // Example 1: Compute Timestamp from POSIX `time()`. 60 | // 61 | // Timestamp timestamp; 62 | // timestamp.set_seconds(time(NULL)); 63 | // timestamp.set_nanos(0); 64 | // 65 | // Example 2: Compute Timestamp from POSIX `gettimeofday()`. 66 | // 67 | // struct timeval tv; 68 | // gettimeofday(&tv, NULL); 69 | // 70 | // Timestamp timestamp; 71 | // timestamp.set_seconds(tv.tv_sec); 72 | // timestamp.set_nanos(tv.tv_usec * 1000); 73 | // 74 | // Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. 75 | // 76 | // FILETIME ft; 77 | // GetSystemTimeAsFileTime(&ft); 78 | // UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; 79 | // 80 | // // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z 81 | // // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. 82 | // Timestamp timestamp; 83 | // timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); 84 | // timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); 85 | // 86 | // Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. 87 | // 88 | // long millis = System.currentTimeMillis(); 89 | // 90 | // Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) 91 | // .setNanos((int) ((millis % 1000) * 1000000)).build(); 92 | // 93 | // 94 | // Example 5: Compute Timestamp from current time in Python. 95 | // 96 | // timestamp = Timestamp() 97 | // timestamp.GetCurrentTime() 98 | // 99 | // # JSON Mapping 100 | // 101 | // In JSON format, the Timestamp type is encoded as a string in the 102 | // [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the 103 | // format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" 104 | // where {year} is always expressed using four digits while {month}, {day}, 105 | // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional 106 | // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), 107 | // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone 108 | // is required. A proto3 JSON serializer should always use UTC (as indicated by 109 | // "Z") when printing the Timestamp type and a proto3 JSON parser should be 110 | // able to accept both UTC and other timezones (as indicated by an offset). 111 | // 112 | // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 113 | // 01:30 UTC on January 15, 2017. 114 | // 115 | // In JavaScript, one can convert a Date object to this format using the 116 | // standard 117 | // [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) 118 | // method. In Python, a standard `datetime.datetime` object can be converted 119 | // to this format using 120 | // [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with 121 | // the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use 122 | // the Joda Time's [`ISODateTimeFormat.dateTime()`]( 123 | // http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D 124 | // ) to obtain a formatter capable of generating timestamps in this format. 125 | // 126 | // 127 | message Timestamp { 128 | // Represents seconds of UTC time since Unix epoch 129 | // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 130 | // 9999-12-31T23:59:59Z inclusive. 131 | int64 seconds = 1; 132 | 133 | // Non-negative fractions of a second at nanosecond resolution. Negative 134 | // second values with fractions must still have non-negative nanos values 135 | // that count forward in time. Must be from 0 to 999,999,999 136 | // inclusive. 137 | int32 nanos = 2; 138 | } 139 | -------------------------------------------------------------------------------- /p29/api.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export MICRO_REGISTRY=etcd 4 | export MICRO_REGISTRY_ADDRESS=127.0.0.1:2379 5 | 6 | export MICRO_API_HANDLER=rpc 7 | export MICRO_API_NAMESPACE=api.hzde.com 8 | 9 | micro api 10 | -------------------------------------------------------------------------------- /p29/appInit/init.go: -------------------------------------------------------------------------------- 1 | package appInit 2 | 3 | import ( 4 | "gomicro_note/p29/models" 5 | "log" 6 | 7 | "github.com/jinzhu/gorm" 8 | _ "github.com/jinzhu/gorm/dialects/mysql" 9 | ) 10 | 11 | var db *gorm.DB 12 | 13 | func init() { 14 | var err error 15 | db, err = gorm.Open("mysql", "root:12345678@tcp(127.0.0.1:3306)/user?charset=utf8&parseTime=True&loc=Local") 16 | if err != nil { 17 | log.Fatal(err) 18 | } 19 | db.DB().SetMaxIdleConns(10) 20 | db.DB().SetMaxOpenConns(50) 21 | // 自动建表 22 | db.AutoMigrate(&models.User{}) 23 | } 24 | 25 | func GetDB() *gorm.DB { 26 | return db 27 | } 28 | -------------------------------------------------------------------------------- /p29/controllers/user.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "context" 5 | "gomicro_note/p29/appInit" 6 | "gomicro_note/p29/models" 7 | 8 | "google.golang.org/protobuf/types/known/timestamppb" 9 | ) 10 | 11 | type UserService struct { 12 | } 13 | 14 | func (*UserService) UserReg(ctx context.Context, req *models.User, rsp *models.RegResponse) error { 15 | users := models.User{UserName: req.UserName, UserPwd: req.UserPwd, UserDate: timestamppb.Now()} 16 | err := appInit.GetDB().Create(&users).Error 17 | if err != nil { 18 | rsp.Message = err.Error() 19 | rsp.Status = "error" 20 | } else { 21 | rsp.Message = "" 22 | rsp.Status = "success" 23 | } 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /p29/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc --micro_out=./ --go_out=./ models/protos/UserService.proto 4 | protoc-go-inject-tag --input=models/UserService.pb.go -------------------------------------------------------------------------------- /p29/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 5 | "github.com/asim/go-micro/v3" 6 | "github.com/asim/go-micro/v3/registry" 7 | 8 | _ "gomicro_note/p29/appInit" 9 | "gomicro_note/p29/controllers" 10 | "gomicro_note/p29/models" 11 | ) 12 | 13 | func main() { 14 | etcdReg := etcd.NewRegistry( 15 | registry.Addrs("127.0.0.1:2379"), 16 | ) 17 | 18 | app := micro.NewService( 19 | micro.Name("api.hzde.com.user"), 20 | micro.Address(":8000"), 21 | micro.Registry(etcdReg), 22 | ) 23 | 24 | models.RegisterUserServiceHandler(app.Server(), new(controllers.UserService)) 25 | app.Init() 26 | 27 | app.Run() 28 | } 29 | -------------------------------------------------------------------------------- /p29/models/UserService.pb.micro.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-micro. DO NOT EDIT. 2 | // source: models/protos/UserService.proto 3 | 4 | package models 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | _ "google.golang.org/protobuf/types/known/timestamppb" 10 | math "math" 11 | ) 12 | 13 | import ( 14 | context "context" 15 | api "github.com/asim/go-micro/v3/api" 16 | client "github.com/asim/go-micro/v3/client" 17 | server "github.com/asim/go-micro/v3/server" 18 | ) 19 | 20 | // Reference imports to suppress errors if they are not otherwise used. 21 | var _ = proto.Marshal 22 | var _ = fmt.Errorf 23 | var _ = math.Inf 24 | 25 | // This is a compile-time assertion to ensure that this generated file 26 | // is compatible with the proto package it is being compiled against. 27 | // A compilation error at this line likely means your copy of the 28 | // proto package needs to be updated. 29 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 30 | 31 | // Reference imports to suppress errors if they are not otherwise used. 32 | var _ api.Endpoint 33 | var _ context.Context 34 | var _ client.Option 35 | var _ server.Option 36 | 37 | // Api Endpoints for UserService service 38 | 39 | func NewUserServiceEndpoints() []*api.Endpoint { 40 | return []*api.Endpoint{} 41 | } 42 | 43 | // Client API for UserService service 44 | 45 | type UserService interface { 46 | UserReg(ctx context.Context, in *User, opts ...client.CallOption) (*RegResponse, error) 47 | } 48 | 49 | type userService struct { 50 | c client.Client 51 | name string 52 | } 53 | 54 | func NewUserService(name string, c client.Client) UserService { 55 | return &userService{ 56 | c: c, 57 | name: name, 58 | } 59 | } 60 | 61 | func (c *userService) UserReg(ctx context.Context, in *User, opts ...client.CallOption) (*RegResponse, error) { 62 | req := c.c.NewRequest(c.name, "UserService.UserReg", in) 63 | out := new(RegResponse) 64 | err := c.c.Call(ctx, req, out, opts...) 65 | if err != nil { 66 | return nil, err 67 | } 68 | return out, nil 69 | } 70 | 71 | // Server API for UserService service 72 | 73 | type UserServiceHandler interface { 74 | UserReg(context.Context, *User, *RegResponse) error 75 | } 76 | 77 | func RegisterUserServiceHandler(s server.Server, hdlr UserServiceHandler, opts ...server.HandlerOption) error { 78 | type userService interface { 79 | UserReg(ctx context.Context, in *User, out *RegResponse) error 80 | } 81 | type UserService struct { 82 | userService 83 | } 84 | h := &userServiceHandler{hdlr} 85 | return s.Handle(s.NewHandler(&UserService{h}, opts...)) 86 | } 87 | 88 | type userServiceHandler struct { 89 | UserServiceHandler 90 | } 91 | 92 | func (h *userServiceHandler) UserReg(ctx context.Context, in *User, out *RegResponse) error { 93 | return h.UserServiceHandler.UserReg(ctx, in, out) 94 | } 95 | -------------------------------------------------------------------------------- /p29/models/protos/UserService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package models; 4 | 5 | option go_package = "./models"; 6 | 7 | import "google/protobuf/timestamp.proto"; 8 | 9 | message User{ 10 | int32 user_id = 1; 11 | string user_name = 2; 12 | string user_pwd = 3; 13 | google.protobuf.Timestamp user_date = 4; 14 | } 15 | 16 | message RegResponse{ 17 | string status = 1; 18 | string message = 2; 19 | } 20 | 21 | service UserService{ 22 | rpc UserReg(User) returns(RegResponse); 23 | } -------------------------------------------------------------------------------- /p29/models/protos/google/protobuf/timestamp.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option cc_enable_arenas = true; 37 | option go_package = "github.com/golang/protobuf/ptypes/timestamp"; 38 | option java_package = "com.google.protobuf"; 39 | option java_outer_classname = "TimestampProto"; 40 | option java_multiple_files = true; 41 | option objc_class_prefix = "GPB"; 42 | 43 | // A Timestamp represents a point in time independent of any time zone or local 44 | // calendar, encoded as a count of seconds and fractions of seconds at 45 | // nanosecond resolution. The count is relative to an epoch at UTC midnight on 46 | // January 1, 1970, in the proleptic Gregorian calendar which extends the 47 | // Gregorian calendar backwards to year one. 48 | // 49 | // All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap 50 | // second table is needed for interpretation, using a [24-hour linear 51 | // smear](https://developers.google.com/time/smear). 52 | // 53 | // The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By 54 | // restricting to that range, we ensure that we can convert to and from [RFC 55 | // 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. 56 | // 57 | // # Examples 58 | // 59 | // Example 1: Compute Timestamp from POSIX `time()`. 60 | // 61 | // Timestamp timestamp; 62 | // timestamp.set_seconds(time(NULL)); 63 | // timestamp.set_nanos(0); 64 | // 65 | // Example 2: Compute Timestamp from POSIX `gettimeofday()`. 66 | // 67 | // struct timeval tv; 68 | // gettimeofday(&tv, NULL); 69 | // 70 | // Timestamp timestamp; 71 | // timestamp.set_seconds(tv.tv_sec); 72 | // timestamp.set_nanos(tv.tv_usec * 1000); 73 | // 74 | // Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. 75 | // 76 | // FILETIME ft; 77 | // GetSystemTimeAsFileTime(&ft); 78 | // UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; 79 | // 80 | // // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z 81 | // // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. 82 | // Timestamp timestamp; 83 | // timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); 84 | // timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); 85 | // 86 | // Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. 87 | // 88 | // long millis = System.currentTimeMillis(); 89 | // 90 | // Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) 91 | // .setNanos((int) ((millis % 1000) * 1000000)).build(); 92 | // 93 | // 94 | // Example 5: Compute Timestamp from current time in Python. 95 | // 96 | // timestamp = Timestamp() 97 | // timestamp.GetCurrentTime() 98 | // 99 | // # JSON Mapping 100 | // 101 | // In JSON format, the Timestamp type is encoded as a string in the 102 | // [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the 103 | // format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" 104 | // where {year} is always expressed using four digits while {month}, {day}, 105 | // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional 106 | // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), 107 | // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone 108 | // is required. A proto3 JSON serializer should always use UTC (as indicated by 109 | // "Z") when printing the Timestamp type and a proto3 JSON parser should be 110 | // able to accept both UTC and other timezones (as indicated by an offset). 111 | // 112 | // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 113 | // 01:30 UTC on January 15, 2017. 114 | // 115 | // In JavaScript, one can convert a Date object to this format using the 116 | // standard 117 | // [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) 118 | // method. In Python, a standard `datetime.datetime` object can be converted 119 | // to this format using 120 | // [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with 121 | // the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use 122 | // the Joda Time's [`ISODateTimeFormat.dateTime()`]( 123 | // http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D 124 | // ) to obtain a formatter capable of generating timestamps in this format. 125 | // 126 | // 127 | message Timestamp { 128 | // Represents seconds of UTC time since Unix epoch 129 | // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 130 | // 9999-12-31T23:59:59Z inclusive. 131 | int64 seconds = 1; 132 | 133 | // Non-negative fractions of a second at nanosecond resolution. Negative 134 | // second values with fractions must still have non-negative nanos values 135 | // that count forward in time. Must be from 0 to 999,999,999 136 | // inclusive. 137 | int32 nanos = 2; 138 | } 139 | -------------------------------------------------------------------------------- /p29/test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "gopkg.in/go-playground/validator.v9" 7 | ) 8 | 9 | type Users struct { 10 | Username string `validate:"required,min=6,max=20"` 11 | Password string `validate:"required,min=6,max=20"` 12 | } 13 | 14 | func main() { 15 | user := Users{Username: "jerry", Password: "12345"} 16 | valid := validator.New() 17 | err := valid.Struct(user) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | log.Println("验证成功") 22 | } 23 | -------------------------------------------------------------------------------- /p3/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 9 | "github.com/asim/go-micro/v3" 10 | "github.com/asim/go-micro/v3/registry" 11 | "github.com/asim/go-micro/v3/server" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | // etcd 服务发现 16 | func main() { 17 | 18 | etcdReg := etcd.NewRegistry( 19 | registry.Addrs("127.0.0.1:2379")) 20 | 21 | r := gin.Default() 22 | r.Handle("GET", "/", func(c *gin.Context) { 23 | c.JSON(http.StatusOK, gin.H{ 24 | "code": http.StatusOK, 25 | }) 26 | }) 27 | service := httpServer.NewServer( 28 | server.Address(":8000"), 29 | server.Registry(etcdReg), 30 | ) 31 | hd := service.NewHandler(r) 32 | service.Handle(hd) 33 | srv := micro.NewService( 34 | micro.Server(service), 35 | ) 36 | if err := srv.Run(); err != nil { 37 | log.Println(err.Error()) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /p4/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | 6 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 7 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | "github.com/asim/go-micro/v3/server" 11 | "github.com/gin-gonic/gin" 12 | ) 13 | 14 | // 调用函数返回json数据 15 | func main() { 16 | 17 | etcdReg := etcd.NewRegistry( 18 | registry.Addrs("127.0.0.1:2379")) 19 | 20 | r := gin.Default() 21 | // 路由分组 22 | v1Group := r.Group("/v1") 23 | { 24 | v1Group.Handle("GET", "/prods", func(c *gin.Context) { 25 | c.JSON(http.StatusOK, NewProdList(5)) 26 | }) 27 | } 28 | 29 | service := httpServer.NewServer( 30 | server.Name("ProdSrv"), 31 | server.Address(":8000"), 32 | server.Registry(etcdReg), 33 | ) 34 | 35 | hd := service.NewHandler(r) 36 | service.Handle(hd) 37 | srv := micro.NewService( 38 | micro.Server(service), 39 | ) 40 | 41 | srv.Run() 42 | } 43 | -------------------------------------------------------------------------------- /p4/prodModels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "strconv" 4 | 5 | // ProdModel 商品模型 6 | type ProdModel struct { 7 | // ProdID 商品Id 8 | ProdID int `json:"prod_id"` 9 | // ProdName 商品名称 10 | ProdName string `json:"prod_name"` 11 | } 12 | 13 | // NewProd 新增产品 14 | func NewProd(id int, name string) *ProdModel { 15 | return &ProdModel{ProdID: id, ProdName: name} 16 | } 17 | 18 | // NewProdList 产品列表 19 | func NewProdList(n int) []*ProdModel { 20 | ret := make([]*ProdModel, 0) 21 | for i := 0; i < n; i++ { 22 | ret = append(ret, NewProd(100+i, "Prod"+strconv.Itoa(100+i))) 23 | } 24 | return ret 25 | } 26 | -------------------------------------------------------------------------------- /p5/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 7 | "github.com/asim/go-micro/v3/registry" 8 | "github.com/asim/go-micro/v3/selector" 9 | ) 10 | 11 | // consul 服务发现 selector随机选择 12 | // 前提是要启动前面的ProdSrv服务 13 | 14 | func main() { 15 | // consul连接句柄 16 | etcdReg := etcd.NewRegistry( 17 | registry.Addrs("127.0.0.1:2379")) 18 | 19 | // 获取服务 20 | getService, err := etcdReg.GetService("ProdSrv") 21 | if err != nil { 22 | log.Fatalf("get service failed, err:%v\n", err) 23 | return 24 | } 25 | 26 | next := selector.Random(getService) 27 | 28 | node, err := next() 29 | if err != nil { 30 | log.Fatalln(err) 31 | return 32 | } 33 | 34 | // 打印服务节点信息 35 | log.Println(node.Address) 36 | 37 | } 38 | -------------------------------------------------------------------------------- /p6/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | 6 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 7 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | "github.com/asim/go-micro/v3/server" 11 | "github.com/gin-gonic/gin" 12 | ) 13 | 14 | // 命令行参数 15 | func main() { 16 | 17 | etcdReg := etcd.NewRegistry( 18 | registry.Addrs("127.0.0.1:2379")) 19 | 20 | r := gin.Default() 21 | // 路由分组 22 | v1Group := r.Group("/v1") 23 | { 24 | v1Group.Handle("GET", "/prods", func(c *gin.Context) { 25 | c.JSON(http.StatusOK, NewProdList(5)) 26 | }) 27 | } 28 | 29 | service := httpServer.NewServer( 30 | server.Name("ProdSrv"), 31 | server.Registry(etcdReg), 32 | ) 33 | 34 | hd := service.NewHandler(r) 35 | service.Handle(hd) 36 | 37 | srv := micro.NewService( 38 | micro.Server(service), 39 | ) 40 | // 通过命令行参数启动 41 | // --server_address 指定地址端口,或者环境变量$MICRO_SERVER_ADDRESS] 42 | // 运行2个服务 43 | // go run main.go prodModels.go --server_address 127.0.0.1:8000 44 | // go run main.go prodModels.go --server_address 127.0.0.1:8001 45 | srv.Init() 46 | srv.Run() 47 | } 48 | -------------------------------------------------------------------------------- /p6/prodModels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "strconv" 4 | 5 | // ProdModel 商品模型 6 | type ProdModel struct { 7 | ProdID int `json:"prod_id"` 8 | ProdName string `json:"prod_name"` 9 | } 10 | 11 | // NewProd 模拟prod 12 | func NewProd(id int, name string) *ProdModel { 13 | return &ProdModel{ProdID: id, ProdName: name} 14 | } 15 | 16 | // NewProdList 根据指定size返回产品 17 | func NewProdList(n int) []*ProdModel { 18 | ret := make([]*ProdModel, 0) 19 | for i := 0; i < n; i++ { 20 | ret = append(ret, NewProd(100+i, "Prod"+strconv.Itoa(100+i))) 21 | } 22 | return ret 23 | } 24 | -------------------------------------------------------------------------------- /p7/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "time" 6 | 7 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 8 | "github.com/asim/go-micro/v3/registry" 9 | "github.com/asim/go-micro/v3/selector" 10 | ) 11 | 12 | // consul 通过轮询获取服务 13 | // 使用前面的方法同时运行3个相同的服务 14 | // 并测试其它节点关闭时不影响业务 15 | 16 | func main() { 17 | 18 | // etcd连接句柄 19 | etcdReg := etcd.NewRegistry( 20 | registry.Addrs("127.0.0.1:2379")) 21 | for { 22 | // 获取服务 23 | getService, err := etcdReg.GetService("ProdSrv") 24 | if err != nil { 25 | log.Fatalf("get service failed, err:%v\n", err) 26 | return 27 | } 28 | 29 | next := selector.RoundRobin(getService) 30 | 31 | node, err := next() 32 | if err != nil { 33 | log.Fatalln(err) 34 | return 35 | } 36 | 37 | log.Println(node.Address) 38 | time.Sleep(time.Second) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /p7/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | 6 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 7 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | "github.com/asim/go-micro/v3/server" 11 | "github.com/gin-gonic/gin" 12 | ) 13 | 14 | // 商品服务 15 | func main() { 16 | 17 | etcdReg := etcd.NewRegistry( 18 | registry.Addrs("127.0.0.1:2379")) 19 | 20 | r := gin.Default() 21 | // 路由分组 22 | v1Group := r.Group("/v1") 23 | { 24 | v1Group.Handle("GET", "/prods", func(c *gin.Context) { 25 | c.JSON(http.StatusOK, NewProdList(5)) 26 | }) 27 | } 28 | 29 | service := httpServer.NewServer( 30 | server.Name("ProdSrv"), 31 | server.Registry(etcdReg), 32 | ) 33 | 34 | hd := service.NewHandler(r) 35 | service.Handle(hd) 36 | 37 | srv := micro.NewService( 38 | micro.Server(service), 39 | ) 40 | // 通过命令行参数启动 41 | // --server_address 指定地址端口,或者环境变量$MICRO_SERVER_ADDRESS] 42 | // 运行2个服务 43 | // go run main.go prodModels.go --server_address 127.0.0.1:8000 44 | // go run main.go prodModels.go --server_address 127.0.0.1:8001 45 | srv.Init() 46 | srv.Run() 47 | } 48 | -------------------------------------------------------------------------------- /p7/prodModels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "strconv" 4 | 5 | // ProdModel 商品模型 6 | type ProdModel struct { 7 | ProdID int `json:"prod_id"` 8 | ProdName string `json:"prod_name"` 9 | } 10 | 11 | // NewProd 模拟产品 12 | func NewProd(id int, name string) *ProdModel { 13 | return &ProdModel{ProdID: id, ProdName: name} 14 | } 15 | 16 | // NewProdList 根据请求的size返回产品数量 17 | func NewProdList(n int) []*ProdModel { 18 | ret := make([]*ProdModel, 0) 19 | for i := 0; i < n; i++ { 20 | ret = append(ret, NewProd(100+i, "Prod"+strconv.Itoa(100+i))) 21 | } 22 | return ret 23 | } 24 | -------------------------------------------------------------------------------- /p8/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "log" 6 | "net/http" 7 | 8 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | "github.com/asim/go-micro/v3/selector" 11 | ) 12 | 13 | // etcd 通过轮询获取服务 14 | // 前提启动之前多个后端服务 15 | // 基本方式调用后端服务 16 | 17 | func callAPI(addr, path, method string) (string, error) { 18 | req, _ := http.NewRequest(method, "http://"+addr+path, nil) 19 | client := http.DefaultClient 20 | res, err := client.Do(req) 21 | if err != nil { 22 | return "", err 23 | } 24 | defer res.Body.Close() 25 | buf, err := ioutil.ReadAll(res.Body) 26 | if err != nil { 27 | return "", err 28 | } 29 | return string(buf), nil 30 | } 31 | 32 | func main() { 33 | // etcd连接句柄 34 | etcdReg := etcd.NewRegistry( 35 | registry.Addrs("127.0.0.1:2379")) 36 | 37 | // 获取服务 38 | getService, err := etcdReg.GetService("ProdSrv") 39 | if err != nil { 40 | log.Fatalf("get service failed, err:%v\n", err) 41 | return 42 | } 43 | 44 | next := selector.RoundRobin(getService) 45 | 46 | node, err := next() 47 | if err != nil { 48 | log.Fatalln(err) 49 | return 50 | } 51 | 52 | res, err := callAPI(node.Address, "/v1/prods", "GET") 53 | if err != nil { 54 | log.Fatal(err) 55 | return 56 | } 57 | log.Println(res) 58 | 59 | } 60 | -------------------------------------------------------------------------------- /p8/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | 6 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 7 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | "github.com/asim/go-micro/v3/server" 11 | "github.com/gin-gonic/gin" 12 | ) 13 | 14 | // 商品服务 15 | func main() { 16 | 17 | etcdReg := etcd.NewRegistry( 18 | registry.Addrs("127.0.0.1:2379")) 19 | 20 | r := gin.Default() 21 | // 路由分组 22 | v1Group := r.Group("/v1") 23 | { 24 | v1Group.Handle("GET", "/prods", func(c *gin.Context) { 25 | c.JSON(http.StatusOK, NewProdList(5)) 26 | }) 27 | } 28 | 29 | service := httpServer.NewServer( 30 | server.Name("ProdSrv"), 31 | server.Registry(etcdReg), 32 | ) 33 | 34 | hd := service.NewHandler(r) 35 | service.Handle(hd) 36 | 37 | srv := micro.NewService( 38 | micro.Server(service), 39 | ) 40 | // 通过命令行参数启动 41 | // --server_address 指定地址端口,或者环境变量$MICRO_SERVER_ADDRESS] 42 | // 运行2个服务 43 | // go run main.go prodModels.go --server_address 127.0.0.1:8000 44 | // go run main.go prodModels.go --server_address 127.0.0.1:8001 45 | srv.Init() 46 | srv.Run() 47 | } 48 | -------------------------------------------------------------------------------- /p8/prodModels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "strconv" 4 | 5 | // ProdModel 商品模型 6 | type ProdModel struct { 7 | ProdID int `json:"prod_id"` 8 | ProdName string `json:"prod_name"` 9 | } 10 | 11 | // NewProd 新增商品 12 | func NewProd(id int, name string) *ProdModel { 13 | return &ProdModel{ProdID: id, ProdName: name} 14 | } 15 | 16 | // NewProdList 根据前端请求的size返回商品数量 17 | func NewProdList(n int) []*ProdModel { 18 | ret := make([]*ProdModel, 0) 19 | for i := 0; i < n; i++ { 20 | ret = append(ret, NewProd(100+i, "Prod"+strconv.Itoa(i))) 21 | } 22 | return ret 23 | } 24 | -------------------------------------------------------------------------------- /p9/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | httpServer "github.com/asim/go-micro/plugins/client/http/v3" 8 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 9 | "github.com/asim/go-micro/v3/client" 10 | "github.com/asim/go-micro/v3/registry" 11 | "github.com/asim/go-micro/v3/selector" 12 | ) 13 | 14 | // 由于http的插件还是1.0的,其它的client还是使用v1版本 15 | // etcd 通过轮询获取服务 16 | // 使用插件 调用http api 17 | func callAPI(s selector.Selector) (map[string]interface{}, error) { 18 | myClient := httpServer.NewClient( 19 | client.Selector(s), 20 | client.ContentType("application/json"), 21 | ) 22 | // 请求对象 23 | req := myClient.NewRequest("ProdSrv", "/v1/prods", map[string]string{}) 24 | // 响应对象 25 | var rsp map[string]interface{} 26 | err := myClient.Call(context.Background(), req, &rsp) 27 | if err != nil { 28 | return nil, err 29 | } 30 | return rsp, nil 31 | } 32 | 33 | func main() { 34 | // etcd 连接句柄 35 | etcdReg := etcd.NewRegistry( 36 | registry.Addrs("127.0.0.1:2379")) 37 | 38 | sel := selector.NewSelector( 39 | selector.Registry(etcdReg), 40 | selector.SetStrategy(selector.RoundRobin), 41 | ) 42 | resp, err := callAPI(sel) 43 | if err != nil { 44 | fmt.Print(err.Error()) 45 | return 46 | } 47 | fmt.Println(resp["data"]) 48 | } 49 | -------------------------------------------------------------------------------- /p9/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | 6 | etcd "github.com/asim/go-micro/plugins/registry/etcd/v3" 7 | httpServer "github.com/asim/go-micro/plugins/server/http/v3" 8 | "github.com/asim/go-micro/v3" 9 | "github.com/asim/go-micro/v3/registry" 10 | "github.com/asim/go-micro/v3/server" 11 | "github.com/gin-gonic/gin" 12 | ) 13 | 14 | // 商品服务 15 | func main() { 16 | 17 | etcdReg := etcd.NewRegistry( 18 | registry.Addrs("127.0.0.1:2379")) 19 | 20 | r := gin.Default() 21 | // 路由分组 22 | v1Group := r.Group("/v1") 23 | { 24 | v1Group.Handle("POST", "/prods", func(c *gin.Context) { 25 | c.JSON(http.StatusOK, gin.H{ 26 | "data": NewProdList(2), 27 | }) 28 | }) 29 | } 30 | 31 | service := httpServer.NewServer( 32 | server.Name("ProdSrv"), 33 | server.Registry(etcdReg), 34 | ) 35 | 36 | hd := service.NewHandler(r) 37 | service.Handle(hd) 38 | 39 | srv := micro.NewService( 40 | micro.Server(service), 41 | ) 42 | // 通过命令行参数启动 43 | // --server_address 指定地址端口,或者环境变量$MICRO_SERVER_ADDRESS] 44 | // 运行2个服务 45 | // go run main.go prodModels.go --server_address 127.0.0.1:8000 46 | // go run main.go prodModels.go --server_address 127.0.0.1:8001 47 | srv.Init() 48 | srv.Run() 49 | } 50 | -------------------------------------------------------------------------------- /p9/prodModels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "strconv" 4 | 5 | // ProdModel 商品模型 6 | type ProdModel struct { 7 | ProdID int `json:"prod_id"` 8 | ProdName string `json:"prod_name"` 9 | } 10 | 11 | // NewProd 新增商品 12 | func NewProd(id int, name string) *ProdModel { 13 | return &ProdModel{ProdID: id, ProdName: name} 14 | } 15 | 16 | // NewProdList 根据前端请求的size返回商品数量 17 | func NewProdList(n int) []*ProdModel { 18 | ret := make([]*ProdModel, 0) 19 | for i := 0; i < n; i++ { 20 | ret = append(ret, NewProd(100+i, "Prod"+strconv.Itoa(100+i))) 21 | } 22 | return ret 23 | } 24 | --------------------------------------------------------------------------------