This is a creation in Article, where the information may have evolved or changed.
When we use PHP development, basically do not need to care about the hot update this matter, because PHP itself has been handled for me, just to submit the code, PHP re-explain it again. And go is a static language, compiled to be executed directly by the machine, all the code has been translated into the corresponding machine instructions and at runtime has been loaded into memory, can not be updated dynamically. So if you want to hot update is a problem, but as a back-end developer, very eager to support this feature, after all, it is possible to add new features online, fix bug client is completely unaware of how perfect.
This article does not discuss HTTP this stateless service update, online can search many articles on how to use FD inheritance to achieve graceful restart. The main discussion here is to use the Golang 1.8 new plugin for business updates, and the business is a stateful service similar to the game. The plugin description in the official documentation is simple, he can dynamically load so and execute the export method, and only provides two methods: Open the module and extract the symbol, even close without (-_-).
A program consists of two parts: data and algorithms, so since there is a stateful service, the data part must not move, then the heat can only move the algorithm part. At this point we need a container to isolate the two parts, on the one hand, to store the data and dynamically load so. Data and algorithms are isolated, and as long as the data exists, we are free to update the algorithm. Before you begin coding, there are several issues to resolve:
1, the same so file will only be opened once
2, each so has a pluginpath used to identify whether duplicate, if two so files are different, but the same as Pluginpath will still error
3. Structures defined by different so files cannot be converted using type assertions
For the above problem, there are the following solutions:
1, each generated so with a version number such as Game.1001.so
2, when compiling the new--ldflags= "-pluginpath=xxx" parameter
3. Use unsafe for conversion (note below)
Code Address: Https://github.com/scgywx/myplugin
1, compile engine, this is what we said above the container, he is responsible for data storage and so loading and execution.
sh build.sh
2. Compile the 1th version so (note that there is a parameter later)
sh build_so.sh 1
3, the src/logic/main.go inside the modelversion and modelname respectively changed to 1002 and game2 (here is mainly testing two versions of the content difference)
4. Compile the 2nd version of So
sh build_so.sh 2
5. Running the container
./engine
6, the browser input 127.0.0.1:12345/hello, you will see the following display (this is the first version of SO)
hello test, this is golang plugin test!, version=1001, name=game1, oldversion=0, oldName=
7, the browser input 127.0.0.1:12345/load?name=plugin2.so (here output done, it means that the load so successful)
8, re-enter 127.0.0.1:12345/hello, you will see the following display.
hello test, this is golang plugin test!, version=1002, name=game2, oldversion=1001, oldName=game1
Here, our heat update effect has been achieved, but there are some limitations
1, each so cannot save the data alone, because when another so load, the previous so data is no way to access, and because so cannot be closed, there may be multiple so reference the same variable, GC can not be released, so need to share data through the container, Then we cannot use global variables in the module to hold the data.
2, go inside two types even if the same, can not directly convert, so the structure defined in two so can not be directly converted, to use unsafe. Pointer to make a strong turn (see SRC/LOGIC/MAIN.GO), since it is strong, then two versions of so use the structure definition can not be different, otherwise the data can be transformed after the exception, that is, hot update can not modify the structure .
This article is just a technical attempt, no online verification, and how many pits still do not know, hot update is not necessary, if supported, is good.