Categorygithub.com/curry-mz/sagittarius-golang
module
0.0.0-20250123030917-21bc27a97483
Repository: https://github.com/curry-mz/sagittarius-golang.git
Documentation: pkg.go.dev

# README

基础框架golang版本

环境变量说明

NACOS

NACOS_SERVER_PATH - 配置中心server地址(必要)
NACOS_ACCESS - 配置中心鉴权accessKey
NACOS_SECRET - 配置中心鉴权secretKey
NACOS_USERNAME - 配置中心Username
NACOS_PASSWORD - 配置中心password
NACOS_CONFIG_FORMAT - 配置文件格式(json/xml/yaml)

ETCD(服务发现)

ETCD_ENDPOINTS - etcd地址

Consul(服务发现)

CONSUL_HTTP_ADDR - consul地址

Sentry

SENTRY_DNS - sentry错误报警服务地址

Jaeger

JAEGER_ADDR - jaeger链路追踪信息收集服务地址

其他配置

METRIC_DISABLE - 是否关闭本地监控(runtime/pprof) true:关闭(不推荐)
SERVICE_ENV - online:线上环境 testing:测试环境 (默认值为testing,该项必须保证准确性)
LOG_PATH - 日志保存路径

集成中间件

Mysql : gorm
Redis : go-redis & go-redsync/redsync
服务发现: etcd,consul
配置中心: nacos
消息队列: rocketMQ
链路追踪: jaeger
监控: pprof+runtime
错误监控: sentry

支持服务类型

http & https & grpc & websocket & socket.io

配置说明

日志配置

rotation - 日志分割方式(day/hour) 默认day
saveDays - 日志保存天数 默认3
level - 日志级别(debug/info/warn/error) 默认debug
format - 日志格式(console/json) 默认console

{
  "rotation": "hour",
  "saveDays": 7,
  "level": "debug",
  "format": "json"
}

启动服务配置

proto - 协议类型(http/rpc/websocket)
port - 端口号

[
  {
    "proto": "http",
    "port": 11001
  },
  {
    "proto": "websocket",
    "port": 11002
  }
]

服务发现配置

used - 服务发现方式(etcd/consul) 需配合对应的环境变量配置

{
  "used": "etcd"
}

数据库配置

name - 名称 配置检索使用
master - 主库dns 主从配置将进行读写分离
slaves - 从库dns
maxOpen - 链接池最大连接数 配置前请通知DBA
maxIdle - 链接池最大空闲连接数 配置前请通知DBA
maxLifeTime - 链接可复用最大时间
maxIdleTime - 链接池链接最大空闲时长

[
  {
    "name":"racing", 
    "master":"app:6oXXByzlNoexPye7@tcp(192.168.0.19:3306)/racing?charset=utf8mb4&parseTime=true&loc=Local&timeout=5s&readTimeout=5s", 
    "slaves":["app:6oXXByzlNoexPye7@tcp(192.168.0.19:3306)/racing?charset=utf8mb4&parseTime=true&loc=Local&timeout=5s&readTimeout=5s"], 
    "maxOpen": 100, 
    "maxIdle": 50, 
    "maxLifeTime": "15m", 
    "maxIdleTime": "1h"
  }
]

redis配置

name - 名称 配置检索使用
model - redis模式(singleton/sentinel/cluster) 默认singleton
addr - 地址 多地址则用','分割
database - db库
maxRetry - 最大重试次数
idleTimeout - 客户端关闭空闲连接的时间 应该小于服务器的超时时间 默认为300秒 -1禁用空闲超时检查
readTimeout - 命令读超时 默认3(秒单位)
writeTimeout - 命令写超时 默认等于读超时(秒单位) poolSize - 连接池大小 默认100 配置前请通知DBA
minIdleConn - 最小连接数量 默认35 配置前请通知DBA
password - 密码

[
  {
    "name": "racing",
    "model": "singleton",
    "addr": "192.168.0.19:6379",
    "database": 0,
    "maxRetry": 3,
    "idleTimeout": 600,
    "readTimeout": 5,
    "writeTimeout": 3,
    "poolSize": 150,
    "minIdleConn": 50,
    "password": "BGGjeI"
  }
]

下游服务配置

namespace - 下游服务namespace
product - 下游服务产品
serviceName - 服务名称 namespace.namespace.serviceName为服务发现名
proto - 下游服务协议(rpc/http)
endpoints - endpoints 多个','分割 如果使用服务发现则该配置为兜底 如果未使用服务发现则该配置生效
unUseDiscovery - 是否禁止服务发现 默认false 如果服务本身未配置服务发现则调用下游服务无法使用服务发现功能
retry - 重试次数
timeout - 超时时间 注意这里的超时时间为单次请求超时 所以接口的最坏超时需要乘以retry

