项目 web 阶段开发
初始化新项目
mkdir mxshop-web
cd mxshop-web
PS D:\golang\goproject\src\mxshop-web> go mod init mxshop-web
go: creating new go.mod: module mxshop-web
go: to add module requirements and sums:
go mod tidy
PS D:\golang\goproject\src\mxshop-web> go mod tidy
go 语言的日志库zap
下载库
PS D:\golang\goproject\src\mxshop-web> go get -u go.uber.org/zap go: added go.uber.org/multierr v1.11.0 go: added go.uber.org/zap v1.28.0
Zap提供了两种类型的日志记录器—Sugared Logger和Logger。
sugared 使用方式
package main
import (
"time"
"go.uber.org/zap"
)
func main() {
logger, _ := zap.NewProduction()//生产环境用法
defer logger.Sync() // flushes buffer, if any;把内存数据同步硬盘
sugar := logger.Sugar()
url := "https://imooc.com"
sugar.Infow("failed to fetch URL",
// Structured context as loosely typed key-value pairs.
"url", url,
"attempt", 3,
"backoff", time.Second,
)
sugar.Infof("Failed to fetch URL: %s", url)
}
启动
PS D:\golang\goproject\src\mxshop-web> go run user-web\zap_test\main.go
{"level":"info","ts":1788846250.2682798,"caller":"zap_test/main.go:14","msg":"failed to fetch URL","url":"https://imooc.com","attempt":3,"backoff":1}
{"level":"info","ts":1788846250.2688963,"caller":"zap_test/main.go:20","msg":"Failed to fetch URL: https://imooc.com"}
在性能很好但不是很关键的上下文中,使用SugaredLogger。它比其他结构化日志记录包快4-10倍,并且支持结构化和printf风格的日志记录。
在每一微秒和每一次内存分配都很重要的上下文中,使用Logger。它甚至比SugaredLogger更快,内存分配次数也更少,但它只支持强类型的结构化日志记录
Logger 格式
package main
import (
"go.uber.org/zap"
)
func main() {
logger,_:=zap.NewDevelopment()
defer logger.Sync() // flushes buffer, if any;把内存数据同步硬盘
url := "https://imooc.com"
logger.Info("failed to fetch URL",
zap.String("url",url),
zap.Int("nums",3),
)
}
启动
PS D:\golang\goproject\src\mxshop-web> go run user-web\zap_test\main.go
2026-09-08T13:59:07.009+0800 INFO zap_test/main.go:17 failed to fetch URL {"url": "https://imooc.com", "nums": 3}
日志写入文件
package main
import (
"go.uber.org/zap"
"time"
)
func NewLogger() (*zap.Logger, error) {
cfg := zap.NewProductionConfig()
cfg.OutputPaths = []string{
"./myproject.log",//输出到文件
"stderr",//错误流
"stdout",//输出流
}
return cfg.Build()
}
func main() {
//logger, _ := zap.NewProduction()
logger, err := NewLogger()//调用
if err != nil {
panic(err)
//panic("初始化logger失败")
}
su := logger.Sugar()
defer su.Sync()
url := "https://imooc.com"
su.Info("failed to fetch URL",
// Structured context as strongly typed Field values.
zap.String("url", url),
zap.Int("attempt", 3),
zap.Duration("backoff", time.Second),
)
}
启动
PS D:\golang\goproject\src\mxshop-web> go run user-web\zap_test\zap_log_file\main.go
{"level":"info","ts":1788848313.0249052,"caller":"zap_log_file/main.go:30","msg":"failed to fetch URL{url 15 0 https://imooc.com <nil>} {attempt 11 3 <nil>} {backoff 8 1000000000 <nil>}"}
{"level":"info","ts":1788848313.0249052,"caller":"zap_log_file/main.go:30","msg":"failed to fetch URL{url 15 0 https://imooc.com <nil>} {attempt 11 3 <nil>} {backoff 8 1000000000 <nil>}"}
initialize 初始化包里定义
package initialize
import (
"github.com/gin-gonic/gin"
router2 "mxshop-web/user-web/router"
)
func Routers() *gin.Engine{
Router := gin.Default()
ApiGroup := Router.Group("/v1")
router2.InitUserRouter(ApiGroup)
return Router
}
router 包定义
package router
import (
"mxshop-web/user-web/api"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
func InitUserRouter(Router *gin.RouterGroup) {
UserRouter:=Router.Group("/user")
zap.S().Info("配置用户相关url")
{
UserRouter.GET("list",api.GetUserList)
}
}
主函数调用
package main
import (
"fmt"
"mxshop-web/user-web/initialize"
"go.uber.org/zap"
//"google.golang.org/protobuf/proto"
)
func main() {
pro := 8021
logger,_ := zap.NewProduction()
zap.ReplaceGlobals(logger)//全局
//初始化
Router :=initialize.Routers()
// logger,_:=zap.NewDevelopment()
// defer logger.Sync()
// suger := logger.Sugar()
/*
1.S()可以获取一个全局的Sugar,可以设置一个全局的loggar
*/
zap.S().Infof("启动,端口:%d",8021)//打印日志信息
if err :=Router.Run(fmt.Sprintf(":%d",pro));err!=nil{
zap.S().Panic("启动失败",err.Error())
}
}
启动
PS D:\golang\goproject\src\mxshop-web> go run user-web\main.go
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
{"level":"info","ts":1788858352.887364,"caller":"router/user.go:12","msg":"配置用户相关url"}
[GIN-debug] GET /v1/user/list --> mxshop-web/user-web/api.GetUserList (3 handlers)
{"level":"info","ts":1788858352.8878922,"caller":"user-web/main.go:24","msg":"启动,端口:8021"}
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8021
从主函数将日志初始化拆分出来
package initialize
import "go.uber.org/zap"
func InitLogger() {
logger, _ := zap.NewDevelopment()
zap.ReplaceGlobals(logger)//全局
}
主函数
package main
import (
"fmt"
"mxshop-web/user-web/initialize"
"go.uber.org/zap"
)
func main() {
pro := 8021
//初始化log
initialize.InitLogger()
//初始化路由
Router :=initialize.Routers()
/*
1.S()可以获取一个全局的Sugar,可以设置一个全局的loggar
2.日志是分级别的debug、info、 warn、 error 、fatal
3.S函数和L函数很有用;给我们提供一个安全的全局访问路径
*/
zap.S().Debugf("启动,端口:%d",8021)//打印日志信息
if err :=Router.Run(fmt.Sprintf(":%d",pro));err!=nil{
zap.S().Panic("启动失败",err.Error())
}
}
启动
PS D:\golang\goproject\src\mxshop-web> go run user-web\main.go
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
2026-09-08T17:23:53.118+0800 INFO router/user.go:12 配置用户相关url
[GIN-debug] GET /v1/user/list --> mxshop-web/user-web/api.GetUserList (3 handlers)
2026-09-08T17:23:53.198+0800 DEBUG user-web/main.go:26 启动,端口:8021
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8021
目录结构

gin调用grpc 服务
api/user.go 文件
package api
import (
"context"
"fmt"
"mxshop-web/user-web/global/reponse"
proto "mxshop-web/user-web/prote"
"net/http"
"time"
//proto "mxshop-web/user-web/proter"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/status"
)
func HandleGrpcErrorToHttp(err error,c *gin.Context){
//将grpc 的code转换为http状态码
if err != nil{
if e,ok :=status.FromError(err);ok{
switch e.Code(){
case codes.NotFound:
c.JSON(http.StatusNotFound,gin.H{
"msg":e.Message(),
})
case codes.Internal:
c.JSON(http.StatusInternalServerError,gin.H{
"msg":"内部错误",
})
case codes.InvalidArgument:
c.JSON(http.StatusBadRequest,gin.H{
"msg":"参数错误",
})
case codes.Unavailable:
c.JSON(http.StatusInternalServerError,gin.H{
"msg":"用户服务不可用",
})
default:
c.JSON(http.StatusInternalServerError,gin.H{
"msg":"其他错误",
})
}
return
}
}
}
func GetUserList(cxt *gin.Context){
ip := "127.0.0.1"
port:= 50051
//拨号连接
userConn,err :=grpc.NewClient(
fmt.Sprintf("%s:%d",ip,port),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err!=nil{
zap.S().Errorw("连接用户服务失败","msg",err.Error(),)
}
//生成grpc 的client并调用接口
userSrvClient:=proto.NewUserClient(userConn)
rsq,err:=userSrvClient.GetUserList(context.Background(),&proto.PageInfo{
Pn: 0,
PSize: 0,
})
if err != nil{
zap.S().Errorw("[GetUserList] 查询【用户列表失败】")
HandleGrpcErrorToHttp(err,cxt)
return
}
result := make([]interface{},0)
for _,value := range rsq.Data{
//data := make(map[string]interface{})
user := reponse.UserResPonse{
Id: value.Id,
NickName: value.NickName,
BirthDay: reponse.JsonTime(time.Unix(int64(value.BirthDay),0)),
Gender: value.Gender,
Mobile: value.Mobile,
}
// data["id"]=value.Id
// data["name"]=value.NickName
// data["birthday"]=value.BirthDay
// data["gender"]=value.Gender
// data["mobile"]=value.Mobile
result=append(result, user)
}
cxt.JSON(http.StatusOK,result)
}
global\reponse\user.go 文件
package reponse
import (
"fmt"
"time"
)
//import "time"
type JsonTime time.Time
func (j JsonTime)MarshalJSON() ([]byte,error){
var stmp = fmt.Sprintf("\"%s\"",time.Time(j).Format("2006-01-02"))
return []byte(stmp),nil
}
type UserResPonse struct {
Id int32 `json:"id"`
NickName string `json:"name"`
//BirthDay string `json:"birthday"`
//BirthDay time.Time `json:"birthday"`
BirthDay JsonTime `json:"birthday"`
Gender string `json:"gender"`
Mobile string `json:"mobile"`
}
initialize\router.go 文件
package initialize
import (
"github.com/gin-gonic/gin"
router2 "mxshop-web/user-web/router"
)
func Routers() *gin.Engine{
Router := gin.Default()
ApiGroup := Router.Group("/u/v1")
router2.InitUserRouter(ApiGroup)
return Router
}
router\user.go 文件
package router
import (
"mxshop-web/user-web/api"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
func InitUserRouter(Router *gin.RouterGroup) {
UserRouter:=Router.Group("/user")
zap.S().Info("配置用户相关url")
{
UserRouter.GET("list",api.GetUserList)
}
}
prote\user.proto 文件
syntax = "proto3";
import "google/protobuf/empty.proto";
option go_package = ".;proto";
service User {
rpc GetUserList(PageInfo) returns(UserListResPonse);//用户列表
rpc GetUserByMobile(MobileRequest) returns(UserInfoResPonse);//通过mobile查询用户
rpc GetUserByID(IdRequest) returns (UserInfoResPonse);//通过ID查用户
rpc CreateUser(CreateUserInfo) returns (UserInfoResPonse);//添加用户
rpc UpdateUser(UpdateUserInfo) returns (google.protobuf.Empty);//更新用户
rpc CheckPassWord(PasswordCheckInfo) returns (CheckReponse);//检查密码
}
message PasswordCheckInfo {
string password =1;
string encryptedPassword=2;
}
message CheckReponse {
bool success=1;
}
message PageInfo {
uint32 Pn = 1;
uint32 pSize =2;
}
message MobileRequest{
string mobile=1;
}
message IdRequest {
int32 Id =1;
}
message CreateUserInfo {
string nickName =1;
string passWord =2;
string mobile =3;
}
message UpdateUserInfo {
int32 id = 1;
string nickName =2;
string gender = 3;
uint64 birthDay =4;
}
message UserInfoResPonse {
int32 id = 1;
string password = 2;
string mobile = 3;
string nickName =4;
uint64 birthDay = 5;
string gender = 6;
int32 role = 7;
}
message UserListResPonse {
int32 total=1;
repeated UserInfoResPonse data=2;
}
生成
protoc --go_out=. --go-grpc_out=. user.proto
main.go
package main
import (
"fmt"
"mxshop-web/user-web/initialize"
"go.uber.org/zap"
//"google.golang.org/protobuf/proto"
)
func main() {
pro := 8021
//初始化log
initialize.InitLogger()
//初始化路由
Router :=initialize.Routers()
// logger,_:=zap.NewDevelopment()
// defer logger.Sync()
// suger := logger.Sugar()
/*
1.S()可以获取一个全局的Sugar,可以设置一个全局的loggar
2.日志是分级别的debug、info、 warn、 error 、fatal
3.S函数和L函数很有用;给我们提供一个安全的全局访问路径
*/
zap.S().Debugf("启动,端口:%d",8021)//打印日志信息
if err :=Router.Run(fmt.Sprintf(":%d",pro));err!=nil{
zap.S().Panic("启动失败",err.Error())
}
}
启动
PS D:\golang\goproject\src\mxshop-web> go run user-web\main.go
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
2026-09-09T18:44:22.283+0800 INFO router/user.go:12 配置用户相关url
[GIN-debug] GET /u/v1/user/list --> mxshop-web/user-web/api.GetUserList (3 handlers)
2026-09-09T18:44:22.300+0800 DEBUG user-web/main.go:26 启动,端口:8021
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8021
[GIN] 2026/09/09 - 18:44:27 | 200 | 8.59ms | 127.0.0.1 | GET "/u/v1/user/list"
[GIN] 2026/09/09 - 18:44:29 | 200 | 3.63ms | 127.0.0.1 | GET "/u/v1/user/list"
[GIN] 2026/09/09 - 18:51:02 | 200 | 13.76ms | 127.0.0.1 | GET "/u/v1/user/list"
测试

go 的配置文件管理-viper
介绍
Viper是适用于Go应用程序的完整配置解决方案。它被设计用于在应用程序中工作,并且可以处理所有类型的配置需求和格式。它支持以下特性:
- 设置默认值
- 从
JSON、TOML、YAML、HCL、envfile和Java properties格式的配置文件读取配置信息 - 实时监控和重新读取配置文件(可选)
- 从环境变量中读取
- 从远程配置系统(etcd或Consul)读取并监控配置变化
- 从命令行参数读取配置
- 从buffer读取配置
- 显式配置值
yaml 教程
示例
下载viper 管理库
go get github.com/spf13/viper
配置文件yaml

Viper 管理配置文件
package main
import (
"fmt"
"github.com/spf13/viper"
)
type ServerConfig struct{
ServerName string `mapstructure:"name"`
}
func main() {
v := viper.New()
v.SetConfigFile("user-web/viper_test/ch01/config.yaml")//配置相对路径
if err:= v.ReadInConfig(); err!=nil{
panic(err)
}
server := ServerConfig{}
if err := v.Unmarshal(&server);err!=nil{
panic(err)
}
fmt.Println(server)
}
启动
PS D:\golang\goproject\src\mxshop-web> go run user-web\viper_test\ch01\main.go
{user-web}
新增一个字段

main.go
package main
import (
"fmt"
"github.com/spf13/viper"
)
type ServerConfig struct{
ServerName string `mapstructure:"name"`//tag 表示把mapstructure的name对应的值填充到ServerName
Prot int `mapstructure:"prot"`//
}
func main() {
v := viper.New()
v.SetConfigFile("user-web/viper_test/ch01/config.yaml")//配置相对路径
if err:= v.ReadInConfig(); err!=nil{
panic(err)
}
server := ServerConfig{}
if err := v.Unmarshal(&server);err!=nil{
panic(err)
}
fmt.Println(server)
}
启动
PS D:\golang\goproject\src\mxshop-web> go run user-web\viper_test\ch01\main.go
{user-web 8021}
yaml 嵌套配置
yaml配置
name: 'user-web' prot: 8021 mysql: host: '127.0.0.1' prot: 3306
main.go 读取
package main
import (
"fmt"
"github.com/spf13/viper"
)
type MysqlConfig struct{
Host string `mapstructure:"host"`
Prot int `mapstructure:"prot"`
}
type ServerConfig struct{
ServerName string `mapstructure:"name"`//tag 表示把mapstructure的name对应的值填充到ServerName
Prot int `mapstructure:"prot"`//
MysqlInfo MysqlConfig `mapstructure:"mysql"`
}
func main() {
v := viper.New()
v.SetConfigFile("user-web/viper_test/ch02/config.yaml")//配置相对路径
if err:= v.ReadInConfig(); err!=nil{
panic(err)
}
server := ServerConfig{}
if err := v.Unmarshal(&server);err!=nil{
panic(err)
}
fmt.Println(server)
}
执行
PS D:\golang\goproject\src\mxshop-web> go run user-web\viper_test\ch02\main.go
{user-web 8021 {127.0.0.1 3306}}
环境配置文件隔离
设置系统环境变量

读取环境变量
package main
import (
"fmt"
"github.com/spf13/viper"
)
type MysqlConfig struct{
Host string `mapstructure:"host"`
Prot int `mapstructure:"prot"`
}
type ServerConfig struct{
ServerName string `mapstructure:"name"`//tag 表示把mapstructure的name对应的值填充到ServerName
Prot int `mapstructure:"prot"`//
MysqlInfo MysqlConfig `mapstructure:"mysql"`
}
func GetEnvInfo(env string) bool{
viper.AutomaticEnv()
return viper.GetBool(env)
}
func main() {
fmt.Println(GetEnvInfo("MXSHOP_DEBUG"))//如果是刚设置的环境变量要重启开发工具像vscode、goland 等才会生效,因为启动的时候才会读环境变量,而你启动后设置的环境变量需要重启更新环境变量
}
执行
PS D:\golang\goproject\src\mxshop-web> go run user-web\viper_test\ch02\main.go
true
config-debug.yaml
environment: debug ame: 'user-web' prot: 8021 mysql: host: '127.0.0.1' prot: 3306
config-pro.yaml
environment: pro name: 'user-web' prot: 8021 mysql: host: '127.0.0.1' prot: 3306
main.go
package main
import (
"fmt"
"github.com/spf13/viper"
)
type MysqlConfig struct{
Host string `mapstructure:"host"`
Prot int `mapstructure:"prot"`
}
type ServerConfig struct{
Environment string `mapstructure:"environment"`
ServerName string `mapstructure:"name"`//tag 表示把mapstructure的name对应的值填充到ServerName
Prot int `mapstructure:"prot"`//
MysqlInfo MysqlConfig `mapstructure:"mysql"`
}
func GetEnvInfo(env string) bool{
viper.AutomaticEnv()
return viper.GetBool(env)
}
func main() {
debug:=GetEnvInfo("MXSHOP_DEBUG")//如果是刚设置的环境变量要重启开发工具像vscode、goland 等才会生效,因为启动的时候才会读环境变量,而你启动后设置的环境变量需要重启更新环境变量
configFilePrefix:="config"
cofigFileName:=fmt.Sprintf("user-web/viper_test/ch02/%s-pro.yaml",configFilePrefix)
if debug{
cofigFileName = fmt.Sprintf("user-web/viper_test/ch02/%s-debug.yaml",configFilePrefix)
}
v := viper.New()
v.SetConfigFile(cofigFileName)//配置相对路径
if err:= v.ReadInConfig(); err!=nil{
panic(err)
}
server := ServerConfig{}
if err := v.Unmarshal(&server);err!=nil{
panic(err)
}
fmt.Println(server)
fmt.Printf("%v",v.Get("environment"))
}
启动
PS D:\golang\goproject\src\mxshop-web> go run user-web\viper_test\ch02\main.go
{debug 8021 {127.0.0.1 3306}}
debug
//viper 动态监控变化的功能
package main
import (
"fmt"
"time"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
type MysqlConfig struct{
Host string `mapstructure:"host"`
Prot int `mapstructure:"prot"`
}
type ServerConfig struct{
Environment string `mapstructure:"environment"`
ServerName string `mapstructure:"name"`//tag 表示把mapstructure的name对应的值填充到ServerName
Prot int `mapstructure:"prot"`//
MysqlInfo MysqlConfig `mapstructure:"mysql"`
}
func GetEnvInfo(env string) bool{
viper.AutomaticEnv()
return viper.GetBool(env)
}
func main() {
debug:=GetEnvInfo("MXSHOP_DEBUG")//如果是刚设置的环境变量要重启开发工具像vscode、goland 等才会生效,因为启动的时候才会读环境变量,而你启动后设置的环境变量需要重启更新环境变量
configFilePrefix:="config"
cofigFileName:=fmt.Sprintf("user-web/viper_test/ch02/%s-pro.yaml",configFilePrefix)
if debug{
cofigFileName = fmt.Sprintf("user-web/viper_test/ch02/%s-debug.yaml",configFilePrefix)
}
v := viper.New()
v.SetConfigFile(cofigFileName)//配置相对路径
if err:= v.ReadInConfig(); err!=nil{
panic(err)
}
server := ServerConfig{}
if err := v.Unmarshal(&server);err!=nil{
panic(err)
}
fmt.Println(server)
fmt.Printf("%v",v.Get("environment"))
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("config file channed :",e.Name)
_=v.ReadInConfig()
_=v.Unmarshal(&server)
fmt.Println(server)
})
time.Sleep(time.Second*300)
}
执行
PS D:\golang\goproject\src\mxshop-web> go run user-web\viper_test\ch02\main.go
{debug 8021 {127.0.0.1 3306}}
debugconfig file channed : user-web\viper_test\ch02\config-debug.yaml
{debug 8021 {127.0.0.1 330}}
config file channed : user-web\viper_test\ch02\config-debug.yaml
{debug 8021 {127.0.0.1 330}}
config file channed : user-web\viper_test\ch02\config-debug.yaml
{debug 8021 {127.0.0.1 3309}}
config file channed : user-web\viper_test\ch02\config-debug.yaml
{debug 8021 {127.0.0.1 3309}}
viper集成到项目中
目录结构

config-debug.yaml 文件
name: "user-web" prot : 8021 user-srv: host: '127.0.0.1' prot: 50051
config-pro.yaml 文件
name: "user-web" prot : 8021 user-srv: host: "127.0.0.1" prot: 50051
user-web\config\config.go 文件
package config
type UserSrvConfig struct{
Host string `mapstructure:"host"`
Prot int `mapstructuer:"prot"`
}
type ServerConfig struct{
Name string `mapstructure:"name"`
Prot int `mapstructuer:"prot"`
UserSrvInfo UserSrvConfig `mapstructure:"user-srv"`
}
user-web\global\global.go 文件
package global
import "mxshop-web/user-web/config"
var (
ServerConfig *config.ServerConfig =&config.ServerConfig{}
)
user-web\initialize\config.go 文件
package initialize
import (
"fmt"
//"mxshop-web/user-web/config"
"mxshop-web/user-web/global"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
"go.uber.org/zap"
)
func GetEnvInfo(env string) bool {
viper.AutomaticEnv()
return viper.GetBool(env)
}
func InitConfig() {
debug:=GetEnvInfo("MXSHOP_DEBUG")//如果是刚设置的环境变量要重启开发工具像vscode、goland 等才会生效,因为启动的时候才会读环境变量,而你启动后设置的环境变量需要重启更新环境变量
configFilePrefix:="config"
cofigFileName:=fmt.Sprintf("user-web/%s-pro.yaml",configFilePrefix)
if debug{
cofigFileName = fmt.Sprintf("user-web/%s-debug.yaml",configFilePrefix)
}
v := viper.New()
v.SetConfigFile(cofigFileName)//配置相对路径
if err:= v.ReadInConfig(); err!=nil{
panic(err)
}
// server := config.ServerConfig{}
//使用全局变量
if err := v.Unmarshal(global.ServerConfig);err!=nil{
panic(err)
}
//fmt.Println(global.ServerConfig)
zap.S().Infof("配置信息:&v",global.ServerConfig)
fmt.Printf("%v",v.Get("environment"))
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("config file channed :",e.Name)
zap.S().Infof("配置文件产生变化:%v",e.Name)
_=v.ReadInConfig()
_=v.Unmarshal(global.ServerConfig)
// fmt.Println(global.ServerConfig)
zap.S().Infof("配置信息:&v",global.ServerConfig)
})
///time.Sleep(time.Second*300)
}
man文件
package main
import (
"fmt"
"mxshop-web/user-web/global"
"mxshop-web/user-web/initialize"
"go.uber.org/zap"
//"google.golang.org/protobuf/proto"
)
func main() {
// prot := 8021
//初始化log
initialize.InitLogger()
//初始化配置文件
initialize.InitConfig()
//初始化路由
Router :=initialize.Routers()
// logger,_:=zap.NewDevelopment()
// defer logger.Sync()
// suger := logger.Sugar()
/*
1.S()可以获取一个全局的Sugar,可以设置一个全局的loggar
2.日志是分级别的debug、info、 warn、 error 、fatal
3.S函数和L函数很有用;给我们提供一个安全的全局访问路径
*/
zap.S().Debugf("启动,端口:%d",global.ServerConfig.Prot)//打印日志信息
if err :=Router.Run(fmt.Sprintf(":%d",global.ServerConfig.Prot));err!=nil{
zap.S().Panic("启动失败",err.Error())
}
}

浙公网安备 33010602011771号