did some grinding off camera
This commit is contained in:
parent
b036acd3f4
commit
302d405cc3
14 changed files with 169 additions and 91 deletions
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
|
@ -0,0 +1,88 @@
|
|||
2
|
||||
Minecraft Rust Async Networking Proxy CRIU
|
||||
# Minecraft servers are HUNGRY
|
||||
|
||||
They hunger for your ram and your cpu. This makes it either expensive or
|
||||
laggy to try and host multiple servers at once.
|
||||
|
||||
This was something I encountered when my friend built a homeserver out of
|
||||
spare computer parts that was barely powerful enough to run a minecraft
|
||||
server.
|
||||
|
||||
The problem was that soon multiple people wanted a minecraft server
|
||||
hosted by him (which included us wanting to play modded minecraft).
|
||||
|
||||
It was a hassle to ssh into the server and start and stop the various
|
||||
servers depending on who wanted to play, especially since a lot of people
|
||||
only played very rarily.
|
||||
|
||||
I remembered that I'd seen
|
||||
[a project](https://github.com/gekware/minecraft-server-hibernation)
|
||||
that claimed to be able to hibernate a minecraft server if nobody was
|
||||
playing on it. The only issue was that it worked for a single server, and
|
||||
did so by starting and stopping the server process.
|
||||
|
||||
This meant that if we wanted to join a modded server the hundreds of mods
|
||||
could make us wait for several minutes before we could play.
|
||||
|
||||
Another issue was the fact that it could only host a single server. This
|
||||
meant that we would have to run multiple intances of the watcher, and that
|
||||
each server would be assigned to an arbitrary port that would be needed
|
||||
when connecting.
|
||||
|
||||
# Building a reverse proxy for minecraft
|
||||
|
||||
Since my friends server was accessible through a domain we thought it
|
||||
would be cool if instead of supplying a port you could connect to a
|
||||
subdomain and be sent to a specific server.
|
||||
|
||||
The simplest way to do this would be to create a dhcp record for each
|
||||
subdomain to point to a server, but that would be slow and tedious to set
|
||||
up for every server.
|
||||
|
||||
We then tried nginx, as it seemingly could magically redirect traffic to
|
||||
an internal port based on the subdomain. I quickly found out that this did
|
||||
*not* work for minecraft servers (who would have guessed), but after doing
|
||||
some research I decided on creating my own reverse proxy that spoke the
|
||||
minecraft protocol instead of HTTP.
|
||||
|
||||
# The Minecraft protocol
|
||||
|
||||
Minecraft implements its own protocol consistent of packets. My first idea was to see if anybody had created a
|
||||
rust library for dealing with minecraft packets.
|
||||
|
||||
While some did exist, most of them where unfinished or couldn't do what I wanted. [One crate](https://www.youtube.com/watch?v=E4WlUXrJgy4)
|
||||
was useful for seeing how an implementation of parsing packets was done, but ultimately I had to write my own parser.
|
||||
|
||||
*images of minecraft protocol*
|
||||
|
||||
# Detecting the subdomain
|
||||
|
||||
Luckily for me, the Minecraft procotol sends the full address it is trying to connect to during the handshake. This meant that I simply
|
||||
had to parse the handshake and extract the subdomain from the address, see if it matches any configured server, and then redirect all
|
||||
traffic to the internal port that server runs on.
|
||||
|
||||
*code explanation*
|
||||
|
||||
# Why aren't my chunks loading?
|
||||
|
||||
Just as I thought I was finally done I encountered a problem. The chunks where loading *really* slowly. It felt like we we're back to
|
||||
hosting on [aternos](aternos.org) (nothing against aternos, the **free** servers are just a little slow).
|
||||
|
||||
*image of chunks not loading*
|
||||
|
||||
I couldn't figure out why it was so slow. I thought it was because all the traffic had to flow through my program,
|
||||
but the sockets are connected on the kernel level.
|
||||
|
||||
After hours of debugging I found the solution. `stream.set_nodelay(true)`
|
||||
|
||||
## ...
|
||||
|
||||
**All this time the problem was as simple as saying ** `if (slow) { dont(); }`!
|
||||
|
||||
To say I was pissed was an understatement, but at the same time I was glad it was finally working.
|
||||
|
||||
The reason this fixed it was because it disabled [Nagle's algorithm](https://en.wikipedia.org/wiki/Nagle%27s_algorithm), which bunches packets together
|
||||
in order to (hopefully) speed up the sending of lots of smaller packets as one big packet.
|
||||
|
||||
For some reason this absolutely destroyed the chunk loading speed, and disabling it led to finally having the perfect Minecraft reverse proxy hibernation system thing.
|
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
Loading…
Add table
Add a link
Reference in a new issue