自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go 微服務(wù)框架 go-micro 使用客戶(hù)端 RPC 調(diào)用服務(wù)端方法返回 408 怎么解決?

開(kāi)發(fā) 前端
本文我們介紹怎么解決客戶(hù)端 RPC 調(diào)用服務(wù)端的方法,返回錯(cuò)誤碼 408 的問(wèn)題,我們使用 go-micro 和 gin 構(gòu)建了示例代碼,并通過(guò)修改示例代碼,分析出現(xiàn)返回錯(cuò)誤碼 408 問(wèn)題的原因。

1、介紹

本文我們使用 go-micro 構(gòu)建微服務(wù)的服務(wù)端和客戶(hù)端,并使用 gin 集成客戶(hù)端構(gòu)建 HTTP Api,在代碼中模擬客戶(hù)端 RPC 調(diào)用服務(wù)端方法返回 408 的問(wèn)題,以及怎么解決?

客戶(hù)端輸出日志:

{"id":"go.micro.client","code":408,"detail":"context deadline exceeded","status":"Request Timeout"}

2、使用 go-micro 構(gòu)建服務(wù)端和客戶(hù)端

關(guān)于 proto 和 consul 的相關(guān)內(nèi)容,不是本文的重點(diǎn),將不再贅述,感興趣的讀者朋友們可以查閱公眾號(hào)的歷史文章。

創(chuàng)建服務(wù)端服務(wù)的代碼:

func main() {
registry := consul.NewRegistry(func(options *registry.Options) {
options.Addrs = []string{"127.0.0.1:8500"}
options.Timeout = 5 * time.Second
})
// create a new service
service := grpc.NewService(
micro.Name("go.micro.srv.user"),
micro.Registry(registry),
)
// handler
user.RegisterUserHandler(service.Server(), new(user_handler.User))
// initialise flags
service.Init()
// start the service
service.Run()
}

服務(wù)端方法:

type User struct{}

func (u *User) Login(ctx context.Context, req *user.LoginRequest, rsp *user.LoginResponse) error {
time.Sleep(10 * time.Second) // 模擬超時(shí)響應(yīng)
rsp.Username = "Welcome " + req.Email
return nil
}

客戶(hù)端代碼:

func main() {
r := NewRouter()
server := &http.Server{
Addr: ":8080",
Handler: r,
ReadTimeout: time.Second * 20,
WriteTimeout: time.Second * 20,
MaxHeaderBytes: 1 << 20,
}
if err := server.ListenAndServe(); err != nil {
log.Fatal(err)
}
}

// 省略 User.Login 相關(guān)代碼

func NewRouter() *gin.Engine {
r := gin.New()
userHandler := new(User)
r.GET("/login", userHandler.Login)
return r
}

func NewClient() user.UserService {
registry := consul.NewRegistry(func(options *registry.Options) {
options.Addrs = []string{"127.0.0.1:8500"}
options.Timeout = 5 * time.Second
})
client := grpc.NewClient(
client.DialTimeout(15*time.Second),
client.RequestTimeout(15*time.Second),
client.Registry(registry),
)
userClient := user.NewUserService("go.micro.srv.user", client)
return userClient
}

分別啟動(dòng)服務(wù)端和客戶(hù)端, 然后使用 curl 請(qǐng)求 Api:

?  /Users/frank curl http://127.0.0.1:8080/login
{"data":"Welcome gopher@88.com"}%

閱讀上面的運(yùn)行結(jié)果,可以發(fā)現(xiàn)我們構(gòu)建的服務(wù)端和客戶(hù)端運(yùn)行正常。

3、模擬返回 408 的問(wèn)題

我們?cè)诜?wù)端的方法中使用 time.Sleep(10 * time.Second) 模擬延長(zhǎng)響應(yīng)時(shí)長(zhǎng),我們修改客戶(hù)端代碼,將客戶(hù)端超時(shí)時(shí)間也設(shè)置為 10s。

修改客戶(hù)端代碼:

client.DialTimeout(10*time.Second),
client.RequestTimeout(10*time.Second),

閱讀上面這段代碼,我們將客戶(hù)端超時(shí)時(shí)間改為 10s,然后重啟客戶(hù)端應(yīng)用,使用 curl 請(qǐng)求 Api:

/Users/frank curl http://127.0.0.1:8080/login

