请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

当etcd 服务未开启时。clientv3 config 中设置的timeout 无效。

当etcd 服务未开启时。clientv3 config 中设置的timeout 无效。导致服务无法返回写好的500 错误。

版本: github.com/coreos/etcd v3.3.18+incompatible

虽然使用上下文可以解决,但是感觉不太好。这样的会需要对每一个相关操作做超时处理。config 中的超时设置就无意义了。

kv := clientv3.NewKV(client)

ctx, _ := context.WithTimeout(context.Background(), time.Second)
get, err := kv.Get(ctx, "video/task/", clientv3.WithPrefix())
log.Println(err)
if err != nil {
	return utils.NewHttpError(http.StatusInternalServerError, "服务器错误", err)
}

怎么说呢。就是感觉这样做好麻烦,有没有更方便的办法?
或者说,怎样可以使config 中的超时设置生效?

package main

import (
	"context"
	"fmt"
	"go.etcd.io/etcd/clientv3"
	"log"
	"time"
)
//
func main() {
	var (
		config clientv3.Config
		client *clientv3.Client
		err error
	)

	config = clientv3.Config{
		Endpoints: []string{"127.0.0.1:2379"},
		DialTimeout: 5 * time.Second,
	}
	
	go func() {
		c := time.Tick(time.Second)
		i := 0
		for {
			select {
			case <-c:
				i+=1
				log.Println(i, " 秒")
			}
		}
	}()

	client, err = clientv3.New(config)
	if err != nil {
		fmt.Println(err)
	}

	kv := clientv3.NewKV(client)

	get, err := kv.Get(context.Background(), "video/task/", clientv3.WithPrefix())
	if err != nil {
		panic(err)
	}

	log.Println(get.Kvs)
}
2020-03-06 18:26:42.602454 I | 1  秒
2020-03-06 18:26:43.602274 I | 2  秒
2020-03-06 18:26:44.602679 I | 3  秒
2020-03-06 18:26:45.601484 I | 4  秒
2020-03-06 18:26:46.602726 I | 5  秒
2020-03-06 18:26:47.603348 I | 6  秒
2020-03-06 18:26:48.602880 I | 7  秒
2020-03-06 18:26:49.601294 I | 8  秒
2020-03-06 18:26:50.603081 I | 9  秒
2020-03-06 18:26:51.602582 I | 10  秒
2020-03-06 18:26:52.602849 I | 11  秒
2020-03-06 18:26:53.599996 I | 12  秒
2020-03-06 18:26:54.603904 I | 13  秒
2020-03-06 18:26:55.602876 I | 14  秒
2020-03-06 18:26:56.601724 I | 15  秒
2020-03-06 18:26:57.601178 I | 16  秒
2020-03-06 18:26:58.602296 I | 17  秒
2020-03-06 18:26:59.602598 I | 18  秒
2020-03-06 18:27:00.600759 I | 19  秒
2020-03-06 18:27:01.602385 I | 20  秒
2020-03-06 18:27:02.603282 I | 21  秒
2020-03-06 18:27:03.602828 I | 22  秒
2020-03-06 18:27:04.603899 I | 23  秒
2020-03-06 18:27:05.600960 I | 24  秒
2020-03-06 18:27:06.602482 I | 25  秒
2020-03-06 18:27:07.601204 I | 26  秒
2020-03-06 18:27:08.601740 I | 27  秒
2020-03-06 18:27:09.603543 I | 28  秒
2020-03-06 18:27:10.603834 I | 29  秒
2020-03-06 18:27:11.601636 I | 30  秒
2020-03-06 18:27:12.604080 I | 31  秒
2020-03-06 18:27:13.603355 I | 32  秒
2020-03-06 18:27:14.602334 I | 33  秒
2020-03-06 18:27:15.603803 I | 34  秒
2020-03-06 18:27:16.620306 I | 35  秒
2020-03-06 18:27:17.603574 I | 36  秒
2020-03-06 18:27:18.599904 I | 37  秒
2020-03-06 18:27:19.602123 I | 38  秒
2020-03-06 18:27:20.602343 I | 39  秒
2020-03-06 18:27:21.600036 I | 40  秒
2020-03-06 18:27:22.603832 I | 41  秒
2020-03-06 18:27:23.602712 I | 42  秒
2020-03-06 18:27:24.604718 I | 43  秒
2020-03-06 18:27:25.603869 I | 44  秒
2020-03-06 18:27:26.602898 I | 45  秒
2020-03-06 18:27:27.604195 I | 46  秒
2020-03-06 18:27:28.604408 I | 47  秒
2020-03-06 18:27:29.604782 I | 48  秒
2020-03-06 18:27:30.601149 I | 49  秒
2020-03-06 18:27:31.602764 I | 50  秒
2020-03-06 18:27:32.603675 I | 51  秒
2020-03-06 18:27:33.604245 I | 52  秒
2020-03-06 18:27:34.604660 I | 53  秒
2020-03-06 18:27:35.601099 I | 54  秒
2020-03-06 18:27:36.602127 I | 55  秒
2020-03-06 18:27:37.603862 I | 56  秒
2020-03-06 18:27:38.604405 I | 57  秒
2020-03-06 18:27:39.604430 I | 58  秒
2020-03-06 18:27:40.603559 I | 59  秒
2020-03-06 18:27:41.604589 I | 60  秒
2020-03-06 18:27:42.603747 I | 61  秒
2020-03-06 18:27:43.603702 I | 62  秒
2020-03-06 18:27:44.604187 I | 63  秒
2020-03-06 18:27:45.600625 I | 64  秒
2020-03-06 18:27:46.602907 I | 65  秒