[
  {
    "serviceName": "pt",
    "proto":"http",
    "endpoints":"https://api.testing.dream22.xyz",
    "unUseDiscovery":true,
    "retry":2,
    "timeout":"3s"
  },
  {
    "namespace": "aries",
    "product": "common",
    "serviceName": "push.link",
    "proto": "http",
    "retry": 2,
    "timeout":"3s"
  }
]

rocketmq producer配置

name - 名称 配置检索使用
brokers - brokers 使用','分割
timeout - 发送超时时间
accessKey - 鉴权用accessKey
secretKey - 鉴权用secretKey
securityToken - 鉴权用securityToken
maxRetry - 写入最大重试次数

[
  {
    "name": "racing_producer",
    "brokers": "192.168.0.19:9876",
    "timeout": "5s",
    "maxRetry": 1
  }
]

rocketmq consumer配置

name - 名称 配置检索使用
brokers - brokers 使用','分割
consumeTimeout - 队列消息超时时间
accessKey - 鉴权用accessKey
secretKey - 鉴权用secretKey
securityToken - 鉴权用securityToken
maxRetry - 读取最大重试次数
mode - 消费模式 0:broadcasting 1:clustering
from - 消费起点 0:最近一次提交 1:记录的最早一次提交 2:当前时间
groupName - 消费组名称
maxReconsumeTimes - 消费重试次数
expression - Tag标签过滤器

[
  {
    "name": "racing_consumer",
    "brokers": "192.168.0.19:9876",
    "consumeTimeout": "60m",
    "maxRetry": 5,
    "mode": 1,
    "from": 0,
    "groupName": "racing_busi_settle-topic",
    "maxReconsumeTimes": 1,
    "expression": "*"
  }
]

其他

accessRequestDisable - access日志禁止输出request信息 默认false

自定义配置

配置文件中除标准配置外可增加自定义配置

{
  "groups":[
    {
      "groupID":1,
      "groupName":"racing_group_90s",
      "rtp":90,
      "bettingSec":55,
      "racingSec1":25,
      "racingSec2":5,
      "lotterySec":5,
      "text": "1.5min"
    },
    {
      "groupID":2,
      "groupName":"racing_group_180s",
      "rtp":90,
      "bettingSec":145,
      "racingSec1":25,
      "racingSec2":5,
      "lotterySec":5,
      "text": "3min"
    }
  ]
}

标准配置由框架读取,自定义配置需要自行解析

package conf

import "github.com/curry-mz/sagittarius-golang/app"

type Config struct {
	Groups []struct {
		GroupID    int    `json:"groupID"`
		GroupName  string `json:"groupName"`
		RTP        int    `json:"rtp"`
		BettingSec int64  `json:"bettingSec"`
		RacingSec1 int64  `json:"racingSec1"`
		RacingSec2 int64  `json:"racingSec2"`
		LotterySec int64  `json:"lotterySec"`
		Text       string `json:"text"`
		Image      string `json:"image"`
	} `json:"groups"`
}

var conf *Config

func InitAppConfig() {
	var cfg Config
	// 解析自定义配置
	// err := app.Router().ExtraXmlConfig
	// err := app.Router().ExtraYamlConfig
	err := app.Router().ExtraJsonConfig(&cfg)
	if err != nil {
		panic(err)
	}
	conf = &cfg
}

整体例子

{
  "accessRequestDisable": true,
  "log": {
    "rotation": "day",
    "saveDays": 3,
    "level": "debug"
  },
  "servers":[{"proto":"http","port":11001}],
  "discovery":{
    "used": "consul"
  },
  "databases":[
    {
      "name":"racing",
      "master":"app:6oXXByzlNoexPye7@tcp(192.168.0.19:3306)/racing?charset=utf8mb4&parseTime=true&loc=Local&timeout=5s&readTimeout=5s",
      "slaves":["app:6oXXByzlNoexPye7@tcp(192.168.0.19:3306)/racing?charset=utf8mb4&parseTime=true&loc=Local&timeout=5s&readTimeout=5s"],
      "maxOpen": 100,
      "maxIdle": 50,
      "maxLifeTime": "15m",
      "maxIdleTime": "1h"
    }
  ],
  "redis":[
    {
      "name": "racing",
      "model": "singleton",
      "addr": "192.168.0.19:6379",
      "database": 0,
      "maxRetry": 3,
      "password": "BGGjeI"
    }
  ],
  "clients":[
    {
      "serviceName": "pt",
      "proto":"http",
      "endpoints":"https://api.testing.dream22.xyz",
      "unUseDiscovery":true,
      "retry":2,
      "timeout":"3s"
    },
    {
      "namespace": "aries",
      "product": "common",
      "serviceName": "push.link",
      "proto": "http",
      "retry": 2,
      "timeout":"3s"
    }
  ],
  "producers": [
    {
      "name": "racing_producer",
      "brokers": "192.168.0.19:9876",
      "timeout": "5s",
      "maxRetry": 1
    }
  ],
  "consumers": [
    {
      "name": "racing_consumer",
      "brokers": "192.168.0.19:9876",
      "consumeTimeout": "60m",
      "maxRetry": 5,
      "mode": 1,
      "from": 0,
      "groupName": "racing_busi_settle-topic",
      "maxReconsumeTimes": 1,
      "expression": "*"
    }
  ],
  "groups":[
    {
      "groupID":1,
      "groupName":"racing_group_90s",
      "rtp":90,
      "bettingSec":55,
      "racingSec1":25,
      "racingSec2":5,
      "lotterySec":5,
      "text": "1.5min"
    },
    {
      "groupID":2,
      "groupName":"racing_group_180s",
      "rtp":90,
      "bettingSec":145,
      "racingSec1":25,
      "racingSec2":5,
      "lotterySec":5,
      "text": "3min"
    }
  ]
}

