最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go-zero?rpc分布式微服務(wù)使用詳解

 更新時(shí)間:2026年01月05日 10:44:52   作者:胡蘿卜的兔  
文章介紹了如何安裝Go環(huán)境、配置Go環(huán)境、安裝goctl工具以及創(chuàng)建第一個(gè)項(xiàng)目,詳細(xì)的步驟包括生成項(xiàng)目、配置文件、啟動(dòng)服務(wù)、測(cè)試項(xiàng)目等,文章還涵蓋了Go?Zero框架的基本概念,如API定義、服務(wù)間通信、業(yè)務(wù)邏輯實(shí)現(xiàn)等

安裝go必要環(huán)境

下載go

https://go.dev/dl/

# inter版本
https://go.dev/dl/go1.25.5.windows-amd64.msi

配置GOROOT

配置代理

安裝goctl工具

 go install github.com/zeromicro/go-zero/tools/goctl@latest

goctl --version

出現(xiàn)下面的信息說(shuō)明go-zero安裝成功

創(chuàng)建第一個(gè)項(xiàng)目

初始化api項(xiàng)目

goctl api new user

查看生成的項(xiàng)目

下載依賴(lài)

切換到user目錄,下載依賴(lài)

 cd user
 go mod tidy

結(jié)果

 cd user
PS E:\work\golang\demo\user> go mod tidy
go: finding module for package github.com/zeromicro/go-zero/core/logx
go: finding module for package github.com/zeromicro/go-zero/rest
go: finding module for package github.com/zeromicro/go-zero/core/conf
go: finding module for package github.com/zeromicro/go-zero/rest/httpx
go: found github.com/zeromicro/go-zero/core/conf in github.com/zeromicro/go-zero v1.9.4
go: found github.com/zeromicro/go-zero/rest in github.com/zeromicro/go-zero v1.9.4
go: found github.com/zeromicro/go-zero/rest/httpx in github.com/zeromicro/go-zero v1.9.4
go: found github.com/zeromicro/go-zero/core/logx in github.com/zeromicro/go-zero v1.9.4
go: downloading github.com/stretchr/testify v1.11.1
go: downloading github.com/google/uuid v1.6.0
go: downloading k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
go: downloading github.com/golang-jwt/jwt/v4 v4.5.2
go: downloading gopkg.in/h2non/gock.v1 v1.1.2
go: downloading github.com/google/go-cmp v0.6.0
go: downloading google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094
go: downloading github.com/kylelemons/godebug v1.1.0
go: downloading github.com/prometheus/procfs v0.15.1
go: downloading go.uber.org/goleak v1.3.0
go: downloading github.com/stretchr/objx v0.5.2
go: downloading github.com/davecgh/go-spew v1.1.1
go: downloading github.com/pmezard/go-difflib v1.0.0
go: downloading github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542
go: downloading gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
go: downloading github.com/kr/pretty v0.3.1
go: downloading github.com/prashantv/gostub v1.1.0
go: downloading github.com/rogpeppe/go-internal v1.10.0
go: downloading github.com/kr/text v0.2.0

運(yùn)行user模塊

運(yùn)行啟動(dòng)user模塊

go run user.go   
Starting server at 0.0.0.0:8888...

生成文件詳細(xì)解釋

配置文件

  • user/etc/user-api.yaml
Name: user-api # 服務(wù)名
Host: 0.0.0.0 # 主機(jī)
Port: 8888 #端口

定義協(xié)議

  • user/user.api
syntax = "v1" # 版本

# 請(qǐng)求 `type`  對(duì)于生成的Request  在`user/internal/types/types.go` 的 	`Request`
type Request {
	Name string `path:"name,options=you|me"`
}

# 響應(yīng)  `type` 對(duì)于生成的Response 在`user/internal/types/types.go` 的 	`Response`
type Response {
	Message string `json:"message"`
}

# 方法, UserHandler在`user/internal/handler/userhandler.go`里
service user-api {
	@handler UserHandler
	get /from/:name (Request) returns (Response)
}


類(lèi)型type

  • user/internal/types/types.go
package types

type Request struct {
	Name string `path:"name,options=you|me"`
}

type Response struct {
	Message string `json:"message"`
}

svc 上下文

// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2

package svc

import (
	"demo/user/internal/config"
)

type ServiceContext struct {
	Config config.Config
}

func NewServiceContext(c config.Config) *ServiceContext {
	return &ServiceContext{
		Config: c,
	}
}

邏輯logic

// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2

package logic

import (
	"context"
	"demo/user/internal/svc"
	"demo/user/internal/types"
	"github.com/zeromicro/go-zero/core/logx"
)

type UserLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserLogic {
	return &UserLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UserLogic) User(req *types.Request) (resp *types.Response, err error) {
	// todo: add your logic here and delete this line
	return &types.Response{
		Message: "===========Hello World==========",
	}, nil
}

路由

// Code generated by goctl. DO NOT EDIT.
// goctl 1.9.2

package handler

import (
	"net/http"

	"demo/user/internal/svc"

	"github.com/zeromicro/go-zero/rest"
)

func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
	server.AddRoutes(
		[]rest.Route{
			{
				Method:  http.MethodGet,
				Path:    "/from/:name",
				Handler: UserHandler(serverCtx),
			},
		},
	)
}

瀏覽器查看

http://127.0.0.1:8888/from/you

http://127.0.0.1:8888/from/wo

知識(shí)總結(jié)

熱加載

下載air

方便開(kāi)發(fā)

go install github.com/air-verse/air@latest
 
air -v

運(yùn)行

不再運(yùn)行 go run user

air 

Thunder Client 測(cè)試

vscode 安裝插件

go-zero項(xiàng)目解析

GRPC demo代碼生成

grpc服務(wù)是和http服務(wù)分開(kāi)的,不可以混為一談

例如:同為user模塊,既可以提供http服務(wù),也可以提供rpc服務(wù)

如果提供http服務(wù),命令行如下:

cd /user
go run user.go

