diff --git "a/docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" "b/docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" similarity index 100% rename from "docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" rename to "docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" diff --git "a/docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" "b/docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" similarity index 100% rename from "docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" rename to "docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" diff --git "a/docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" "b/docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" similarity index 100% rename from "docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" rename to "docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" diff --git "a/docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.4.\346\216\247\345\210\266\345\231\250.md" "b/docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.4.\346\216\247\345\210\266\345\231\250.md" similarity index 100% rename from "docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.4.\346\216\247\345\210\266\345\231\250.md" rename to "docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.4.\346\216\247\345\210\266\345\231\250.md" diff --git "a/docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" "b/docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" similarity index 98% rename from "docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" rename to "docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" index 8f6c8bb9cd9..cb822f4fc4d 100644 --- "a/docs/course/proxima-book/\347\254\254\344\270\211\345\274\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" +++ "b/docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" @@ -45,9 +45,11 @@ var ( package main import ( + _ "github.com/gogf/gf/contrib/drivers/mysql/v2" + "github.com/gogf/gf/v2/os/gctx" + "proxima/app/word/internal/cmd" - _ "proxima/app/word/internal/packed" ) func main() { diff --git "a/docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" "b/docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" new file mode 100644 index 00000000000..dd6123de80c --- /dev/null +++ "b/docs/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" @@ -0,0 +1,45 @@ +添加配置文件: +*app/word/manifest/config/etcd.yaml* +```yaml +etcd: + address: "srv.com:2379" +``` + +在入口文件添加注册逻辑: +*app/word/main.go* +```go +package main + +import ( + _ "github.com/gogf/gf/contrib/drivers/mysql/v2" + + "github.com/gogf/gf/contrib/registry/etcd/v2" + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" + + "proxima/app/word/internal/cmd" +) + +func main() { + var ctx = gctx.New() + conf, err := g.Cfg("etcd").Get(ctx, "etcd.address") + if err != nil { + panic(err) + } + + var address = conf.String() + grpcx.Resolver.Register(etcd.New(address)) + + cmd.Main.Run(ctx) +} +``` + +重新运行项目,再次进入`etcd`容器,执行命令查看: +```bash +$ etcdctl get "" --prefix --keys-only +/service/default/default/user/latest/{IP}:32001 +/service/default/default/word/latest/{IP}:32002 +``` + +我们的两个微服务都已经注册到`etcd`中,接下来,运行网关,即可调用它们。 \ No newline at end of file diff --git "a/docs/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" "b/docs/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" index 1779b4620cb..ae48ef28653 100644 --- "a/docs/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" +++ "b/docs/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" @@ -46,7 +46,9 @@ package main import ( _ "github.com/gogf/gf/contrib/drivers/mysql/v2" + "github.com/gogf/gf/v2/os/gctx" + "proxima/app/user/internal/cmd" ) @@ -69,7 +71,7 @@ database: debug: true ``` -`gprc`字段定义了两个字段,微服务名称和监听端口。这两个是必要的,完整配置见[配置模板](https://goframe.org/docs/micro-service/config#%E9%85%8D%E7%BD%AE%E6%A8%A1%E6%9D%BF)。 +`gprc`字段定义了两个字段,微服务名称和监听端口。这两个是必要的,完整配置见[配置模板](https://goframe.org/docs/micro-service/config#%E9%85%8D%E7%BD%AE%E6%A8%A1%E6%9D%BF)。微服务名称会用作后文的服务注册。 ## 启动运行 --- diff --git "a/docs/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" "b/docs/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" new file mode 100644 index 00000000000..b4276be914b --- /dev/null +++ "b/docs/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" @@ -0,0 +1,53 @@ +接下来,我们将服务注册到`etcd`中。先回到主目录安装`etcd`组件: +```bash +$ go get -u github.com/gogf/gf/contrib/registry/etcd/v2 +``` + +添加配置文件: +*app/user/manifest/config/etcd.yaml* +```yaml +etcd: + address: "srv.com:2379" +``` + +在入口文件添加注册逻辑: +*app/user/main.go* +```go +package main + +import ( + _ "github.com/gogf/gf/contrib/drivers/mysql/v2" + + "github.com/gogf/gf/contrib/registry/etcd/v2" + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" + + "proxima/app/user/internal/cmd" +) + +func main() { + var ctx = gctx.New() + conf, err := g.Cfg("etcd").Get(ctx, "etcd.address") + if err != nil { + panic(err) + } + + var address = conf.String() + grpcx.Resolver.Register(etcd.New(address)) + + cmd.Main.Run(ctx) +} +``` + +重新运行项目,查看服务是否注册成功。进入`etcd`容器,执行命令: +```bash +$ etcdctl get "" --prefix --keys-only +``` + +这条命令查看`etcd`中所有存在的`key`,在其中我们会看到注册的服务: +```text +/service/default/default/user/latest/{IP}:32001 +``` + +> 服务注册可以理解成`DNS`域名解析,配置文件中的服务名称`grpc.name`类比成域名。 diff --git "a/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" "b/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" new file mode 100644 index 00000000000..2a3177cc144 --- /dev/null +++ "b/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" @@ -0,0 +1,24 @@ +业务网关和单体`HTTP`服务基本一致,不同的地方在于,由调用微服务来实现业务逻辑。 + +## 代码初始化 +--- +执行以下命令,建立名为`gateway`的服务,同样保存在`app`目录下。 + +```bash +$ gf init app/gateway -a +initializing... +initialization done! +you can now run "cd app/gateway && gf run main.go" to start your journey, enjoy! +``` + +删除下列文件,留下一个空白的环境。 +```text +app/word/api/* +app/word/internal/controller/* +app/word/internal/cmd/cmd.go +``` + +进入仓库,开始正式开发。 +```bash +$ cd app/gateway +``` \ No newline at end of file diff --git "a/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.2.\346\216\245\345\217\243\344\270\216\346\216\247\345\210\266\345\231\250.md" "b/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.2.\346\216\245\345\217\243\344\270\216\346\216\247\345\210\266\345\231\250.md" new file mode 100644 index 00000000000..b5b7f37288d --- /dev/null +++ "b/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.2.\346\216\245\345\217\243\344\270\216\346\216\247\345\210\266\345\231\250.md" @@ -0,0 +1,68 @@ +这一步大家应该很熟悉,就不过多介绍。 + +*app/gateway/api/user/v1/user.go* +```go +package v1 + +import "github.com/gogf/gf/v2/frame/g" + +type LoginReq struct { + g.Meta `path:"users/login" method:"post" sm:"登录" tags:"用户"` + Username string `json:"username" v:"required|length:3,12"` + Password string `json:"password" v:"required|length:6,16"` +} + +type LoginRes struct { + Token string `json:"token" dc:"在需要鉴权的接口中header加入Authorization: token"` +} +``` + +*app/gateway/api/words/v1/words.go* +```go +package v1 + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +type CreateReq struct { + g.Meta `path:"words" method:"post" sm:"创建" tags:"单词"` + Word string `json:"word" v:"required|length:1,100" dc:"单词"` + Definition string `json:"definition" v:"required|length:1,300" dc:"单词定义"` +} + +type CreateRes struct { +} + +type DetailReq struct { + g.Meta `path:"words/{id}" method:"get" sm:"详情" tags:"单词"` + Id uint `json:"id" v:"required"` +} + +type DetailRes struct { + Id uint `json:"id"` + Word string `json:"word"` + Definition string `json:"definition"` + ExampleSentence string `json:"exampleSentence"` + ChineseTranslation string `json:"chineseTranslation"` + Pronunciation string `json:"pronunciation"` + CreatedAt *gtime.Time `json:"createdAt"` + UpdatedAt *gtime.Time `json:"updatedAt"` +} +``` + +执行命令,生成控制器。 +```bash +$ gf gen ctrl +generated: D:\project\proxima\app\gateway\api\user\user.go +generated: D:\project\proxima\app\gateway\internal\controller\user\user.go +generated: D:\project\proxima\app\gateway\internal\controller\user\user_new.go +generated: D:\project\proxima\app\gateway\internal\controller\user\user_v1_login.go +generated: D:\project\proxima\app\gateway\api\words\words.go +generated: D:\project\proxima\app\gateway\internal\controller\words\words.go +generated: D:\project\proxima\app\gateway\internal\controller\words\words_new.go +generated: D:\project\proxima\app\gateway\internal\controller\words\words_v1_create.go +generated: D:\project\proxima\app\gateway\internal\controller\words\words_v1_detail.go +done! +``` diff --git "a/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.3.\345\220\257\345\212\250\350\277\220\350\241\214.md" "b/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.3.\345\220\257\345\212\250\350\277\220\350\241\214.md" new file mode 100644 index 00000000000..1581f88fe8b --- /dev/null +++ "b/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.3.\345\220\257\345\212\250\350\277\220\350\241\214.md" @@ -0,0 +1,114 @@ +我们简单的将服务运行起来,之后再调用微服务。 + +## 编写配置文件 +--- +*app/gateway/manifest/config/config.yaml* +```yaml +server: + address: ":8000" + openapiPath: "/api.json" + swaggerPath: "/swagger" + logger: + path: "./log" + file: "{Y-m-d}.log" + level: "all" + stdout: true +``` + +*app/gateway/manifest/config/etcd.yaml* +```yaml +etcd: + address: "srv.com:2379" +``` + +## CMD文件 +--- +*app/gateway/internal/cmd/cmd.go* +```go +package cmd + +import ( + "context" + + "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gcmd" "proxima/app/gateway/internal/controller/user" "proxima/app/gateway/internal/controller/words") + +var ( + Main = gcmd.Command{ + Name: "main", + Usage: "main", + Brief: "start http gateway server", + Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { + s := g.Server() + s.Group("/", func(group *ghttp.RouterGroup) { + group.Group("/v1", func(group *ghttp.RouterGroup) { + group.Group("/", func(group *ghttp.RouterGroup) { + group.Bind(user.NewV1()) + group.Bind(words.NewV1()) + }) + }) + }) + s.Run() + return nil + }, + } +) +``` + +## 启动运行 +--- +*app/gateway/main.go* +```go +package main + +import ( + "github.com/gogf/gf/contrib/registry/etcd/v2" + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" + "proxima/app/gateway/internal/cmd" +) + +func main() { + var ctx = gctx.New() + conf, err := g.Cfg("etcd").Get(ctx, "etcd.address") + if err != nil { + panic(err) + } + + var address = conf.String() + grpcx.Resolver.Register(etcd.New(address)) + + cmd.Main.Run(ctx) +} +``` + +```bash +$ gf run .\main.go +build running pid: 16144 +2024-12-10 15:30:30.788 [INFO] pid[16144]: http server started listening on [:8000] +2024-12-10 15:30:30.788 [INFO] {f0f10d9d4ec00f181b7a6f615f39d54b} swagger ui is serving at address: http://127.0.0.1:8000/swagger/ +2024-12-10 15:30:30.789 [INFO] {f0f10d9d4ec00f181b7a6f615f39d54b} openapi specification is serving at address: http://127.0.0.1:8000/api.json +2024-12-10 15:30:30.817 [DEBU] {f0f10d9d4ec00f181b7a6f615f39d54b} service register: &{Head: Deployment: Namespace: Name:default Version: Endpoints:192.168.10.98:8000 Metadata:map[insecure:true protocol:http]} +2024-12-10 15:30:30.900 [DEBU] {f0f10d9d4ec00f181b7a6f615f39d54b} etcd put success with key "/service/default/default/default/latest/192.168.10.98:8000", value "{"insecure":true,"protocol":"http"}", lease "7587883327293376805" + + ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + :8000 | ALL | /api.json | github.com/gogf/gf/v2/net/ghttp.(*Server).openapiSpec | +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + :8000 | ALL | /swagger/* | github.com/gogf/gf/v2/net/ghttp.(*Server).swaggerUI | HOOK_BEFORE_SERVE +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + :8000 | POST | /v1/users/login | proxima/app/gateway/internal/controller/user.(*ControllerV1).Login | +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + :8000 | POST | /v1/words | proxima/app/gateway/internal/controller/words.(*ControllerV1).Create | +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + :8000 | GET | /v1/words/{id} | proxima/app/gateway/internal/controller/words.(*ControllerV1).Detail | +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- +``` + +进入`etcd`容器,执行命令查看: +```bash +$ etcdctl get "" --prefix --keys-only +/service/default/default/default/latest/{IP}:8000 +/service/default/default/word/latest/{IP}:32001 +/service/default/default/word/latest/{IP}:32002 +``` diff --git "a/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.4.\350\260\203\347\224\250\345\276\256\346\234\215\345\212\241.md" "b/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.4.\350\260\203\347\224\250\345\276\256\346\234\215\345\212\241.md" new file mode 100644 index 00000000000..3edfcec0a77 --- /dev/null +++ "b/docs/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.4.\350\260\203\347\224\250\345\276\256\346\234\215\345\212\241.md" @@ -0,0 +1,5 @@ +接下来,我们要调用微服务,完成具体的业务逻辑。 + +## 用户服务 +--- +*app/gateway/internal/controller/user/user_v1_login.go* \ No newline at end of file