代码示例

框架启动

package main

import (
	"flag"

	"code.cd.local/games-go/racing/racing.busi/conf"
	"code.cd.local/games-go/racing/racing.busi/server"

	"github.com/curry-mz/sagittarius-golang/app"
	"github.com/curry-mz/sagittarius-golang/app/config"
	"github.com/curry-mz/sagittarius-golang/env"
)

var (
	confPath = flag.String("confPath", "", "confPath is none")
)

func init() {
	flag.Parse()

	if *confPath != "" && env.IsTesting() {
		// 仅测试环境支持通过启动项传入配置文件地址
		config.WithConfigPath(*confPath)
	}
	// 初始化框架&服务定义
	app.InitRouter(&config.ServiceDefine{
		Namespace:   Namespace,
		Product:     Product,
		ServiceName: ServiceName,
	})
}

func main() {
	// 自定义配置解析
	conf.InitAppConfig()
	// 初始化启动服务
	srv := server.NewHttp()
	// 将server绑定到框架
	app.Router().BindServer(srv)
	// 框架启动
	app.Run()
}

下游服务调用

package push

import (
	"context"
	"fmt"
	netHttp "net/http"

	"github.com/curry-mz/sagittarius-golang/app/proxy"
	"github.com/curry-mz/sagittarius-golang/cores/client/http"
	gErrors "github.com/curry-mz/sagittarius-golang/cores/errors"
	"github.com/curry-mz/sagittarius-golang/logger"

	"github.com/pkg/errors"
)

const (
	Name = "aries.common.push.link"
)

const (
	MessagePushUrl = "/server_api/v1/link/push/message"
)

type RequestPushMessage struct {
	App     string      `json:"app"`  // required
	Mode    int         `json:"mode"` // 1:app内广播 2:组内广播 3:指定id推送
	Group   string      `json:"group,omitempty"`
	To      []string    `json:"to,omitempty"`
	Version string      `json:"version,omitempty"`
	Tag     string      `json:"tag,omitempty"`
	SubType int32       `json:"subType"`
	Payload interface{} `json:"payload,omitempty"`
}

type ResponsePushMessage struct {
	Status  int    `json:"status"`
	Message string `json:"message"`
}

func MessagePush(ctx context.Context, req *RequestPushMessage) error {
	c, err := proxy.InitHttpClient(ctx, Name)
	if err != nil {
		return errors.WithMessage(err, "| proxy.InitHttpClient")
	}
	var rsp ResponsePushMessage
	httpRsp, err := c.JsonPost(http.Request(ctx, MessagePushUrl), req, &rsp)
	if err != nil {
		return errors.WithMessage(err, "| c.JsonPost")
	}
	if httpRsp.StatusCode != netHttp.StatusOK {
		return errors.New(fmt.Sprintf("post %s, httpCode:%d", MessagePushUrl, httpRsp.StatusCode))
	}
	if rsp.Status != 0 {
		return gErrors.New(rsp.Status, rsp.Message)
	}
	return nil
}

数据库使用

package db

import (
	"github.com/curry-mz/sagittarius-golang/app/proxy"
	"github.com/curry-mz/sagittarius-golang/mysql"
)

const dbName = "racing"

type RacingDB struct {
	sql *mysql.Client
}

func New() (*RacingDB, error) {
	cli, err := proxy.InitSqlClient(dbName)
	if err != nil {
		return nil, err
	}
	return &RacingDB{sql: cli}, nil
}

redis使用

package redis

import (
	"github.com/curry-mz/sagittarius-golang/app/proxy"
	"github.com/curry-mz/sagittarius-golang/redis"
)

const redisName = "racing"

type RacingRedis struct {
	rds *redis.Client
}

func New() (*RacingRedis, error) {
	cli, err := proxy.InitRedisClient(redisName)
	if err != nil {
		return nil, err
	}
	return &RacingRedis{rds: cli}, nil
}

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author