如果提供rpc服務(wù),相應(yīng)的配置,proto文件等需要生成。這里只講啟動(dòng)

cd /user/rpc
go run user.go

以car項(xiàng)目為例

goctl rpc new car

創(chuàng)建過(guò)程

goctl rpc new car
go: downloading google.golang.org/protobuf v1.36.11
go: downloading google.golang.org/grpc v1.78.0
go: downloading google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.0
go: downloading google.golang.org/protobuf v1.36.10
Done.

切換到car目錄下拉去依賴(lài)

go mod tidy

運(yùn)行

會(huì)報(bào)錯(cuò)

go run car

編輯該文件

internal/logic/pinglogic.go

商城微服務(wù) shop

規(guī)劃

服務(wù)http端口
user-api8881
user-rpc8882
order-api8883
order-rpc8884
product-api8885
product-rpc8886
cart-api8887
cart-rpc8888
product-api8887
product-rpc8888
gateway-api8889
gateway-rpc8890

創(chuàng)建項(xiàng)目

mkdir -p shop/api
cd shop

初始化init mod

go mod init finejade/shop-mall

定義 API 文件

網(wǎng)關(guān)服務(wù) api/gateway.api

// api/gateway.api
info (
	title:   "Shop Mall Gateway API"
	desc:    "API Gateway for the distributed shop mall system."
	author:  "Your Name"
	email:   "your.email@example.com"
	version: "1.0.0"
)

// 1. 定義所有路由所需的具體請(qǐng)求和響應(yīng)結(jié)構(gòu)體
//    這些結(jié)構(gòu)體必須與各自微服務(wù) .api 文件中的定義保持一致!
type (
	// --- 用戶(hù)服務(wù) (user.api) ---
	UserRegisterReq {
		Username string `json:"username"`
		Password string `json:"password"`
		Email    string `json:"email"`
	}
	UserRegisterResp {
		Id int64 `json:"id"`
	}
	UserLoginReq {
		Username string `json:"username"`
		Password string `json:"password"`
	}
	UserLoginResp {
		Token string `json:"token"`
	}
	GetUserInfoReq {
		// 實(shí)際項(xiàng)目中,用戶(hù)ID通常從JWT Token解析,這里僅為演示
		UserId int64 `json:"userId"`
	}
	UserInfo {
		Id       int64  `json:"id"`
		Username string `json:"username"`
		Email    string `json:"email"`
	}
	GetUserInfoResp {
		User UserInfo `json:"user"`
	}
	// --- 商品服務(wù) (product.api) ---
	GetProductListReq {
		Page     int `form:"page,default=1"`
		PageSize int `form:"pageSize,default=10"`
	}
	ProductItem {
		Id       int64   `json:"id"`
		Name     string  `json:"name"`
		Price    float64 `json:"price"`
		ImageUrl string  `json:"imageUrl"`
	}
	GetProductListResp {
		List  []ProductItem `json:"list"`
		Total int64         `json:"total"`
	}
	GetProductDetailReq {
		Id int64 `path:"id"`
	}
	GetProductDetailResp {
		Product ProductItem `json:"product"`
	}
	// --- 購(gòu)物車(chē)服務(wù) (cart.api) ---
	AddToCartReq {
		UserId    int64 `json:"userId"`
		ProductId int64 `json:"productId"`
		Quantity  int   `json:"quantity"`
	}
	GetCartListReq {
		UserId int64 `json:"userId"`
	}
	CartItem {
		ProductId   int64   `json:"productId"`
		ProductName string  `json:"productName"`
		Price       float64 `json:"price"`
		Quantity    int     `json:"quantity"`
	}
	GetCartListResp {
		Items []CartItem `json:"items"`
	}
	UpdateCartItemReq {
		UserId    int64 `json:"userId"`
		ProductId int64 `json:"productId"`
		Quantity  int   `json:"quantity"`
	}
	DeleteCartItemReq {
		UserId    int64 `json:"userId"`
		ProductId int64 `json:"productId"`
	}
	// --- 訂單服務(wù) (order.api) ---
	CreateOrderReq {
		UserId  int64  `json:"userId"`
		Address string `json:"address"`
	}
	CreateOrderResp {
		OrderId int64 `json:"orderId"`
	}
	GetOrderListReq {
		UserId int64 `json:"userId"`
	}
	OrderInfo {
		Id         int64   `json:"id"`
		TotalPrice float64 `json:"totalPrice"`
		Status     string  `json:"status"`
		CreateTime string  `json:"createTime"`
	}
	GetOrderListResp {
		Orders []OrderInfo `json:"orders"`
	}
	GetOrderDetailReq {
		Id int64 `path:"id"`
	}
	GetOrderDetailResp {
		Order OrderInfo `json:"order"`
	}
	// --- 支付服務(wù) (payment.api) ---
	CreatePaymentReq {
		OrderId int64  `json:"orderId"`
		Method  string `json:"method"`
	}
	CreatePaymentResp {
		PaymentUrl string `json:"paymentUrl"`
	}
	PaymentNotifyReq {
		OutTradeNo  string `json:"out_trade_no"`
		TradeStatus string `json:"trade_status"`
	}
	PaymentNotifyResp {
		Code string `json:"code"`
		Msg  string `json:"msg"`
	}
	// 2. 定義網(wǎng)關(guān)統(tǒng)一的、最終的對(duì)外響應(yīng)格式
	GatewayResponse {
		Code int         `json:"code"` // 業(yè)務(wù)狀態(tài)碼, 0 代表成功
		Msg  string      `json:"msg"` // 提示信息
		Data interface{} `json:"data"` // 響應(yīng)數(shù)據(jù),這里可以是任意類(lèi)型
	}
)

