level= error Error 1045: Access denied for user ‘‘@‘xxx.xxx.xxx.xxx‘ (using password: NO)

项目场景:

项目场景:微服务项目中使用consul作为配置中心存储mysql配置,获取配置后使用gorm连接mysql数据库时出现错误。


问题描述

错误:file=category/main.go:48 level= error Error 1045:Access denied for user ''@'xxx.xxx.xxx.xxx'' (using password: NO)


配置中心以及获取配置中心代码:

package main


func GetConsulConfig(host string, port int64, prefix string) (config.Config, error) {
	consulSource := consul.NewSource(
		consul.WithAddress(host+":"+strconv.FormatInt(port, 10)),
		consul.WithPrefix(prefix),
		consul.StripPrefix(true),
	)
	cf, err := config.NewConfig()
	if err != nil {
		return cf, err
	}

	err = config.Load(consulSource)
	return cf, err
}

type MysqlConfig struct {
	Host     string `json:"host"`
	User     string `json:"user"`
	Pwd      string `json:"pwd"`
	Database string `json:"database"`
	Port     int64  `json:"port"`
}

// 获取 mysql 的配置
func GetMysqlFromConsul(config config.Config, path ...string) *MysqlConfig {
	mysqlConfig := &MysqlConfig{}
	config.Get(path...).Scan(mysqlConfig)
	return mysqlConfig
}


func main() {
	// config center
	consulConfig, err := common.GetConsulConfig("127.0.0.1", 8500, "/micro/config")
	if err != nil {
		log.Error(err)
	}
	// get mysql config
	mysqlInfo := common.GetMysqlFromConsul(consulConfig, "mysql")
	//"mysql",root+:123456@/db3?charset=utf8&parseTime=True&loc=Local"
	db, err := gorm.Open("mysql", mysqlInfo.User+":"+mysqlInfo.Pwd+"@/"+mysqlInfo.Database+"?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		log.Error(err)
	}

}


原因分析:

根据打印的日志:

file=category/main.go:48 level= error Error 1045:Access denied for user ''@'xxx.xxx.xxx.xxx' (using password: NO)

报错的地方为main函数的48行,也就是gorm连接mysql的地方:

	db, err := gorm.Open("mysql", mysqlInfo.User+":"+mysqlInfo.Pwd+"@/"+mysqlInfo.Database+"?charset=utf8&parseTime=True&loc=Local")
	if err != nil { 
		log.Error(err)    // 记录了错误日志
	}

gorm包已经引入, 那么肯定就是gorm连接地址出错,地址通过mysql配置拼接,找了半天并没有发现地址格式有误,于是开始向上查找,在往上就是从consul获取mysql配置,也许是这里出错了,就试着打印mysqlInfo中的信息,添加一行代码:

	fmt.Printf("user:%s\npassword:%s\ndatabase:%s\nport:%d\nhost:%s\n", mysqlInfo.User, mysqlInfo.Pwd, mysqlInfo.Database, mysqlInfo.Port, mysqlInfo.Host)

output:

哦豁,获取不到consul中MySQL的配置 ,涉及到consul和获取consul中MySQL配置的只有两个函数,分别为:

func GetConsulConfig(host string, port int64, prefix string) (config.Config, error) {
	consulSource := consul.NewSource(
		consul.WithAddress(host+":"+strconv.FormatInt(port, 10)),
		consul.WithPrefix(prefix),
		consul.StripPrefix(true),
	)
    // 配置初始化
	config, err := config.NewConfig()
	if err != nil {
		return config, err
	}
    // 加载配置
	err = config.Load(consulSource)
	return config, err
}
// 获取 mysql 的配置
func GetMysqlFromConsul(config config.Config, path ...string) *MysqlConfig {
	mysqlConfig := &MysqlConfig{}
	config.Get(path...).Scan(mysqlConfig)
	return mysqlConfig
}

 问题进一步缩小,当看到GetConsulConfig()函数时发现了错误,配置初始化config.NewConfig()返回了一个new config,用config变量接收,随后就是加载配置config.Load(consulSource),这里就是关键。

前面用config变量接收返回值,而有个包也叫config,config变量有个方法Load(),而config包中也有个Load()方法,就是因为调用错了才导致获取不到consul中的配置。


解决方案:

出现这样的问题就是变量命名和包名重名了,在调用时不小心调用错了方法,才导致获取不到consul中mysql的配置。

更改config.NewConfig()返回值接收对象名称为cf,然后调用cf的Load()方法即可:

func GetConsulConfig(host string, port int64, prefix string) (config.Config, error) {
	consulSource := consul.NewSource(
		consul.WithAddress(host+":"+strconv.FormatInt(port, 10)),
		consul.WithPrefix(prefix),
		consul.StripPrefix(true),
	)
	cf, err := config.NewConfig()
	if err != nil {
		return cf, err
	}
    //err = config.Load(consulSource)  <-----原先错误的写法
	err = cf.Load(consulSource)
	return cf, err
}

再次运行项目:

此时就获取到了配置中心的MySQL配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值