Files
lone-services/README-NEW.md
T
gjs be8f89f449
CI / changes (push) Successful in 5s
CI / docker-bff (push) Failing after 7s
CI / docker-product (push) Failing after 5s
CI / docker-admin (push) Failing after 4s
CI / docker-user (push) Failing after 6s
change layout
2026-08-20 15:41:44 +08:00

318 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 常用命令
### 命令 goctl 生成/更新脚手架
```bash
cd lone-services/
rpc/scripts/gen-rpc.sh 服务名 如 product
```
**什么时候跑:**
- 增删改 **字段**BFF gateway 编解码需要)
- 增删 **RPC**
-**google.api.http** 路由
## 如何加一个新服务
以加 `order` 为例(对标现有 `product`)。
### 0. 安装 goctl
```bash
go install github.com/zeromicro/go-zero/tools/goctl@latest
goctl --version
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
```
### 1. 创建 RPC 服务(goctl
在仓库根目录执行:
```bash
cd services
goctl rpc new order
cd order
```
### 2. 将 proto 移到 `proto/` 目录
`goctl rpc new` 默认把 proto 放在服务根目录(如 `order/order.proto`)。统一挪到 `../rpc/order/order.proto`
```bash
mkdir ../rpc/proto
mv order.proto proto/
修改 option go_package="./order"; 为 option go_package="lone-services/rpc/order";
```
### 3. 删除order目录
### 4. Zero 兼容 Nacos 等配置
编辑 `order/internal/config/config.go`
```go
package config
type Config struct {
Nacos NacosConf
}
type NacosConf struct {
Hosts []string
NamespaceId string `json:",optional"`
Group string `json:",optional"`
RegisterIP string `json:",optional"`
ConfigID string `json:",optional"`
}
```
### 5. 配置服务名与监听端口
编辑 `order/etc/order.yaml`
```yaml
Nacos:
Hosts:
- host.docker.internal:8848
NamespaceId: test
Group: LONE_SERVICES
RegisterIP: order
ConfigID: develop-order
```
### 6. 服务注册
编辑 `order/order.go`
增加初始化
```go
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
// Nacos配置拉取初始化
nacosParam := utils.NacosConfig{
Hosts: c.Nacos.Hosts,
NamespaceId: c.Nacos.NamespaceId,
Group: c.Nacos.Group,
ConfigID: c.Nacos.ConfigID,
}
utils.InitConfig(nacosParam)
// 日志配置
logConf := logx.LogConf{
ServiceName: utils.GetConfigString("log.serviceName"),
Mode: utils.GetConfigString("log.mode"),
Encoding: utils.GetConfigString("log.encoding"),
Level: utils.GetConfigString("log.level"),
Path: utils.GetConfigString("log.path"),
KeepDays: utils.GetConfigInt("log.keepDays"),
MaxSize: utils.GetConfigInt("log.maxSize"),
MaxBackups: utils.GetConfigInt("log.maxBackups"),
Compress: utils.GetConfigBool("log.compress"),
}
logx.SetUp(logConf)
logx.AddWriter(logx.NewWriter(os.Stdout))
listenOn := utils.GetConfigString("base.listenOn")
mode := utils.GetConfigString("base.mode")
serviceName := utils.GetConfigString("base.name")
// 初始化服务发现
if err := discovery.Init(discovery.Config{
Hosts: c.Nacos.Hosts,
NamespaceId: c.Nacos.NamespaceId,
Group: c.Nacos.Group,
}); err != nil {
logx.Errorf("nacos init: %v", err)
os.Exit(1)
}
port, err := listenPort(listenOn)
if err != nil {
logx.Errorf("parse ListenOn: %v", err)
os.Exit(1)
}
// 注册服务
if err := discovery.Register(discovery.Instance{
ServiceName: serviceName,
IP: c.Nacos.RegisterIP,
Port: port,
Group: c.Nacos.Group,
}); err != nil {
logx.Errorf("nacos register: %v", err)
os.Exit(1)
}
logx.Infof("服务注册成功: %s:%d", c.Nacos.RegisterIP, port)
defer func() {
if err := discovery.Deregister(); err != nil {
logx.Errorf("nacos deregister: %v", err)
}
}()
// 初始化MySQL
db, err := mysql.New(mysql.Config{
Host: utils.GetConfigString("mysql.host"),
Port: utils.GetConfigInt("mysql.port"),
User: utils.GetConfigString("mysql.user"),
Password: utils.GetConfigString("mysql.password"),
Database: utils.GetConfigString("mysql.database"),
Charset: utils.GetConfigString("mysql.charset"),
Prefix: utils.GetConfigString("mysql.prefix"),
ReadHost: utils.GetConfigString("mysql_read.host"),
ReadPort: utils.GetConfigInt("mysql_read.port"),
ReadUser: utils.GetConfigString("mysql_read.user"),
ReadPassword: utils.GetConfigString("mysql_read.password"),
ReadDatabase: utils.GetConfigString("mysql_read.database"),
})
if err != nil {
logx.Errorf("mysql init: %v", err)
os.Exit(1)
}
// 初始化Redis
if err := redis.Init(redis.Config{
Host: utils.GetConfigString("redis.host"),
Port: utils.GetConfigInt("redis.port"),
Password: utils.GetConfigString("redis.password"),
DB: utils.GetConfigInt("redis.db"),
}); err != nil {
logx.Errorf("redis init: %v", err)
os.Exit(1)
}
debug := utils.GetConfigBool("mysql.debug")
modelbase.Init(db, modelbase.Config{Prefix: utils.GetConfigString("mysql.prefix"), Debug: debug})
// 初始化服务信息
rpcConf := zrpc.RpcServerConf{
ListenOn: listenOn,
}
rpcConf.Mode = mode
ctx := svc.NewServiceContext(c, db)
s := zrpc.MustNewServer(rpcConf, func(grpcServer *grpc.Server) {
order.RegisterOrderServer(grpcServer, server.NewOrderServer(ctx))
if mode == service.DevMode || mode == service.TestMode {
reflection.Register(grpcServer)
}
})
defer s.Stop()
s.AddUnaryInterceptors(validate.UnaryServerInterceptor(validate.MustNew()))
logx.Infof("Starting rpc server at %s...", listenOn)
s.Start()
}
// listenPort 拆分端口
func listenPort(listenOn string) (uint64, error) {
_, portStr, err := net.SplitHostPort(listenOn)
if err != nil {
return utils.NumberZero, err
}
return strconv.ParseUint(portStr, utils.NumberTen, utils.NumberSixtyFourth)
}
```
执行 tidy
```bash
go mod tidy
```
编辑 `internal/svc/servicecontext.go`
```go
package svc
import (
"lone-services/pkg/utils"
"lone-services/services/order/internal/config"
"gorm.io/gorm"
)
type ServiceContext struct {
Config config.Config
DB *gorm.DB
Prefix string
}
func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext {
return &ServiceContext{
Config: c,
DB: db,
Prefix: utils.GetConfigString("mysql.prefix"),
}
}
```
### 7. 接入 Docker Compose
`deploy/docker-compose.dev.override.yml` 增加服务:
```yaml
order:
image: golang:1.26.5
volumes:
- ..:/src
- go-mod-cache:/go/pkg/mod
- go-build-cache:/root/.cache/go-build
working_dir: /src/services/order
command: go run . -f etc/order.yaml
ports:
- "10200:10200"
environment:
NACOS_SERVER_ADDR: rnacos:8848
depends_on:
- rnacos
```
### 9. 在 BFF 配 UpstreamHTTP 路由写在 proto
编辑 `bff/etc/bff.yaml`,在 **Upstreams** 增加一段(不必写 Mappingsgateway 会从 ProtoSet 里的 http option 注册路由):
```yaml
- Name: order
Grpc:
Target: order-service # 必须等于 order.yaml 的 Name
Timeout: 5000
ProtoSets:
- etc/order.pb
```
在对应 RPC 上声明 `google.api.http`(需 `import "google/api/annotations.proto";`):
```protobuf
rpc Ping(Request) returns (Response) {
option (google.api.http) = {
post: "/admin/v3/order/ping"
body: "*"
};
}
```
### 编写业务须知
只改业务逻辑(`internal/logic/`)不必跑 goctl。
`proto/order.proto`(新增/改名 RPC、改字段、改 http option 等)后,按文末「三条命令何时用」处理;
若 HTTP 路径有变,改 proto 里的 `google.api.http` 后重新跑命令 ② 生成 ProtoSet。
---