// 3. 在 service 塊中,為每個(gè)路由指定其具體的請(qǐng)求和響應(yīng)類(lèi)型
service gateway-api {
	// --- 用戶(hù)服務(wù)路由 ---
	@doc "用戶(hù)注冊(cè)"
	@handler userRegisterHandler
	post /api/user/register (UserRegisterReq) returns (GatewayResponse)

	@doc "用戶(hù)登錄"
	@handler userLoginHandler
	post /api/user/login (UserLoginReq) returns (GatewayResponse)

	@doc "獲取用戶(hù)信息"
	@handler getUserInfoHandler
	get /api/user/info (GetUserInfoReq) returns (GatewayResponse)

	// --- 商品服務(wù)路由 ---
	@doc "獲取商品列表"
	@handler getProductListHandler
	get /api/product/list (GetProductListReq) returns (GatewayResponse)

	@doc "獲取商品詳情"
	@handler getProductDetailHandler
	get /api/product/:id (GetProductDetailReq) returns (GatewayResponse)

	// --- 購(gòu)物車(chē)服務(wù)路由 ---
	@doc "添加商品到購(gòu)物車(chē)"
	@handler addToCartHandler
	post /api/cart/add (AddToCartReq) returns (GatewayResponse)

	@doc "獲取購(gòu)物車(chē)列表"
	@handler getCartListHandler
	get /api/cart/list (GetCartListReq) returns (GatewayResponse)

	@doc "更新購(gòu)物車(chē)商品數(shù)量"
	@handler updateCartItemHandler
	post /api/cart/update (UpdateCartItemReq) returns (GatewayResponse)

	@doc "刪除購(gòu)物車(chē)商品"
	@handler deleteCartItemHandler
	post /api/cart/delete (DeleteCartItemReq) returns (GatewayResponse)

	// --- 訂單服務(wù)路由 ---
	@doc "創(chuàng)建訂單"
	@handler createOrderHandler
	post /api/order/create (CreateOrderReq) returns (GatewayResponse)

	@doc "獲取訂單列表"
	@handler getOrderListHandler
	get /api/order/list (GetOrderListReq) returns (GatewayResponse)

	@doc "獲取訂單詳情"
	@handler getOrderDetailHandler
	get /api/order/:id (GetOrderDetailReq) returns (GatewayResponse)

	// --- 支付服務(wù)路由 ---
	@doc "創(chuàng)建支付"
	@handler createPaymentHandler
	post /api/payment/create (CreatePaymentReq) returns (GatewayResponse)

	@doc "支付回調(diào)通知"
	@handler paymentNotifyHandler
	post /api/payment/notify (PaymentNotifyReq) returns (PaymentNotifyResp)
}


}

用戶(hù)服務(wù) api/user.api

info(
    title: "User Service API"
    desc: "Provides user registration, login, and profile management."
    author: "Your Name"
    email: "your.email@example.com"
    version: "1.0.0"
)

type (
    // --- 請(qǐng)求結(jié)構(gòu)體 ---
    RegisterReq {
        Username string `json:"username"`
        Password string `json:"password"`
        Email    string `json:"email"`
    }

    LoginReq {
        Username string `json:"username"`
        Password string `json:"password"`
    }

    GetUserInfoReq {
        // 實(shí)際項(xiàng)目中,用戶(hù)ID通常從JWT Token中解析,這里僅作示例
        UserId int64 `json:"userId"`
    }

    // --- 響應(yīng)結(jié)構(gòu)體 ---
    RegisterResp {
        Id int64 `json:"id"`
    }

    LoginResp {
        Token string `json:"token"`
    }

    UserInfo {
        Id       int64  `json:"id"`
        Username string `json:"username"`
        Email    string `json:"email"`
        Nickname string `json:"nickname"`
        Avatar   string `json:"avatar"`
    }
    
    GetUserInfoResp {
        User UserInfo `json:"user"`
    }

    // 統(tǒng)一響應(yīng)
    UserResponse {
        Code int         `json:"code"`
        Msg  string      `json:"msg"`
        Data interface{} `json:"data"`
    }
)

service user-api {
    @handler registerHandler
    post /user/register (RegisterReq) returns (UserResponse)

    @handler loginHandler
    post /user/login (LoginReq) returns (UserResponse)

    @handler getUserInfoHandler
    get /user/info (GetUserInfoReq) returns (UserResponse)
}

商品服務(wù) (api/product.api)

info(
    title: "Product Service API"
    desc: "Provides product listing and detail information."
    author: "Your Name"
    email: "your.email@example.com"
    version: "1.0.0"
)

type (
    // --- 請(qǐng)求結(jié)構(gòu)體 ---
    GetProductListReq {
        Page     int `form:"page,default=1"`
        PageSize int `form:"pageSize,default=10"`
    }

    GetProductDetailReq {
        Id int64 `path:"id"`
    }

    // --- 響應(yīng)結(jié)構(gòu)體 ---
    ProductItem {
        Id          int64   `json:"id"`
        Name        string  `json:"name"`
        Price       float64 `json:"price"`
        Description string  `json:"description"`
        Stock       int     `json:"stock"`
        ImageUrl    string  `json:"imageUrl"`
    }

    GetProductListResp {
        List  []ProductItem `json:"list"`
        Total int64         `json:"total"`
    }

    GetProductDetailResp {
        Product ProductItem `json:"product"`
    }

    // 統(tǒng)一響應(yīng)
    ProductResponse {
        Code int         `json:"code"`
        Msg  string      `json:"msg"`
        Data interface{} `json:"data"`
    }
)

service product-api {
    @handler getProductListHandler
    get /product/list (GetProductListReq) returns (ProductResponse)

    @handler getProductDetailHandler
    get /product/:id (GetProductDetailReq) returns (ProductResponse)
}

購(gòu)物車(chē)服務(wù) (cart.api)

info(
    title: "Cart Service API"
    desc: "Manages user shopping cart items."
    author: "Your Name"
    email: "your.email@example.com"
    version: "1.0.0"
)

