aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXe Iaso <me@christine.website>2022-09-04 21:12:58 +0000
committerXe Iaso <me@christine.website>2022-09-04 21:12:58 +0000
commite024cc3808162726eb437ef7aee10051ee8d0a52 (patch)
treea57e3cc08d4b3d6b0ecbb3ff22971354191be7dd
parent8f10fb82dc09249eabe1224d5478ffa0430960bd (diff)
downloadxesite-e024cc3808162726eb437ef7aee10051ee8d0a52.tar.xz
xesite-e024cc3808162726eb437ef7aee10051ee8d0a52.zip
blog: add xedn
Signed-off-by: Xe Iaso <me@christine.website>
-rw-r--r--blog/xedn.markdown109
-rw-r--r--static/blog/xedn-after.svg58
-rw-r--r--static/blog/xedn-before.svg72
3 files changed, 239 insertions, 0 deletions
diff --git a/blog/xedn.markdown b/blog/xedn.markdown
new file mode 100644
index 0000000..fcf7c76
--- /dev/null
+++ b/blog/xedn.markdown
@@ -0,0 +1,109 @@
+---
+title: "Announcing the glorious advent of XeDN"
+date: 2022-09-04
+---
+
+<xeblog-hero ai="Stable Diffusion" file="sky-datacentre" prompt="A datacentre in the clouds sending down letters and packages, digital painting, matte painting, concept art, greg rutkowski, daytime"></xeblog-hero>
+
+<xeblog-conv name="Numa" mood="delet">For someone that calls themselves an
+"archmage of infrastructure" you sure don't do much heckin' infrastructure
+work.</xeblog-conv>
+
+<xeblog-conv name="Mara" mood="hmm">All those conference talks take a lot of
+time, effort, and energy to create. Not to mention things have been stable
+enough that we don't _really_ have to care.</xeblog-conv>
+
+<xeblog-conv name="Numa" mood="delet">You say this as someone who has a "CDN"
+domain where the "CDN" doesn't actually cache things correctly.</xeblog-conv>
+
+<xeblog-conv name="Mara" mood="sh0rck">W...what? I thought that it was taken
+care of.</xeblog-conv>
+
+<xeblog-conv name="Numa" mood="delet">Go look at the storage bill lol. Boom.
+Roasted.</xeblog-conv>
+
+So I made a mistake with how the CDN for my website works. I use a CDN for all
+the static images on my blog, such as the conversation snippet images and the AI
+generated "hero" images. This CDN is set up to be a caching layer on top of
+[Backblaze B2](https://www.backblaze.com/b2/cloud-storage.html), an object
+storage thing for the cloud.
+
+There's only one major problem though: every time someone loads a page on the
+website, assets get routed to the CDN. I thought the CDN was configured to cache
+things. Guess what it hasn't been doing.
+
+<xeblog-conv name="Cadey" mood="facepalm">Oh god...</xeblog-conv>
+
+This is roughly what I've intended the flow to look like when I was designing
+this blog:
+
+![](/static/blog/xedn-before.svg)
+
+I wanted the flow to go from users to the CDN, and the CDN would reach into its
+cache to make things feel snappy. If it wasn't in the cache, the CDN would just
+reach out into B2 and grab it, then store that in the cache. This allows normal
+user behavior to automatically populate the cache and then every future visitor
+gets things more quickly.
+
+However, because of things that I don't completely understand, when I moved from
+`christine.website` to `xeiaso.net` something got messed up in one of the page
+rules and my CDN domain went from almost always caching everything to never
+caching anything. This is not good.
+
+<xeblog-conv name="Numa" mood="delet">We need a hero for this fallen land.
+Everything has gone to ruin and there is only one savior!</xeblog-conv>
+
+<xeblog-conv name="Cadey" mood="facepalm">Oh no, what now. Are you going to
+announce another one of those weird alt-universe Xe-things that makes a horrible
+pun on a common tech term?</xeblog-conv>
+
+<xeblog-conv name="Numa" mood="delet">We
+need...[XeDN](https://cdn.xeiaso.net).</xeblog-conv>
+
+<xeblog-conv name="Cadey" mood="facepalm">You are, aren't you.</xeblog-conv>
+
+<xeblog-hero ai="Stable Diffusion" file="cyberpunk-hacker" prompt="Cyberpunk cyber hacker in the neon city at midnight"></xeblog-hero>
+
+So yes, I have my own CDN service now apparently. The overall architecture of
+how XeDN fits into everything looks something like this:
+
+![](/static/blog/xedn-after.svg)
+
+XeDN is built on top of Go's [standard library HTTP
+server](https://pkg.go.dev/net/http) and a few other libraries:
+
+- [groupcache](https://pkg.go.dev/github.com/golang/groupcache) for in-ram
+ Last-Recently-Used caching
+- [ln](https://pkg.go.dev/within.website/ln) (the _natural_ log function) for
+ the logging stack
+- [tsnet](https://pkg.go.dev/tailscale.com/tsnet) to allow me to access the
+ debug routes more securely over Tailscale
+- [xff](https://pkg.go.dev/github.com/sebest/xff) to parse X-Forwarded-For
+ headers for me
+
+<xeblog-conv name="Cadey" mood="angy">I wouldn't have had to _make_ XeDN if
+Varnish and HAProxy didn't force you to pay for the enterprise tier to connect
+to backend servers over HTTPS. Yes, I could bodge something with Go to just
+reverse proxy to HTTPS and use Varnish as-is, but at that point it's probably
+easier to just do the whole thing in Go in the first place.</xeblog-conv>
+
+This allows me to have a caching CDN service in less than 250 lines of Go. I run
+XeDN on top of [fly.io](https://fly.io) in multiple regions, so it's one of the
+first things I've made for this blog that is actually a redundant service
+geo-replicated across multiple datacentres. It's pretty nice.
+
+<xeblog-conv name="Cadey" mood="enby">Fly really make [a great
+product](https://xeiaso.net/blog/fly.io-heroku-replacement) and I can't suggest
+it more if you're looking at [moving off Heroku](https://xeiaso.net/blog/rip-heroku).
+</xeblog-conv>
+
+I switched over my CDN to use XeDN yesterday and nobody noticed at first. The
+only reason people noticed at all is because I tweeted about it. Either way,
+things should be very fast now. This should scale to meet my CDN needs a lot
+better than the previous setup and everything should be a lot more streamlined
+in the future.
+
+<xeblog-conv name="Numa" mood="delet">You do know that your blog isn't being
+cached either, right?</xeblog-conv>
+
+<xeblog-sticker name="Cadey" mood="percussive-maintenance"></xeblog-sticker>
diff --git a/static/blog/xedn-after.svg b/static/blog/xedn-after.svg
new file mode 100644
index 0000000..006bdee
--- /dev/null
+++ b/static/blog/xedn-after.svg
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.40.1 (20161225.0304)
+ -->
+<!-- Title: G Pages: 1 -->
+<svg width="352pt" height="132pt"
+ viewBox="0.00 0.00 351.67 131.83" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 127.8313)">
+<title>G</title>
+<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-127.8313 347.6689,-127.8313 347.6689,4 -4,4"/>
+<!-- user -->
+<g id="node1" class="node">
+<title>user</title>
+<ellipse fill="none" stroke="#000000" cx="27.1221" cy="-41.4156" rx="27.2447" ry="18"/>
+<text text-anchor="middle" x="27.1221" y="-37.2156" font-family="Times,serif" font-size="14.00" fill="#000000">user</text>
+</g>
+<!-- cdn -->
+<g id="node2" class="node">
+<title>cdn</title>
+<ellipse fill="none" stroke="#000000" cx="127.4814" cy="-94.4156" rx="36.4761" ry="18"/>
+<text text-anchor="middle" x="127.4814" y="-90.2156" font-family="Times,serif" font-size="14.00" fill="#000000">XeDN</text>
+</g>
+<!-- user&#45;&gt;cdn -->
+<g id="edge2" class="edge">
+<title>user&#45;&gt;cdn</title>
+<path fill="none" stroke="#000000" d="M48.4057,-52.6556C61.4615,-59.5504 78.4761,-68.5358 93.3765,-76.4047"/>
+<polygon fill="#000000" stroke="#000000" points="91.8494,-79.5563 102.3265,-81.1313 95.1183,-73.3665 91.8494,-79.5563"/>
+</g>
+<!-- my_blog -->
+<g id="node4" class="node">
+<title>my_blog</title>
+<ellipse fill="none" stroke="#000000" cx="127.4814" cy="-29.4156" rx="30.6326" ry="29.3315"/>
+<text text-anchor="middle" x="127.4814" y="-33.6156" font-family="Times,serif" font-size="14.00" fill="#000000">My</text>
+<text text-anchor="middle" x="127.4814" y="-16.8156" font-family="Times,serif" font-size="14.00" fill="#000000">Blog</text>
+</g>
+<!-- user&#45;&gt;my_blog -->
+<g id="edge1" class="edge">
+<title>user&#45;&gt;my_blog</title>
+<path fill="none" stroke="#000000" d="M54.0165,-38.1999C64.152,-36.988 75.9159,-35.5814 87.0197,-34.2537"/>
+<polygon fill="#000000" stroke="#000000" points="87.4521,-37.727 96.9658,-33.0644 86.621,-30.7765 87.4521,-37.727"/>
+</g>
+<!-- b2 -->
+<g id="node3" class="node">
+<title>b2</title>
+<ellipse fill="none" stroke="#000000" cx="291.1307" cy="-94.4156" rx="52.5764" ry="29.3315"/>
+<text text-anchor="middle" x="291.1307" y="-98.6156" font-family="Times,serif" font-size="14.00" fill="#000000">Backblaze</text>
+<text text-anchor="middle" x="291.1307" y="-81.8156" font-family="Times,serif" font-size="14.00" fill="#000000">B2</text>
+</g>
+<!-- cdn&#45;&gt;b2 -->
+<g id="edge3" class="edge">
+<title>cdn&#45;&gt;b2</title>
+<path fill="none" stroke="#000000" d="M163.8005,-94.4156C182.7412,-94.4156 206.4519,-94.4156 228.2614,-94.4156"/>
+<polygon fill="#000000" stroke="#000000" points="228.4538,-97.9157 238.4538,-94.4156 228.4537,-90.9157 228.4538,-97.9157"/>
+<text text-anchor="middle" x="201.1556" y="-98.6156" font-family="Times,serif" font-size="14.00" fill="#000000">Maybe</text>
+</g>
+</g>
+</svg>
diff --git a/static/blog/xedn-before.svg b/static/blog/xedn-before.svg
new file mode 100644
index 0000000..fa81a22
--- /dev/null
+++ b/static/blog/xedn-before.svg
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.40.1 (20161225.0304)
+-->
+<!-- Title: G Pages: 1 -->
+<svg width="451pt" height="144pt"
+viewBox="0.00 0.00 451.13 143.83" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 139.8313)">
+<title>G</title>
+<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-139.8313 447.1303,-139.8313 447.1303,4 -4,4"/>
+<!-- user -->
+<g id="node1" class="node">
+<title>user</title>
+<ellipse fill="none" stroke="#000000" cx="27.1221" cy="-67.4156" rx="27.2447" ry="18"/>
+<text text-anchor="middle" x="27.1221" y="-63.2156" font-family="Times,serif" font-size="14.00" fill="#000000">user</text>
+</g>
+<!-- cdn -->
+<g id="node2" class="node">
+<title>cdn</title>
+<ellipse fill="none" stroke="#000000" cx="122.6636" cy="-67.4156" rx="31.339" ry="18"/>
+<text text-anchor="middle" x="122.6636" y="-63.2156" font-family="Times,serif" font-size="14.00" fill="#000000">CDN</text>
+</g>
+<!-- user&#45;&gt;cdn -->
+<g id="edge1" class="edge">
+<title>user&#45;&gt;cdn</title>
+<path fill="none" stroke="#000000" d="M54.2449,-67.4156C62.5822,-67.4156 71.9586,-67.4156 81.0343,-67.4156"/>
+<polygon fill="#000000" stroke="#000000" points="81.0818,-70.9157 91.0818,-67.4156 81.0818,-63.9157 81.0818,-70.9157"/>
+</g>
+<!-- cdn_cache -->
+<g id="node3" class="node">
+<title>cdn_cache</title>
+<ellipse fill="none" stroke="#000000" cx="227.1316" cy="-67.4156" rx="36.0972" ry="29.3315"/>
+<text text-anchor="middle" x="227.1316" y="-71.6156" font-family="Times,serif" font-size="14.00" fill="#000000">CDN</text>
+<text text-anchor="middle" x="227.1316" y="-54.8156" font-family="Times,serif" font-size="14.00" fill="#000000">Cache</text>
+</g>
+<!-- cdn&#45;&gt;cdn_cache -->
+<g id="edge2" class="edge">
+<title>cdn&#45;&gt;cdn_cache</title>
+<path fill="none" stroke="#000000" d="M154.2909,-67.4156C162.5784,-67.4156 171.69,-67.4156 180.5795,-67.4156"/>
+<polygon fill="#000000" stroke="#000000" points="180.8503,-70.9157 190.8503,-67.4156 180.8503,-63.9157 180.8503,-70.9157"/>
+</g>
+<!-- b2 -->
+<g id="node4" class="node">
+<title>b2</title>
+<ellipse fill="none" stroke="#000000" cx="390.5922" cy="-106.4156" rx="52.5764" ry="29.3315"/>
+<text text-anchor="middle" x="390.5922" y="-110.6156" font-family="Times,serif" font-size="14.00" fill="#000000">Backblaze</text>
+<text text-anchor="middle" x="390.5922" y="-93.8156" font-family="Times,serif" font-size="14.00" fill="#000000">B2</text>
+</g>
+<!-- cdn_cache&#45;&gt;b2 -->
+<g id="edge3" class="edge">
+<title>cdn_cache&#45;&gt;b2</title>
+<path fill="none" stroke="#000000" d="M261.7974,-75.6865C282.2156,-80.5581 308.5789,-86.8481 332.13,-92.4672"/>
+<polygon fill="#000000" stroke="#000000" points="331.4864,-95.9118 342.0257,-94.8282 333.111,-89.1029 331.4864,-95.9118"/>
+<text text-anchor="middle" x="300.6171" y="-92.6156" font-family="Times,serif" font-size="14.00" fill="#000000">Maybe</text>
+</g>
+<!-- my_blog -->
+<g id="node5" class="node">
+<title>my_blog</title>
+<ellipse fill="none" stroke="#000000" cx="390.5922" cy="-29.4156" rx="30.6326" ry="29.3315"/>
+<text text-anchor="middle" x="390.5922" y="-33.6156" font-family="Times,serif" font-size="14.00" fill="#000000">My</text>
+<text text-anchor="middle" x="390.5922" y="-16.8156" font-family="Times,serif" font-size="14.00" fill="#000000">Blog</text>
+</g>
+<!-- cdn_cache&#45;&gt;my_blog -->
+<g id="edge4" class="edge">
+<title>cdn_cache&#45;&gt;my_blog</title>
+<path fill="none" stroke="#000000" d="M262.198,-59.2637C288.2339,-53.2111 323.7711,-44.9497 350.8582,-38.6527"/>
+<polygon fill="#000000" stroke="#000000" points="351.8407,-42.0177 360.7884,-36.3442 350.2556,-35.1995 351.8407,-42.0177"/>
+<text text-anchor="middle" x="300.6171" y="-58.6156" font-family="Times,serif" font-size="14.00" fill="#000000">Maybe</text>
+</g>
+</g>
+</svg>