介绍

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/*的任何请求都将发送到我们的二进制文件,称为gatewaystatus = 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应用相关推荐

  1. CentOS Docker安装配置部署Golang web helloworld

    目录[阅读时间:约5分钟] 一.Docker简介 二.Docker的安装与配置[CentOS环境] 三.Docker部署Golang web helloworld 四.Docker与虚拟机的区别 五. ...

  2. 本篇文档介绍如何手动在ECS实例上部署Java web项目

    本篇文档介绍如何手动在ECS实例上部署Java web项目.适用于刚开始使用阿里云进行建站的个人用户. 项目配置 { .section} 本篇教程在示例步骤中使用了以下版本的软件.操作时,请您以实际软 ...

  3. 在windows上部署IIS web服务

    在windows上部署IIS web服务 在windows上部署IIS web服务安装IIS相关环境并利用IIS服务器发布靶站源代码(注意应用程序池使用.net 4.0并开启.NET服务) 1.1程序 ...

  4. jq写的项目如何部署到静态服务器_如何在阿里云服务器上部署一个Web项目

    准备工作: 1:你得有云服务器! 2:你的云服务器上的tomcat必须正常运行! 如何在云服务器上发布一个Web项目? 1:需要制作好一个Web项目: 2:在本地电脑上tomcat上部署后运行正常: ...

  5. aws部署php程序,实验1:在AWS上部署一个Web Application应用实践

    Deploying a Web Applicaiton on AWS 实验目标 通过多个AWS的服务去部署一个web application web application是基于PHP 部署在 EC2 ...

  6. 在linux上部署一个web项目的小经验

    文章目录 设置IP地址和设置IP地址为静态 更改IP和设置IP为静态的方法 其他一些知识点 ps命令一点小知识 CentOS7可视化页面下设置为中文 MySQL部分 MySQL错误代码1130 lin ...

  7. 在Linux系统上部署java web项目

    将Spring boot项目打成jar包后放在服务器进行运行: 部署命令: nohup java -jar mybatis-0.0.1-SNAPSHOT.jar >output 2>&am ...

  8. 在华为云服务器上部署的web项目,外网不能访问处理方法

    解决方法: 在服务器ping外网可以ping通 外网ping服务器无法ping通,可以判断是网络问题. 在华为云服务器的安全组添加出入站,点默认的default安全组进入编辑页面 分别在入方向规则和出 ...

  9. 阿里云部署java web

    转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了如何在阿里云上安装JDK.Tomcat以及其配置过程.最后以一个实例来演示在阿里云上部署Java web项目 ...

最新文章

  1. cryptojs php 互通_关于PHP7和CryptoJS的AES加密方式互通
  2. rpc.ratatd安装过程中遇到的问题
  3. 微软出资10亿美元研究AGI,意与谷歌竞争?
  4. hdu 1404/zoj 2725 Digital Deletions 博弈论
  5. 中国十大名画,你知道几幅?(附高清全图)
  6. 日志库EasyLogging++学习系列(9)—— 性能跟踪功能
  7. 指数分布java_python-numpy-指数分布实例详解
  8. VHDL 语法小点(1)
  9. linux-bzip2压缩
  10. 探求Floyd算法的动态规划本质
  11. Nodejs 离线文档下载
  12. 生物信息学主要研究方向
  13. 高等数学(同济大学)
  14. ROS-3DSLAM(十二)lvi-sam源代码阅读10 —— visual_loop阅读3 + ORB学习
  15. 活动|QuarkChain 高TPS悬赏令:看你能有多快!2.4BTC等你拿!
  16. forward与sendRedirect区别
  17. 黄教头第六周作业 一个基础的反射型xss
  18. 微信视频号视频免费下载最新的4种办法
  19. VBA取得EXCEL表格中的行数和列数
  20. 能远程控制你电脑的苹果充电线正在生产和售卖,走一个?

热门文章

  1. 【IOS】In-App Purchases入门
  2. 故障管理:故障应急和故障复盘
  3. 【AIGC】2、扩散模型 | 到底什么是扩散模型?
  4. OpenDayLight+Mininet+Postman下发流表实验
  5. Linux操作系统和虚拟机VM VirtualBox的安装
  6. 基于 SpringMvc kisso 的 sso 演示 demo
  7. 数据挖掘易犯的11大错误与数据分析技能
  8. Java-Swing- BorderLayout() 边界布局
  9. Robotaxi公司做L2前装量产,机遇与挑战并存
  10. android 资源网址总结