type (
    // --- 請(qǐng)求結(jié)構(gòu)體 ---
    AddToCartReq {
        UserId    int64 `json:"userId"`
        ProductId int64 `json:"productId"`
        Quantity  int   `json:"quantity"`
    }

    GetCartListReq {
        UserId int64 `json:"userId"`
    }

    UpdateCartItemReq {
        UserId    int64 `json:"userId"`
        ProductId int64 `json:"productId"`
        Quantity  int   `json:"quantity"`
    }

    DeleteCartItemReq {
        UserId    int64 `json:"userId"`
        ProductId int64 `json:"productId"`
    }

    // --- 響應(yīng)結(jié)構(gòu)體 ---
    CartItem {
        ProductId   int64   `json:"productId"`
        ProductName string  `json:"productName"`
        Price       float64 `json:"price"`
        Quantity    int     `json:"quantity"`
        ImageUrl    string  `json:"imageUrl"`
    }

    GetCartListResp {
        Items []CartItem `json:"items"`
    }
    
    // 統(tǒng)一響應(yīng)
    CartResponse {
        Code int         `json:"code"`
        Msg  string      `json:"msg"`
        Data interface{} `json:"data"`
    }
)

service cart-api {
    @handler addToCartHandler
    post /cart/add (AddToCartReq) returns (CartResponse)

    @handler getCartListHandler
    get /cart/list (GetCartListReq) returns (CartResponse)

    @handler updateCartItemHandler
    post /cart/update (UpdateCartItemReq) returns (CartResponse)

    @handler deleteCartItemHandler
    post /cart/delete (DeleteCartItemReq) returns (CartResponse)
}

訂單服務(wù) (order.api)

info(
    title: "Order Service API"
    desc: "Manages the entire order lifecycle, from creation to fulfillment."
    author: "Your Name"
    email: "your.email@example.com"
    version: "1.0.0"
)

type (
    // --- 請(qǐng)求結(jié)構(gòu)體 ---
    CreateOrderReq {
        UserId  int64 `json:"userId"`
        // 實(shí)際項(xiàng)目中,地址信息會(huì)更復(fù)雜,這里簡(jiǎn)化
        Address string `json:"address"`
    }

    GetOrderListReq {
        UserId int64 `json:"userId"`
    }

    GetOrderDetailReq {
        OrderId int64 `path:"id"`
    }

    // --- 響應(yīng)結(jié)構(gòu)體 ---
    OrderItem {
        ProductId   int64   `json:"productId"`
        ProductName string  `json:"productName"`
        Price       float64 `json:"price"`
        Quantity    int     `json:"quantity"`
    }

    OrderInfo {
        Id         int64       `json:"id"`
        UserId     int64       `json:"userId"`
        TotalPrice float64     `json:"totalPrice"`
        Status     string      `json:"status"` // e.g., "pending_payment", "paid", "shipped"
        Items      []OrderItem `json:"items"`
        CreateTime string      `json:"createTime"`
    }

    CreateOrderResp {
        OrderId int64 `json:"orderId"`
    }

    GetOrderListResp {
        Orders []OrderInfo `json:"orders"`
    }

    GetOrderDetailResp {
        Order OrderInfo `json:"order"`
    }

    // 統(tǒng)一響應(yīng)
    OrderResponse {
        Code int         `json:"code"`
        Msg  string      `json:"msg"`
        Data interface{} `json:"data"`
    }
)

service order-api {
    @handler createOrderHandler
    post /order/create (CreateOrderReq) returns (OrderResponse)

    @handler getOrderListHandler
    get /order/list (GetOrderListReq) returns (OrderResponse)

    @handler getOrderDetailHandler
    get /order/:id (GetOrderDetailReq) returns (OrderResponse)
}

支付服務(wù) (payment.api)

info(
    title: "Payment Service API"
    desc: "Handles payment processing and payment notifications."
    author: "Your Name"
    email: "your.email@example.com"
    version: "1.0.0"
)

type (
    // --- 請(qǐng)求結(jié)構(gòu)體 ---
    CreatePaymentReq {
        OrderId int64 `json:"orderId"`
        // 支付方式, e.g., "alipay", "wechat"
        Method  string `json:"method"`
    }

    // 支付回調(diào)的請(qǐng)求體通常由第三方支付平臺(tái)定義,這里簡(jiǎn)化
    PaymentNotifyReq {
        OutTradeNo  string `json:"out_trade_no"`
        TradeStatus string `json:"trade_status"`
        // ... 其他回調(diào)參數(shù)
    }

    // --- 響應(yīng)結(jié)構(gòu)體 ---
    CreatePaymentResp {
        // 支付鏈接或參數(shù),前端需要用它來(lái)喚起支付
        PaymentUrl string `json:"paymentUrl"`
    }
    
    // 支付回調(diào)的響應(yīng)體也需要符合第三方平臺(tái)的要求,通常是 "success"
    PaymentNotifyResp {
        Code string `json:"code"`
        Msg  string `json:"msg"`
    }

    // 統(tǒng)一響應(yīng)
    PaymentResponse {
        Code int         `json:"code"`
        Msg  string      `json:"msg"`
        Data interface{} `json:"data"`
    }
)

service payment-api {
    @handler createPaymentHandler
    post /payment/create (CreatePaymentReq) returns (PaymentResponse)

    // 注意:支付回調(diào)接口通常是 POST,并且可能需要特殊的簽名驗(yàn)證
    @handler paymentNotifyHandler
    post /payment/notify (PaymentNotifyReq) returns (PaymentNotifyResp)
}

庫(kù)存 api/stock.api

info(
    title: "Stock Service API"
    desc: "Provides stock deduction and management for products."
    author: "Your Name"
    email: "your.email@example.com"
    version: "1.0.0"
)

type (
    // --- 請(qǐng)求結(jié)構(gòu)體 ---
    DeductStockReq {
        ProductId int64  `json:"productId"`
        Quantity  int    `json:"quantity"`
        OrderId   string `json:"orderId"`
    }

    RollbackStockReq {
        ProductId int64  `json:"productId"`
        Quantity  int    `json:"quantity"`
        OrderId   string `json:"orderId"`
    }

    GetStockReq {
        ProductId int64 `path:"productId"`
    }

    // --- 響應(yīng)結(jié)構(gòu)體 ---
    StockResponse {
        Code int         `json:"code"`
        Msg  string      `json:"msg"`
        Data interface{} `json:"data"`
    }

    GetStockData {
        TotalStock     int `json:"totalStock"`
        AvailableStock int `json:"availableStock"`
    }
)

