英文:
Basic web tweaks that all applications should have
问题
目前我的Web应用程序只是一个路由器和处理程序。
有哪些重要的东西我忽略了,以使其适合生产环境?
-
我相信我必须设置goroutine的最大数量以确保使用最大的goroutine?
-
我应该使用输出缓冲吗?
还有其他任何你认为缺失的最佳实践吗?
var (
templates = template.Must(template.ParseFiles("templates/home.html"))
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", WelcomeHandler)
http.ListenAndServe(":9000", r)
}
func WelcomeHandler(w http.ResponseWriter, r *http.Request) {
homePage, err := api.LoadHomePage()
if err != nil {
}
tmpl := "home"
renderTemplate(w, tmpl, homePage)
}
func renderTemplate(w http.ResponseWriter, tmpl string, hp *HomePage) {
err := templates.ExecuteTemplate(w, tmpl+".html", hp)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
以下是翻译好的代码部分:
var (
templates = template.Must(template.ParseFiles("templates/home.html"))
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", WelcomeHandler)
http.ListenAndServe(":9000", r)
}
func WelcomeHandler(w http.ResponseWriter, r *http.Request) {
homePage, err := api.LoadHomePage()
if err != nil {
}
tmpl := "home"
renderTemplate(w, tmpl, homePage)
}
func renderTemplate(w http.ResponseWriter, tmpl string, hp *HomePage) {
err := templates.ExecuteTemplate(w, tmpl+".html", hp)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
英文:
Currently my web app is just a router and handlers.
What are some important things I am missing to make this production worthy?
-
I believe I have to set the # of procs to ensure this uses maximum goroutines?
-
Should I be using output buffering?
Anything else you see missing that is best-practise?
var (
templates = template.Must(template.ParseFiles("templates/home.html")
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", WelcomeHandler)
http.ListenAndServe(":9000", r)
}
func WelcomeHandler(w http.ResponseWriter, r *http.Request) {
homePage, err := api.LoadHomePage()
if err != nil {
}
tmpl := "home"
renderTemplate(w, tmpl, homePage)
}
func renderTemplate(w http.ResponseWriter, tmpl string, hp *HomePage) {
err := templates.ExecuteTemplate(w, tmpl+".html", hp)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
答案1
得分: 1
-
你不需要设置/更改
runtime.GOMAXPROCS()
,因为自从Go 1.5版本以来,默认值已经设置为可用CPU核心的数量。 -
输出缓冲?从性能角度来看,你不需要。但是可能有其他考虑因素。
例如,你的renderTemplate()
函数可能会发生恐慌。如果执行模板开始写入输出,它会在写入数据之前设置HTTP响应代码和其他标头。如果在此之后发生模板执行错误,它将返回一个错误,因此你的代码会尝试发送一个错误响应。此时HTTP标头已经被写入,而这个http.Error()
函数将尝试再次设置标头=>恐慌。
避免这种情况的一种方法是首先将模板渲染到缓冲区(例如bytes.Buffer
),如果模板执行没有返回错误,然后你可以将缓冲区的内容写入响应写入器。如果发生错误,当然你不会写入缓冲区的内容,而是像你之前做的那样发送一个错误响应。
总之,从性能角度来看,你的代码已经准备好投入生产(不包括处理模板执行错误的方式)。
英文:
-
You don't need to set/change
runtime.GOMAXPROCS()
as since Go 1.5 it defaults to the number of available CPU cores. -
Buffering output? From the performance point of view, you don't need to. But there may be other considerations for which you may.
For example, your renderTemplate()
function may potentially panic. If executing the template starts writing to the output, it involves setting the HTTP response code and other headers prior to writing data. And if a template execution error occurs after that, it will return an error, and so your code attempts to send back an error response. At this point HTTP headers are already written, and this http.Error()
function will try to set headers again => panic.
One way to avoid this is to first render the template into a buffer (e.g. bytes.Buffer
), and if no error is returned by the template execution, then you can write the content of the buffer to the response writer. If error occurs, then of course you won't write the content of the buffer, but send back an error response just like you did.
To sum it up, your code is production ready performance-wise (excluding the way you handle template execution errors).
答案2
得分: 0
- 当
err != nil
为真时,WelcomeHandler
应该返回。 - 如果遇到错误,记录错误以帮助调查。
- 将
templates = template.Must(template.ParseFiles("templates/home.html"))
放在init
中。将其拆分为单独的行。如果template.ParseFiles
返回错误,则进行Fatal
日志记录。如果有多个模板需要初始化,则使用共享的WaitGroup
在 goroutine 中初始化它们,以加快启动速度。 - 由于你正在使用 mux,了解 HTTP Server is too clean with its URLs 也可能是一个好主意。
- 你可能还想重新考虑让用户知道为什么会收到
http.StatusInternalServerError
响应的决定。 - 如果你有多个核心,将
GOMAXPROCS
设置为大于 1 绝对是一个好主意,但我会将其保持在可用核心数量以下。
英文:
WelcomeHandler
should return whenerr != nil
is true.- Log the error when one is hit to help investigation.
- Place
templates = template.Must(template.ParseFiles("templates/home.html")
in theinit
. Split it into separate lines. Iftemplate.ParseFiles
returns an then error make aFatal
log. And if you have multiple templates to initialize then initialize them in goroutines with a commonWaitGroup
to speed up the startup. - Since you are using mux, HTTP Server is too clean with its URLs might also be good to know.
- You might also want to reconsider the decision of letting the user's know why they got the
http.StatusInternalServerError
response. - Setting the
GOMAXPROCS
> 1 if you have more the one core would definitely be a good idea but I would keep it less than number of cores available.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论