一脸懵逼。。超时设置有啥用??

还有http 服务也无法超时。
使用的echo框架;

自定义 Server
使用Echo#StartServer() 进行自定义 Server 的启动

示例

s := &http.Server{
  Addr:         ":1323",
  ReadTimeout:  20 * time.Minute,
  WriteTimeout: 20 * time.Minute,
}
e.Logger.Fatal(e.StartServer(s))

我的配置

package config_api_server

import (
	"net/http"
	"time"
	"yeepv2/configs"
)

func GetApiServerConfig() *http.Server {
	apiServer := configs.GetEnv().ApiServer

	return &http.Server{
		Addr: apiServer.Port,
		ReadTimeout:  time.Second,
		WriteTimeout:  time.Second,
	}
}

无法超时

简易demo

package main

import (
	"github.com/labstack/echo/v4"
	"net/http"
	"time"
)

func main() {
	e := echo.New()
	s := &http.Server{
		Addr:         ":1323",
		ReadTimeout:  time.Second,
		WriteTimeout: time.Second,
	}
	e.GET("test", func(context echo.Context) error {
		for {
			time.Sleep(time.Second)
		}
	})
	e.Logger.Fatal(e.StartServer(s))
}
// 客户端代码
package main

import (
	"log"
	"net/http"
	"time"
)

func main() {

	go func() {
		c := time.Tick(time.Second)
		i := 0
		for {
			select {
			case <-c:
				i+=1
				log.Println(i, " 秒")
			}
		}
	}()


	get, err := http.Get("http://127.0.0.1:1323/test")
	if err != nil {
		panic(err)
	}
	log.Println(get.Status)

}

测试结果

2020/03/06 18:49:16 1  秒
2020/03/06 18:49:17 2  秒
2020/03/06 18:49:18 3  秒
2020/03/06 18:49:19 4  秒
2020/03/06 18:49:20 5  秒
2020/03/06 18:49:21 6  秒
2020/03/06 18:49:22 7  秒
2020/03/06 18:49:23 8  秒
2020/03/06 18:49:24 9  秒
2020/03/06 18:49:25 10  秒
2020/03/06 18:49:26 11  秒
2020/03/06 18:49:27 12  秒
2020/03/06 18:49:28 13  秒
2020/03/06 18:49:29 14  秒
2020/03/06 18:49:30 15  秒
2020/03/06 18:49:31 16  秒
2020/03/06 18:49:32 17  秒
2020/03/06 18:49:33 18  秒
2020/03/06 18:49:34 19  秒
2020/03/06 18:49:35 20  秒
2020/03/06 18:49:36 21  秒
2020/03/06 18:49:37 22  秒
2020/03/06 18:49:38 23  秒
2020/03/06 18:49:39 24  秒
2020/03/06 18:49:40 25  秒
2020/03/06 18:49:41 26  秒
2020/03/06 18:49:42 27  秒
2020/03/06 18:49:43 28  秒
2020/03/06 18:49:44 29  秒
2020/03/06 18:49:45 30  秒
2020/03/06 18:49:46 31  秒
2020/03/06 18:49:47 32  秒
2020/03/06 18:49:48 33  秒
2020/03/06 18:49:49 34  秒
2020/03/06 18:49:50 35  秒
2020/03/06 18:49:51 36  秒
2020/03/06 18:49:52 37  秒
2020/03/06 18:49:53 38  秒
^C

正在回答 回答被采纳积分+3

1回答

小鱼儿老师 2020-03-08 21:25:38

1)在课程里newKV返回的对象,内部是无限重试的。

2)golang打断超时的机制是监听context.Done(),所以如果阻塞在没有监听context.Done()的方法上,是无法取消打断的。

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信