service stock-api {
    @doc "扣減庫(kù)存"
    @handler deductStockHandler
    post /stock/deduct (DeductStockReq) returns (StockResponse)

    @doc "回滾庫(kù)存"
    @handler rollbackStockHandler
    post /stock/rollback (RollbackStockReq) returns (StockResponse)

    @doc "獲取庫(kù)存信息"
    @handler getStockHandler
    get /stock/:productId (GetStockReq) returns (StockResponse)
}

生成各http服務(wù)代碼

# --- 網(wǎng)關(guān)服務(wù) ---
# 網(wǎng)關(guān)通常是一個(gè) API Gateway 類(lèi)型的服務(wù)
goctl api go -api api/gateway.api -dir gateway

# --- 用戶(hù)服務(wù) ---
goctl api go -api api/user.api -dir user

# --- 商品服務(wù) ---
goctl api go -api api/product.api -dir product

# --- 訂單服務(wù) ---
goctl api go -api api/order.api -dir order

# --- 購(gòu)物車(chē)服務(wù) ---
goctl api go -api api/cart.api -dir cart

# --- 支付服務(wù) ---
goctl api go -api api/payment.api -dir payment


# --- 庫(kù)存服務(wù) ---
# 庫(kù)存服務(wù)通常是一個(gè) RPC 服務(wù),用于內(nèi)部服務(wù)間調(diào)用
# 假設(shè)你已經(jīng)定義了 stock.proto
# goctl rpc protoc api/stock.proto --go_out=stock --go-grpc_out=stock --zrpc_out=stock
# 如果先用 API 風(fēng)格開(kāi)發(fā),命令如下:

goctl api go -api api/stock.api -dir stock

ETCD

下載

https://github.com/etcd-io/etcd/tree/v3.6.7

運(yùn)行

啟動(dòng) Etcd: 解壓后,在本地啟動(dòng)一個(gè)單節(jié)點(diǎn)的 Etcd 服務(wù)。

圖形界面

下載

https://github.com/evildecay/etcdkeeper/releases

特點(diǎn)

etcdkeeper 目前最流行、最簡(jiǎn)單易用的 Etcd 可視化工具。它是一個(gè)單文件的二進(jìn)制應(yīng)用,無(wú)需任何依賴(lài),開(kāi)箱即用

特點(diǎn):

  1. 單文件部署:下載一個(gè)二進(jìn)制文件,直接運(yùn)行即可,非常方便。
  2. 界面簡(jiǎn)潔直觀:左側(cè)是目錄樹(shù),右側(cè)是鍵值對(duì),操作簡(jiǎn)單。
  3. 功能全面:支持增、刪、改、查,以及樹(shù)形結(jié)構(gòu)的展示。
  4. 跨平臺(tái):提供 Windows, macOS, Linux 版本。

運(yùn)行

解壓進(jìn)入目錄

etcdkeeper.exe -p 9999
2025/12/30 15:04:22 main.go:103: listening on 0.0.0.0:9999
2025/12/30 15:04:51 main.go:638: POST v3 connect success.
2025/12/30 15:04:51 main.go:701: GET v3 /
2025/12/30 15:04:53 main.go:701: GET v3 user.rpc/7587891840418209374

瀏覽器打開(kāi)

http://127.0.0.1:9999/etcdkeeper/

進(jìn)入左上角設(shè)置用戶(hù)名和密碼

RPC文件生成,配置

在每個(gè)服務(wù)的配置文件中添加 Etcd 配置

你需要修改每個(gè)服務(wù)的 etc/xxx-api.yaml 文件,告訴它們?nèi)绾芜B接到 Etcd。

以 user/etc/user-api.yaml 為例

Name: user-api
Host: 0.0.0.0
Port: 8888
# ... 其他配置 ...

# 新增 Etcd 配置
Etcd:
  Hosts:
  - 127.0.0.1:2379
  Key: user.api # 這個(gè) Key 是服務(wù)在 Etcd 中的唯一標(biāo)識(shí)

服務(wù)間通信 (Inter-Service Communication)

這是微服務(wù)架構(gòu)的核心。我們將以 “訂單服務(wù)調(diào)用用戶(hù)服務(wù)獲取用戶(hù)信息” 為例,演示如何實(shí)現(xiàn)服務(wù)間調(diào)用。

將被調(diào)用方改造為 RPC 服務(wù) (以 user 服務(wù)為例)

HTTP API 服務(wù)主要用于對(duì)外(給前端或網(wǎng)關(guān))提供服務(wù)。服務(wù)間的高效通信應(yīng)該使用 RPC。

創(chuàng)建 user.proto: 在 api 目錄下創(chuàng)建一個(gè) user.proto 文件,定義 user 服務(wù)提供的 RPC 接口。

api/user.proto

syntax = "proto3";

package user;

option go_package = "./user";

message IdRequest {
  int64 id = 1;
}

message UserResponse {
  int64 id = 1;
  string username = 2;
  string email = 3;
}

service User {
  rpc GetUserById(IdRequest) returns (UserResponse);
}

生成 RPC 代碼: 使用 goctl 生成 user 的 RPC 服務(wù)代碼

# 在項(xiàng)目根目錄下執(zhí)行
goctl rpc protoc api/user.proto --go_out=user/rpc --go-grpc_out=user/rpc --zrpc_out=user/rpc

整合 RPC 和 HTTP 服務(wù)

現(xiàn)在 user 目錄下既有 HTTP API 代碼,也有了 RPC 代碼。

你需要在 user.go 中同時(shí)啟動(dòng)這兩個(gè)服務(wù)。

** 1. 在 order 的配置文件中添加 user 服務(wù)的 RPC 配置:**

order/etc/order-api.yaml

Name: order-api
Host: 0.0.0.0
Port: 8889
# ... 其他配置 ...

