在netlify上部署golang web应用
介绍
Netlify是一个专门托管静态文件的云。这使得它非常适合托管开发人员博客、宣传册网站,甚至只是一个个人简历。它甚至内置了对Hugo的支持。但是Netlify也有各种动态托管解决方案,他们的functions
服务是托管Go Web应用程序的一种非常简单的方法,而且通常是免费的。
Netlify:
GitHub:go-netlify-app
实现
假设我们有一个静态HTML网页,但我们希望在页面上有一个动态填充的信息流。例如,网页本身是静态的,但使用JavaScript从API中提取相关链接。这是在不牺牲包含其他内容的能力的情况下为页面保留较长缓存时间的好方法。理想情况下,我们可以自己部署网页,但无需部署一个定期将链接转储到数据库中的爬虫程序。
举个例子,让我们使用知乎热榜,它来自https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=50&desktop=true
,让后端获取我们需要的信息,通过API提供给静态网页。
Go可以很容易地编写一个将JSON格式内容的URL转换为JSON的服务。
package mainimport ("flag""fmt""io/ioutil""log""net/http"
)var (port = flag.Int("port", -1, "specify a port")
)func main() {flag.Parse()http.HandleFunc("/api/feed", feed)log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
}func feed(w http.ResponseWriter, r *http.Request) {url := "https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=50&desktop=true"method := "GET"client := &http.Client{}req, err := http.NewRequest(method, url, nil)if err != nil {fmt.Println(err)return}res, err := client.Do(req)if err != nil {fmt.Println(err)return}defer res.Body.Close()body, err := ioutil.ReadAll(res.Body)if err != nil {fmt.Println(err)return}w.Header().Set("content-type", "application/json")w.Write(body)
}
如果我们从命令行使用go run myfile.go -port 8000
运行它,Go标准包flag
将为我们解析-port 8000
,并提供一个在8000端口的API。
当我们查看Netlify的文档时,我们发现我们的第一个挑战是他们使用AWS Lambda,而不是普通的HTTP 服务,因此我们要么需要重写我们的服务以使用Lambda,要么找到一个适配器。最好避免将架构与特定的云提供商紧密耦合,因为这会导致难以从平台迁移,因此无需编写不必要的AWS特定代码。
AWS Lambda和Go标准http
包之间的适配器已经存在。它们采用AWS Lambda
函数使用和返回JSON对象,并将它们调整为正常的Gohttp.Handler
调用。
Gateway使在本地开发中试用我们的代码变得容易,而无需启动某种AWS Lambda模拟器。
package mainimport ("flag""fmt""io/ioutil""log""net/http""github.com/apex/gateway"
)var (port = flag.Int("port", -1, "specify a port")
)func main() {flag.Parse()http.HandleFunc("/api/feed", feed)listener := gateway.ListenAndServeportStr := "n/a"if *port != -1 {portStr = fmt.Sprintf(":%d", *port)listener = http.ListenAndServehttp.Handle("/", http.FileServer(http.Dir("./public")))}log.Fatal(listener(portStr, nil))
}package mainimport ("flag""fmt""io/ioutil""log""net/http""github.com/apex/gateway"
)var (port = flag.Int("port", -1, "specify a port")
)func main() {flag.Parse()http.HandleFunc("/api/feed", feed)listener := gateway.ListenAndServeportStr := "n/a"if *port != -1 {portStr = fmt.Sprintf(":%d", *port)listener = http.ListenAndServehttp.Handle("/", http.FileServer(http.Dir("./public")))}log.Fatal(listener(portStr, nil))
}
使用这个版本的代码,如果我们运行go run main.go -port 8000
,服务器将在http://localhost:8000
上启动,但如果我们省略一个端口,它将以AWS Lambda模式启动。它还以HTTP模式运行文件服务器,因此我们可以在开发时在浏览器中预览正在处理的静态文件。
接下来,让我们添加一个带有一些基本JavaScript的静态网页:
static/index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Go Web App in Netlify</title>
</head>
<body><h1>知乎热榜</h1><ul id="contents"></ul><script type="module">let options = {weekday: "short",year: "numeric",month: "short",day: "numeric",hour: "numeric",dayPeriod: "short"};const toDate = new Intl.DateTimeFormat("default", options);(async () => {let data = await fetch("/api/feed").then(rsp => rsp.json());let listEls = [];for (let item of data["data"]) {let row = document.createElement("li");let link = document.createElement("a");link.href = item["target"]["url"];link.innerText = item["target"]["title"];row.append(link);let d = new Date(item["target"]["created"]);row.innerHTML += " " + toDate.format(d);listEls.push(row);}let el = document.getElementById("contents");el.append(...listEls);})();</script>
</body>
</html>
至此,开发工作基本完成,现在需要操作Netlify。我们可以通过创建一个简单的构建命令和一个netlify.toml
配置文件来告诉Netlify如何使用我们的静态文件和Go函数。
我们可以添加build.sh
,告诉Go将我们的二进制文件编译到functions
目录中。
set -euxo pipefailmkdir -p "$(pwd)/functions"
GOBIN=$(pwd)/functions go install ./...
chmod +x "$(pwd)"/functions/*
go env
接下来我们的netlify.toml
文件指定Netlify应该使用该脚本来构建我们的函数并在functions
目录中查看它们。
[build]command = "./build.sh"functions = "functions"publish = "static"[build.environment]GO_IMPORT_PATH = "github.com/surzia/go-netlify-app"GO111MODULE = "on"
由于我们在这个项目中使用Go模块进行依赖管理,我们还需要告诉Netlify将GO111MODULE
设置为on
,并为Netlify提供一个带有GO_IMPORT_PATH的导入路径,以作为构建Go文件的起点。我们可以在项目根目录中添加一个.go-version
文件来指定我们想要的Go版本。
Netlify在/.netlify/functions/binary-name
中提供其所有功能。我们可以重写我们的JavaScript以使用它们的URL。但如果可能的话,最好避免与供应商不必要的紧密耦合。
Netlify为我们提供了一个简单的解决方案,那就是他们的URL重写选项。我们可以将其添加到netlify.toml
的末尾:
[[redirects]]from = "/api/*"to = "/.netlify/functions/gateway/:splat"status = 200
现在,对/api/*
的任何请求都将发送到我们的二进制文件,称为gateway
。status = 200
意味着这应该作为服务器端重写来完成,因此不会有任何客户端重定向。
Netlify每月为我们提供125000次免费函数调用。这对于大约每三分钟一个请求来说已经足够了。作为最终的服务增强,最好通过缓存响应来确保我们不会使用比预期更多的函数调用。Netlify尊重标准的Cache-Control
标头。通过添加w.Header().Set("Cache-Control", "public, max-age=300")
,我们可以告诉Netlify的CDN每5分钟只向我们的函数发出一次请求,并且在我们网站的所有用户之间共享相同的响应。
结论
Netlify绝对不是托管Go服务的唯一方法,但它是最简单的方法之一。 通过其内置的Github和Gitlab集成,只需将Netlify指向一个存储库,它就会在推送到master时自动部署,并创建Pull Requests的部署预览。如果你只是想快速托管一些东西,而不需要花费几天的时间在环境变量秘密共享、内容交付网络缓存、持续交付等的初始设置上,那么Netlify就是不错的选择。
Netlify:
GitHub:go-netlify-app
在netlify上部署golang web应用相关推荐
- CentOS Docker安装配置部署Golang web helloworld
目录[阅读时间:约5分钟] 一.Docker简介 二.Docker的安装与配置[CentOS环境] 三.Docker部署Golang web helloworld 四.Docker与虚拟机的区别 五. ...
- 本篇文档介绍如何手动在ECS实例上部署Java web项目
本篇文档介绍如何手动在ECS实例上部署Java web项目.适用于刚开始使用阿里云进行建站的个人用户. 项目配置 { .section} 本篇教程在示例步骤中使用了以下版本的软件.操作时,请您以实际软 ...
- 在windows上部署IIS web服务
在windows上部署IIS web服务 在windows上部署IIS web服务安装IIS相关环境并利用IIS服务器发布靶站源代码(注意应用程序池使用.net 4.0并开启.NET服务) 1.1程序 ...
- jq写的项目如何部署到静态服务器_如何在阿里云服务器上部署一个Web项目
准备工作: 1:你得有云服务器! 2:你的云服务器上的tomcat必须正常运行! 如何在云服务器上发布一个Web项目? 1:需要制作好一个Web项目: 2:在本地电脑上tomcat上部署后运行正常: ...
- aws部署php程序,实验1:在AWS上部署一个Web Application应用实践
Deploying a Web Applicaiton on AWS 实验目标 通过多个AWS的服务去部署一个web application web application是基于PHP 部署在 EC2 ...
- 在linux上部署一个web项目的小经验
文章目录 设置IP地址和设置IP地址为静态 更改IP和设置IP为静态的方法 其他一些知识点 ps命令一点小知识 CentOS7可视化页面下设置为中文 MySQL部分 MySQL错误代码1130 lin ...
- 在Linux系统上部署java web项目
将Spring boot项目打成jar包后放在服务器进行运行: 部署命令: nohup java -jar mybatis-0.0.1-SNAPSHOT.jar >output 2>&am ...
- 在华为云服务器上部署的web项目,外网不能访问处理方法
解决方法: 在服务器ping外网可以ping通 外网ping服务器无法ping通,可以判断是网络问题. 在华为云服务器的安全组添加出入站,点默认的default安全组进入编辑页面 分别在入方向规则和出 ...
- 阿里云部署java web
转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了如何在阿里云上安装JDK.Tomcat以及其配置过程.最后以一个实例来演示在阿里云上部署Java web项目 ...
最新文章
- cryptojs php 互通_关于PHP7和CryptoJS的AES加密方式互通
- rpc.ratatd安装过程中遇到的问题
- 微软出资10亿美元研究AGI,意与谷歌竞争?
- hdu 1404/zoj 2725 Digital Deletions 博弈论
- 中国十大名画,你知道几幅?(附高清全图)
- 日志库EasyLogging++学习系列(9)—— 性能跟踪功能
- 指数分布java_python-numpy-指数分布实例详解
- VHDL 语法小点(1)
- linux-bzip2压缩
- 探求Floyd算法的动态规划本质
- Nodejs 离线文档下载
- 生物信息学主要研究方向
- 高等数学(同济大学)
- ROS-3DSLAM(十二)lvi-sam源代码阅读10 —— visual_loop阅读3 + ORB学习
- 活动|QuarkChain 高TPS悬赏令:看你能有多快!2.4BTC等你拿!
- forward与sendRedirect区别
- 黄教头第六周作业 一个基础的反射型xss
- 微信视频号视频免费下载最新的4种办法
- VBA取得EXCEL表格中的行数和列数
- 能远程控制你电脑的苹果充电线正在生产和售卖,走一个?