運(yùn)行 curl,沒(méi)有返回響應(yīng)結(jié)果,我們查看客戶(hù)端的日志發(fā)現(xiàn):

{"id":"go.micro.client","code":408,"detail":"context deadline exceeded","status":"Request Timeout"}

原因是服務(wù)端方法中,我們?cè)诖a中使用 time.Sleep(10 * time.Second) 模擬響應(yīng)需要 10s,而在客戶(hù)端中,我們定義的客戶(hù)端超時(shí)時(shí)間由原來(lái)的 15s 改為 10s,所以導(dǎo)致返回 408 的問(wèn)題。

需要注意的是,go-micro 中 client 的默認(rèn)超時(shí)時(shí)間是 5s。

4、解決方法

我們?cè)诹私馔陠?wèn)題出現(xiàn)的原因之后,聰明的讀者朋友們可能已經(jīng)有了解決問(wèn)題的方法。

解決該問(wèn)題,有兩種解決方法,第一種是修改 client 的超時(shí)時(shí)間,延長(zhǎng)超時(shí)時(shí)間至足夠接收到響應(yīng)結(jié)果的時(shí)長(zhǎng),但是需要注意的是,http server 的讀寫(xiě)時(shí)間也要滿足可以接收到響應(yīng)結(jié)果的時(shí)長(zhǎng),本文我們?cè)O(shè)置為 20s,如下所示:

server := &http.Server{
Addr: ":8080",
Handler: r,
ReadTimeout: time.Second * 20,
WriteTimeout: time.Second * 20,
MaxHeaderBytes: 1 << 20,
}

而且還需要注意其上下游服務(wù)之間的超時(shí)時(shí)間,避免出現(xiàn)雪崩等問(wèn)題。

第二種是優(yōu)化服務(wù)端方法的響應(yīng)時(shí)間,將其響應(yīng)時(shí)間縮短至客戶(hù)端的超時(shí)時(shí)間以?xún)?nèi)。具體如何優(yōu)化,要根據(jù)實(shí)際情況決定,比如是否因?yàn)閿?shù)據(jù)庫(kù)讀寫(xiě)耗時(shí)太長(zhǎng),代碼的時(shí)間復(fù)雜度太高等。

5、總結(jié)

本文我們介紹怎么解決客戶(hù)端 RPC 調(diào)用服務(wù)端的方法,返回錯(cuò)誤碼 408 的問(wèn)題,我們使用 go-micro 和 gin 構(gòu)建了示例代碼,并通過(guò)修改示例代碼,分析出現(xiàn)返回錯(cuò)誤碼 408 問(wèn)題的原因。

讀者朋友們?cè)谟龅皆搯?wèn)題時(shí),建議優(yōu)先采用第二種方法解決,如果使用第一種方法,需要特別注意避免分布式系統(tǒng)的雪崩問(wèn)題。

責(zé)任編輯:武曉燕 來(lái)源: Golang語(yǔ)言開(kāi)發(fā)棧
相關(guān)推薦

2021-07-26 11:19:43

微服務(wù)開(kāi)發(fā)技術(shù)

2021-10-19 08:58:48

Java 語(yǔ)言 Java 基礎(chǔ)

2024-01-02 12:17:44

Go傳統(tǒng)遠(yuǎn)程

2024-03-06 14:58:52

客戶(hù)端微服務(wù)架構(gòu)

2025-01-13 00:00:07

Go語(yǔ)言微服務(wù)

2015-01-13 10:32:23

RestfulWeb框架

2023-04-03 08:13:05

MySQLCtrl + C

2025-01-20 00:10:00

Go語(yǔ)言Kratos

2009-08-21 15:59:22

服務(wù)端與客戶(hù)端通信

2011-09-09 09:44:23

WCF

2009-08-21 16:14:52

服務(wù)端與客戶(hù)端通信

2010-03-18 17:47:07

Java 多客戶(hù)端通信

2023-03-06 08:01:56

MySQLCtrl + C

2021-10-14 08:39:17

Java Netty Java 基礎(chǔ)

2024-12-23 00:22:55

2009-08-21 15:36:41

服務(wù)端與客戶(hù)端

2009-08-21 15:54:40

服務(wù)端與客戶(hù)端

2022-03-22 09:22:21

Go kitgRPC網(wǎng)絡(luò)傳輸

2010-11-19 14:22:04

oracle服務(wù)端

2021-01-14 09:55:21

Java微服務(wù)Go
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)