# 新增要調(diào)用的 user 服務(wù)的 RPC 配置
UserRpc:
  Etcd:
    Hosts:
    - 127.0.0.1:2379
    Key: user.rpc # 這個(gè) Key 必須和 user 服務(wù)在 Etcd 中注冊(cè)的 Key 一致

** 2.新增:在調(diào)用的user服務(wù)的RPC配置 **

RpcClientConf:order/internal/config/config.go

package config

import (
    "github.com/zeromicro/go-zero/rest"
    "github.com/zeromicro/go-zero/zrpc"
)

type Config struct {
    rest.RestConf
    UserRpc zrpc.RpcClientConf // 新增這一行
}

3.在 order 的服務(wù)上下文中初始化 RPC 客戶(hù)端:

order/internal/svc/servicecontext.go

package svc

import (
	"finejade/shop-mall/order/internal/config"
	// 1. 導(dǎo)入生成的 user rpc 客戶(hù)端包
	//    這個(gè)路徑是根據(jù)你的項(xiàng)目結(jié)構(gòu)和 user.proto 中的 go_package 生成的
	"finejade/shop-mall/user/rpc/userclient"

	"github.com/zeromicro/go-zero/zrpc"
)

type ServiceContext struct {
	Config config.Config
	// 2. 在這里聲明一個(gè) UserRpc 客戶(hù)端實(shí)例
	//    它的類(lèi)型是 userclient.User
	UserRpc userclient.User
}

func NewServiceContext(c config.Config) *ServiceContext {
	return &ServiceContext{
		Config: c,
		// 3. 在這里初始化 UserRpc 客戶(hù)端
		//    zrpc.MustNewClient 會(huì)根據(jù)配置自動(dòng)從 Etcd 發(fā)現(xiàn)服務(wù)并創(chuàng)建連接
		UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
	}
}

階段四:實(shí)現(xiàn)業(yè)務(wù)邏輯

  • 現(xiàn)在,基礎(chǔ)設(shè)施已經(jīng)搭建完畢,你可以開(kāi)始填充每個(gè)服務(wù) internal/logic/ 目錄下的業(yè)務(wù)邏輯代碼了。例如:
  • 在 user 服務(wù)中連接數(shù)據(jù)庫(kù),實(shí)現(xiàn)用戶(hù)的增刪改查。
  • 在 product 服務(wù)中實(shí)現(xiàn)商品列表和詳情的查詢(xún)。

在 order 服務(wù)中,實(shí)現(xiàn)創(chuàng)建訂單的完整流程:

  • 調(diào)用 user RPC 驗(yàn)證用戶(hù)信息。
  • 調(diào)用 product RPC 獲取商品價(jià)格。
  • 調(diào)用 stock RPC 預(yù)扣減庫(kù)存。
  • 在本地?cái)?shù)據(jù)庫(kù)創(chuàng)建訂單記錄。
  • 返回訂單 ID。

啟動(dòng)

以u(píng)ser為例,啟動(dòng)user-rpc服務(wù),如果需要,也可以啟動(dòng)user http服務(wù)

  • 1、啟動(dòng)rpc服務(wù)
cd shop/user/rpc
go run user.go
Starting server at 0.0.0.0:8885...
  • 2、啟動(dòng)http服務(wù)
cd shop/user
go run user.go
Starting server at 0.0.0.0:8885...

測(cè)試

訪問(wèn)order服務(wù),通過(guò)rpc查詢(xún)user服務(wù)數(shù)據(jù)

http://127.0.0.1:8881/order/list

改造product模塊為rpc

1. 生成proto3文件

syntax = "proto3";

package product;
option go_package = "./product";
message IdRequest {
  int64 id = 1;
}

message ProductResponse {
  int64 id = 1;
  string name = 2;
  string description = 3;
  float price = 4;
}

service Product {
  rpc GetProductById(IdRequest) returns (ProductResponse);
}

2. 命令生成product rpc

goctl rpc protoc api/product.proto --go_out=product/rpc --go-grpc_out=product/rpc --zrpc_out=product/rpc

3. order調(diào)用添加配置文件

order/etc/order-api.yaml

ProductRpc:
  Etcd:
    Hosts:
      - 127.0.0.1:2379
    Key: product.rpc # 這個(gè) Key 必須和 product 服務(wù)注冊(cè)的 Key 一致

4. 給order.api新增商品名稱(chēng)字段

api/order.api

并且重新生成 order服務(wù)模塊代碼 命令行:

goctl api go -api api/order.api -dir order
	OrderInfo {
		Id       int64  `json:"id"`
		UserId   int64  `json:"userId"`
		UserName string `json:"userName"` // <-- 新增字段,用于存放從 user-rpc 獲取的用戶(hù)名
		//新增商品名稱(chēng)字段
		ProductName string      `json:"productName"`  // 新增字段,用于存放從 product-rpc 獲取的商品名稱(chēng)
		TotalPrice  float64     `json:"totalPrice"`
		Status      string      `json:"status"` // e.g., "pending_payment", "paid", "shipped"
		Items       []OrderItem `json:"items"`
		CreateTime  string      `json:"createTime"`
	}

5. config文件新增product rpc配置

路徑:order/internal/config/config.go

ProductRpc zrpc.RpcClientConf

// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2

package config

import (
	"github.com/zeromicro/go-zero/rest"
	"github.com/zeromicro/go-zero/zrpc"
)

type Config struct {
	rest.RestConf
	// 新增:要調(diào)用的user服務(wù)的RPC配置
	UserRpc zrpc.RpcClientConf
	// 新增:要調(diào)用的product服務(wù)的RPC配置
	ProductRpc zrpc.RpcClientConf
}

6. 聲明product rpc服務(wù)客戶(hù)端

order/internal/svc/servicecontext.go

package svc

import (
	"finejade/shop-mall/order/internal/config"
	"finejade/shop-mall/product/rpc/productclient"

	// 1. 導(dǎo)入生成的 user rpc 客戶(hù)端包
	//    這個(gè)路徑是根據(jù)你的項(xiàng)目結(jié)構(gòu)和 user.proto 中的 go_package 生成的
	"finejade/shop-mall/user/rpc/userclient"

	"github.com/zeromicro/go-zero/zrpc"
)

