feat: 添加微服务模板基础架构

- 创建基于 CloudWego Hertz 的 Go 微服务脚手架
- 集成 Nacos 服务注册/发现功能
- 添加 gRPC 客户端支持
- 实现环境变量配置管理 (.env.example)
- 添加 HTTP 中间件 (Recovery, AccessLog, CORS)
- 配置 Gitea CI/CD 构建部署流程

BREAKING CHANGE: 项目结构调整,从简单的 API 服务升级为完整的微服务架构
This commit is contained in:
shiran
2026-04-15 11:13:38 +08:00
parent 8654cd6e5c
commit 6050d11f27
30 changed files with 1643 additions and 358 deletions
+45 -23
View File
@@ -2,21 +2,29 @@ package server_cli
import (
"apiServer_service/proto"
"apiServer_service/utils/loger"
"apiServer_service/utils/logger"
"apiServer_service/utils/nacos"
"context"
"errors"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"os"
"strconv"
"sync"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
)
var (
grpcConn *grpc.ClientConn
grpcClient proto.ServerVisitServiceClient
connMu sync.Mutex
)
// 获取 apiServer 的地址
func getApiServer() string {
service, err := nacos.DiscoverService("apiServer")
if err != nil {
loger.Error("获取服务器地址失败", err)
logger.Error("获取服务器地址失败", err)
if service.Ip != "" {
return service.Ip + ":" + strconv.Itoa(int(service.Port))
}
@@ -25,42 +33,56 @@ func getApiServer() string {
return service.Ip + ":" + strconv.Itoa(int(service.Port))
}
// 获取 grpc 客户端
func getGrpcClient() (*proto.ServerVisitServiceClient, error) {
func getGrpcClient() (proto.ServerVisitServiceClient, error) {
connMu.Lock()
defer connMu.Unlock()
if grpcClient != nil && grpcConn != nil {
return grpcClient, nil
}
serverUri := getApiServer()
if serverUri == "" {
loger.Error("获取服务器地址失败")
return nil, errors.New("getApiServer error")
return nil, errors.New("无法获取 apiServer 地址")
}
conn, err := grpc.NewClient(serverUri, grpc.WithInsecure())
conn, err := grpc.NewClient(serverUri, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
loger.Error("getGrpcClient error", err)
logger.Error("gRPC 连接失败", err)
return nil, err
}
c := proto.NewServerVisitServiceClient(conn)
return &c, nil
grpcConn = conn
grpcClient = proto.NewServerVisitServiceClient(conn)
return grpcClient, nil
}
// getContext 创建带有 token 的上下文
func getContext() context.Context { // 创建带有 token 的上下文
func getContext() context.Context {
token := os.Getenv("GRPC_TOKEN")
md := metadata.Pairs("authorization", "Bearer "+token) // 设置 authorization 头
ctx := metadata.NewOutgoingContext(context.Background(), md)
return ctx
md := metadata.Pairs("authorization", "Bearer "+token)
return metadata.NewOutgoingContext(context.Background(), md)
}
// ReportVisit 演示方法 向服务器上报访问记录
func ReportVisit(token, note, VisitIp, OS string, point, UserId int) error {
func ReportVisit(token, note, visitIP, osName string, point, userID int) error {
client, err := getGrpcClient()
if err != nil {
return err
}
recode, err := (*client).AddServerVisitRecode(getContext(), &proto.ServerVisitRequest{})
record, err := client.AddServerVisitRecode(getContext(), &proto.ServerVisitRequest{})
if err != nil {
loger.Error("ReportVisit error", err)
logger.Error("ReportVisit error", err)
return err
}
loger.Debug("ReportVisit", recode)
logger.Debug("ReportVisit", record)
return nil
}
func CloseGrpcConn() {
connMu.Lock()
defer connMu.Unlock()
if grpcConn != nil {
grpcConn.Close()
grpcConn = nil
grpcClient = nil
}
}