失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Go 相关问题及解决办法汇总

Go 相关问题及解决办法汇总

时间:2021-05-03 16:05:06

相关推荐

Go 相关问题及解决办法汇总

目录

1.# command-line-arguments ./main.go:25:2: undefined: initHandlers

2.Gorm报invalid connection错误

1.# command-line-arguments ./main.go:25:2: undefined: initHandlers

问题背景

同一个包下的两个文件,点击idea的运行按钮或者运行 go run main.go命令时,就会报错 (# command-line-arguments ./main.go:25:2: undefined: initHandlers)如下图所示。

问题原因

在文件模式下,同一目录下不能将方法放在当前目录下的单独文件中调用,但是在包模式下可以。

解决办法

该出错原因属于go的多文件加载问题,采用go run命令执行的时候,需要把待加载的.go文件都包含到参数里面。通过 go run *.go (目录里面没有test.go才行)配置IDE(goland) 以 package包模式运行

相关资料

1./lhl1124281072/article/details/80405474

2.Gorm报invalid connection错误

新上的一个项目,使用gorm进行数据操作,线上报connection invalid错误。

从报错信息来看,应该是mysql client连接的问题。看了一些网上类似问题的分析,其中一篇提到了数据库客户端如果长时间不使用,mysql server端会单方面关闭该连接。

可以在mysql服务器上使用以下命令查看:

SHOW VARIABLES LIKE '%timeout%';+-----------------------------------+----------+| Variable_name | Value |+-----------------------------------+----------+| connect_timeout | 10 || delayed_insert_timeout | 300|| have_statement_timeout | YES|| innodb_flush_log_at_timeout | 1 || innodb_lock_wait_timeout| 50 || innodb_rollback_on_timeout | OFF|| interactive_timeout| 28800 || lock_wait_timeout | 31536000 || mysqlx_connect_timeout | 30 || mysqlx_idle_worker_thread_timeout | 60 || mysqlx_interactive_timeout | 28800 || mysqlx_port_open_timeout| 0 || mysqlx_read_timeout| 30 || mysqlx_wait_timeout| 28800 || mysqlx_write_timeout | 60 || net_read_timeout | 30 || net_write_timeout | 60 || rpl_stop_slave_timeout | 31536000 || slave_net_timeout | 60 || wait_timeout | 28800 |+-----------------------------------+----------+

其中wait_timeout表示mysql服务最长容忍一个连接idle的时间,单位是秒。上例为8小时。

猜想:

从中文意思上看invalid connection其实就是表示无效链接的情况。如果是上述原因,很自然的就想到一种解决方案:重试一次。既然本次连接idle掉了,那么我们再发送一次相同的请求,不就可以重联了么?

验证:

把改进后的代码重新上线。果不其然,第一次链接时还是会报相同的错误,但是第二次重新执行成功了。那问题真的解决了么?

继续猜想:

由于这条命令每天只会执行一次,我们还需要多关注几天以确定问题得到解决。不幸的是,在第二天的观察到的现象中两次操作均以失败告终。看来我并没有真正解决掉这个问题。除此之外,我心里还有两处疑问:

是同样的代码在测试环境运行正常,但线上出错;是代码中有很多地方也存在数据库操作,但未观察到有相同的错误发生;

进一步分析:

我们看一下出问题的这条sql,它大致是这样子的。

select * from table1 where field1="xxx" and field2="yyy" and id>num order by id asc limit 100;

使用explain来看一下mysql是怎么执行它的

+----+-------------+-------------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key| key_len | ref | rows | filtered | Extra |+----+-------------+-------------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+| 1 | SIMPLE| table1s.| NULL | range | PRIMARY | PRIMARY | 8 | NULL | 11 | 12.50 | Using where |+----+-------------+-------------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+

这个解释非常具有迷惑性,因为它告诉我这次查询走的是索引(我的另一篇博文对explain命令有详解--/zhanglehes/article/details/110523519)。但仔细分析了一下,id是自增主键,虽然mysql在查询时走的是primary key,但实质上仍是一个(类)全表扫码,这样的话,本次操作就是非常耗时的。

为了验证以上的猜想成立,我在线上直接使用命令行进行同样的操作

3 rows in set (0.51 sec)

Mysql server的执行时间为510毫秒。

再去确认gorm的配置参数,ReadTimeoutMs这个参数的值正好为500。

最后答疑解惑

Q1:在未创建新索引时,为何第一次改动上线后能在部分情况下成功?

答:mysql server端对应同一条sql的执行应该会有部分缓存,我尝试过多次执行同一条命令,后续执行的时间都会比第一次执行要低。另外线上配置的mysql客户端的超时时间与sql真实执行的时间相近,也会造成同一条指令偶尔成功的情况。

Q2:为何测试环境没有问题?

答:数据量小

Q3:本次改动是否具有通用性?

答:不具有。Mysql中会存储一些统计信息。一条sql执行时,如果有多条索引存在,mysql会预先评估每条索引执行的时间,选取效率最高的那个。因此可能存在添加新索引后,mysql还是判断原先索引执行较快,这时就不会得到性能提升了。

如果觉得《Go 相关问题及解决办法汇总》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。