type ServiceContext struct {
	Config config.Config
	// 2. 在這里聲明一個(gè) UserRpc 客戶(hù)端實(shí)例
	//    它的類(lèi)型是 userclient.User
	UserRpc    userclient.User
	ProductRpc productclient.Product
}

func NewServiceContext(c config.Config) *ServiceContext {
	return &ServiceContext{
		Config: c,
		// 3. 在這里初始化 UserRpc 客戶(hù)端
		//    zrpc.MustNewClient 會(huì)根據(jù)配置自動(dòng)從 Etcd 發(fā)現(xiàn)服務(wù)并創(chuàng)建連接
		UserRpc:    userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
		ProductRpc: productclient.NewProduct(zrpc.MustNewClient(c.ProductRpc)),
	}
}

測(cè)試

http://127.0.0.1:8883/order/list

常用命令

部分命令可能因?yàn)榘姹締?wèn)題有變動(dòng)

命令主要功能實(shí)例
goctl api new快速創(chuàng)建新項(xiàng)目骨架goctl api new user-api
goctl api go核心:根據(jù) .api 生成 Go 項(xiàng)目代碼goctl api go -api user.api -dir .
goctl api format格式化 .api 文件goctl api format api/user.api --dir api
goctl api validate校驗(yàn) .api 文件語(yǔ)法goctl api validate --api api/user.api
goctl api -o快速創(chuàng)建 *.api 文件,存在提示已存在,不存在則直接創(chuàng)建goctl api -o example.api
goctl api doc生成靜態(tài) HTML 文檔goctl api doc -api user.api -dir ./docs
goctl api swagger生成 Swagger (OpenAPI) JSON 文件goctl api swagger -api user.api -dir .
goctl api dart為 Flutter 生成 API 調(diào)用代碼goctl api dart -api user.api -dir ./dart-api

goctl api format api/user.api --dir api

格式化前

格式化后(對(duì)齊了)

檢測(cè)api語(yǔ)法

 goctl api validate --api api/user.api

錯(cuò)誤版本

正確版本

快速創(chuàng)建api

goctl api -o xxx.api

已存在的文件

不存在的文件

swagger文檔生成

goctl api swagger -api  api/user.api -dir ./docs
goctl api swagger -api  api/order.api -dir ./docs

生成靜態(tài)html文檔

goctl api doc -api api/user.api -dir ./docs

為 TypeScript 生成 API 調(diào)用代碼

 goctl api ts -api api/user.api -dir ./ts-api

swagger接口文檔使用

安裝

go install github.com/swaggo/swag/cmd/swag@latest

參數(shù)說(shuō)明

go-zero支持通過(guò)注解豐富Swagger文檔內(nèi)容,主要注解包括:

注解作用示例
@summary接口簡(jiǎn)短描述@summary 用戶(hù)注冊(cè)接口
@description接口詳細(xì)說(shuō)明@description 用于新用戶(hù)注冊(cè)賬號(hào),返回用戶(hù)ID
@tags接口分類(lèi)標(biāo)簽@tags 用戶(hù)管理
@accept請(qǐng)求數(shù)據(jù)格式@accept application/json
@produce響應(yīng)數(shù)據(jù)格式@produce application/json
@param自定義請(qǐng)求參數(shù)@param Authorization header string true “Bearer token”
@success成功響應(yīng)描述@success 200 {object} RegisterResponse “注冊(cè)成功”
@failure錯(cuò)誤響應(yīng)描述@failure 400 {object} ErrorResponse “參數(shù)錯(cuò)誤”

帶注解的API示例

service user-api {
  @handler RegisterHandler
  @summary 用戶(hù)注冊(cè)接口
  @description 用于新用戶(hù)注冊(cè)賬號(hào),用戶(hù)名需3-20個(gè)字符,密碼需6-32個(gè)字符
  @tags 用戶(hù)管理
  @accept application/json
  @produce application/json
  @param Authorization header string false "Bearer token"
  @success 200 {object} RegisterResponse "注冊(cè)成功"
  @failure 400 {object} ErrorResponse "參數(shù)錯(cuò)誤"
  @failure 500 {object} ErrorResponse "服務(wù)器內(nèi)部錯(cuò)誤"
  post /api/user/register (RegisterRequest) returns (RegisterResponse)
}

搭建swagger ui

下載

https://github.com/swagger-api/swagger-ui/releases

# 或者csdn下載

https://download.csdn.net/download/xxpxxpoo8/92520157

部署

解壓后把文件復(fù)制到項(xiàng)目根目錄下swagger-ui文件夾里

修改接口地址

window.onload = function() {
  //<editor-fold desc="Changeable Configuration Block">

  // the following lines will be replaced by docker/configurator, when it runs in a docker-container
  window.ui = SwaggerUIBundle({
    url: "http://localhost:8080/docs/user.json",
    dom_id: '#swagger-ui',
    deepLinking: true,
    presets: [
      SwaggerUIBundle.presets.apis,
      SwaggerUIStandalonePreset
    ],
    plugins: [
      SwaggerUIBundle.plugins.DownloadUrl
    ],
    layout: "StandaloneLayout"
  });

  //</editor-fold>
};

在根目錄下新建serve_swagger.go啟動(dòng)文件

// serve_swagger.go
package main

import (
	"log"
	"net/http"
)

