版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w15249243295/article/details/78763974
背景
所在项目Go服务之前部署在测试机器上,最近再把Go的配置迁移到etcd,但是因为etcd没有对应的测试环境,而公司里面网段是隔离的,导致了原本的Go服务再接入etcd之后跑不起来。
- 让Go服务正常启动,
- 其他依赖方,比如前端、网关少做修改
方案
Go服务部署到docker上,docker上的域名都是特定后缀结尾,这样会涉及到cookie等一些问题,所以考虑通过测试机的Nginx做代理。
问题
- http 426 报错:测试环境的http协议是1.0,而docker上的http协议是1.1,所以需要在nginx转发的时候,添加header头。如果是websocket可以参考下 https://www.nginx.com/blog/websocket-nginx/
- http 404 报错:Nginx在做转发的时候,需要加上host header头,域名解析找到对应的主机,但是需要根据host信息,找到对应的服务。
插曲
再解决问题的时候,通过curl -I 在访问docker上的服务,一直提示404,但是通过curl直接访问的时候,正常。后来想到curl -I是通过head的方式请求。项目注册的路由请求方式是get,但是Iris的底层路由,404和405报错不能共存,iris默认会将404和405报错统一的转换成404报错。
直接上代码
pool.Run(w, r, func(context *iris.Context) {
routePath := context.Path()
for i := range mux.garden {
tree := mux.garden[i]
if !mux.methodEqual(context.Request.Method, tree.method) {
continue
}
if mux.hosts && tree.subdomain != "" {
requestHost := context.Host()
// println("mux are true and tree.subdomain= " + tree.subdomain + "and hostname = " + hostname + " host = " + requestHost)
if requestHost != hostname {
// we have a subdomain
if strings.Contains(tree.subdomain, iris.DynamicSubdomainIndicator) {
} else {
if tree.subdomain+hostname != requestHost {
// go to the next tree, we have a subdomain but it is not the correct
continue
}
}
} else {
//("it's subdomain but the request is not the same as the vhost)
continue
}
}
mustRedirect := tree.entry.getValue(routePath, context) // pass the parameters here for 0 allocation
if context.Middleware != nil {
// ok we found the correct route, serve it and exit entirely from here
//ctx.Request.Header.SetUserAgentBytes(DefaultUserAgent)
context.Do()
return
} else if mustRedirect && !context.Framework().Config.DisablePathCorrection { // && context.Method() == MethodConnect {
reqPath := routePath
pathLen := len(reqPath)
if pathLen > 1 {
if reqPath[pathLen-1] == '/' {
reqPath = reqPath[:pathLen-1] //remove the last /
} else {
//it has path prefix, it doesn't ends with / and it hasn't be found, then just add the slash
reqPath = reqPath + "/"
}
urlToRedirect := reqPath
statusForRedirect := iris.StatusMovedPermanently // StatusMovedPermanently, this document is obselte, clients caches this.
if tree.method == iris.MethodPost ||
tree.method == iris.MethodPut ||
tree.method == iris.MethodDelete {
statusForRedirect = iris.StatusTemporaryRedirect // To maintain POST data
}
context.Redirect(urlToRedirect, statusForRedirect)
// RFC2616 recommends that a short note "SHOULD" be included in the
// response because older user agents may not understand 301/307.
// Shouldn't send the response for POST or HEAD; that leaves GET.
if tree.method == iris.MethodGet {
note := "<a href=\"" + HTMLEscape(urlToRedirect) + "\">Moved Permanently</a>.\n"
// ignore error
context.WriteString(note)
}
return
}
}
// not found
break
}
// https://github.com/kataras/iris/issues/469
if context.Framework().Config.FireMethodNotAllowed {
var methodAllowed string
for i := range mux.garden {
tree := mux.garden[i]
methodAllowed = tree.method // keep track of the allowed method of the last checked tree
if !mux.methodEqual(context.Method(), tree.method) {
continue
}
}
// RCF rfc2616 https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
// The response MUST include an Allow header containing a list of valid methods for the requested resource.
context.SetHeader("Allow", methodAllowed)
context.EmitError(iris.StatusMethodNotAllowed)
return
}
context.EmitError(iris.StatusNotFound)
})