func main() {
	// 創(chuàng)建一個(gè)文件服務(wù)器,用于提供當(dāng)前目錄下的所有文件
	fs := http.FileServer(http.Dir("."))
	http.Handle("/", fs)

	log.Println("Serving Swagger UI at http://localhost:8080/swagger-ui/dist/index.html")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

運(yùn)行

go run serve_swagger

打開(kāi)瀏覽器查看

http://localhost:8080/swagger-ui/dist/#/default/getUserInfoHandler

docker打包部署

切換到shop/user下運(yùn)行

go-zero 和goctl是獨(dú)立分開(kāi)的

如果 goctl命令未找到請(qǐng)安裝goctl

go install github.com/zeromicro/go-zero/tools/goctl@latest

1.構(gòu)建dockerfile文件

在根目錄下構(gòu)建dockerfile文件

 goctl docker --go user/user.go --exe user

2.設(shè)置國(guó)內(nèi)鏡像加速器(大部分沒(méi)法用了)

如果國(guó)外鏡像超時(shí),可以使用國(guó)內(nèi)代理

sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json

daemon.json

目前國(guó)內(nèi)我找到能用的鏡像就只有https://docker.1ms.run了

{
  "registry-mirrors": [
	"https://docker.1ms.run"
  ]
}

3.構(gòu)建鏡像

# 確保在 /root/shop 目錄
cd /root/shop

# 重新構(gòu)建鏡像
docker build -t user-api:v1 -f ./user/Dockerfile .

FROM golang:alpine AS builder

LABEL stage=gobuilder

ENV CGO_ENABLED 0


RUN apk update --no-cache && apk add --no-cache tzdata

WORKDIR /build
# 在這里添加國(guó)內(nèi)代理
ENV GOPROXY=https://goproxy.cn,direct
ADD go.mod .
ADD go.sum .
RUN go mod download
COPY . .

RUN go build -ldflags="-s -w" -o /app/user ./user



FROM scratch

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ Asia/Shanghai

WORKDIR /app
COPY --from=builder /app/user /app/user
COPY user/etc /app/etc

CMD ["./user", "-f", "etc/user-api.yaml"]

4. 啟動(dòng)docker服務(wù)

docker run --rm -it -p 8881:8881 user:v1

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 完美解決golang go get私有倉(cāng)庫(kù)的問(wèn)題

    完美解決golang go get私有倉(cāng)庫(kù)的問(wèn)題

    這篇文章主要介紹了完美解決golang go get私有倉(cāng)庫(kù)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-05-05
  • Go語(yǔ)言中的錯(cuò)誤處理過(guò)程

    Go語(yǔ)言中的錯(cuò)誤處理過(guò)程

    Go錯(cuò)誤處理涵蓋接口、創(chuàng)建方式、檢查模式、包裝、最佳實(shí)踐及工具庫(kù),強(qiáng)調(diào)顯式檢查、簡(jiǎn)單可預(yù)測(cè)和錯(cuò)誤即值理念,提升代碼清晰度和可靠性
    2025-07-07
  • Golang+Vue輕松構(gòu)建Web應(yīng)用的方法步驟

    Golang+Vue輕松構(gòu)建Web應(yīng)用的方法步驟

    本文主要介紹了Golang+Vue輕松構(gòu)建Web應(yīng)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 詳解Go語(yǔ)言如何高效解壓ZIP文件

    詳解Go語(yǔ)言如何高效解壓ZIP文件

    在日常開(kāi)發(fā)中,我們經(jīng)常需要處理 ZIP 文件,本文主要為大家介紹一個(gè)使用 Go 語(yǔ)言編寫(xiě)的高效 ZIP 文件解壓工具,希望對(duì)大家有一定的幫助
    2025-03-03
  • Go語(yǔ)言MD5加密用法實(shí)例

    Go語(yǔ)言MD5加密用法實(shí)例

    這篇文章主要介紹了Go語(yǔ)言MD5加密用法,實(shí)例分析了Go語(yǔ)言MD5加密的使用技巧,需要的朋友可以參考下
    2015-03-03
  • go獲取協(xié)程(goroutine)號(hào)的實(shí)例

    go獲取協(xié)程(goroutine)號(hào)的實(shí)例

    這篇文章主要介紹了go獲取協(xié)程(goroutine)號(hào)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Golang中處理import自定義包出錯(cuò)問(wèn)題的解決辦法

    Golang中處理import自定義包出錯(cuò)問(wèn)題的解決辦法

    最近開(kāi)始使用Go/GoLand在import自定義包時(shí)出現(xiàn)各種狀況,下面這篇文章主要給大家介紹了關(guān)于Golang中處理import自定義包出錯(cuò)問(wèn)題的解決辦法,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • Golang中實(shí)現(xiàn)類(lèi)似類(lèi)與繼承的方法(示例代碼)

    Golang中實(shí)現(xiàn)類(lèi)似類(lèi)與繼承的方法(示例代碼)

    這篇文章主要介紹了Golang中實(shí)現(xiàn)類(lèi)似類(lèi)與繼承的方法,Go語(yǔ)言中通過(guò)方法接受者的類(lèi)型來(lái)決定方法的歸屬和繼承關(guān)系,本文通過(guò)示例代碼講解的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • Go gRPC超時(shí)控制Deadlines用法詳解

    Go gRPC超時(shí)控制Deadlines用法詳解

    這篇文章主要為大家介紹了Go gRPC超時(shí)控制Deadlines用法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • golang?中?recover()的使用方法

    golang?中?recover()的使用方法

    這篇文章主要介紹了Guam與golang??recover()的使用方法,Recover?是一個(gè)Go語(yǔ)言的內(nèi)建函數(shù),可以讓進(jìn)入宕機(jī)流程中的?goroutine?恢復(fù)過(guò)來(lái),下文更多相關(guān)資料需要的小伙伴可以參考一下
    2022-04-04

最新評(píng)論

昌乐县| 安西县| 孝感市| 丹棱县| 罗江县| 铁岭县| 五峰| 普宁市| 大丰市| 阿拉尔市| 临夏县| 新建县| 河北省| 福贡县| 东海县| 北流市| 新乐市| 曲阳县| 张家界市| 抚远县| 天水市| 永康市| 赫章县| 舒兰市| 灵宝市| 富源县| 南皮县| 上高县| 蒙山县| 墨脱县| 玛曲县| 巴青县| 黄石市| 清远市| 文安县| 定结县| 宜川县| 招远市| 新田县| 南华县| 丹凤县|