Read the golang plugin hot update attempt

  • 2020-06-12 09:23:08
  • OfStack

When we were developing with php, we hardly needed to worry about hot updates, because PHP itself took care of it for me. All we needed to do was submit the code and PHP reinterpreted it once. go, on the other hand, is a static language. The compiled code is directly executed by the machine. All the code has been translated into corresponding machine instructions and loaded into memory at runtime. It would be a hassle to get hot updates, but as a back-end developer, you are eager to support this functionality, because it would be perfect to add new functionality online and fix the bug client's complete lack of awareness.

This article will not discuss stateless service updates like http for the time being. There are many articles on how to leverage fd inheritance for an elegant restart. The focus here is on using plugin, a new addition to golang 1.8, to update a business that is a game-like stateful service. The official documentation for plugin is relatively simple. It can dynamically load so and perform export methods, and only provides two methods: open module and extract symbol, without even closing (-_-).

A program contains two parts: data and algorithm, so since it is a stateful service, the data part must not move, so the hot more can only move the algorithm part. We need a container to separate the two, one to store the data and one to dynamically load so. We isolate the data from the algorithm, and we can update the algorithm as long as the data exists. Before you start coding, you need to solve a few problems:

1. The same so file will only be opened once

2. There is one pluginpath for each so to identify whether it is repeated. If two so files do not match one, the error of pluginpath1 will still be reported

3. Structures defined by different so files cannot be converted using type assertions

For the above problems, there are the following solutions:

1. Each generation of so has one version number, such as ES35en.1001.so

2. Add --ldflags=" -pluginpath =xxx" parameter when compiling

3. Use unsafe for conversion (notes below)

Code address: https: / / github com/scgywx/myplugin

1. Compile engine, which is the container mentioned above. It is responsible for data storage and loading and execution of so.


sh build.sh

2. Compile version 1 so(note the following parameter)


sh build_so.sh 1

. 3, will src logic/main go modelVersion inside and change to 1002 and game2 modelName (here) is primarily to test the two versions of the content difference between

4. Compile version 2 so


sh build_so.sh 2

5. Run the container


./engine

6. Enter 127.0.0.1 into the browser :12345/hello, and you will see the following display (this is the first version of so used)

hello test, this is golang plugin test!, version=1001, name=game1, oldversion=0, oldName=

7. Browser input 127.0.0.1:12345/load? name= plugin2.ES90en (output done here, indicating that loading so succeeded)

8. Enter 127.0.0.1 again :12345/hello, and you will see the following display.

hello test, this is golang plugin test!, version=1002, name=game2, oldversion=1001, oldName=game1

At this point, our hot update effect has been achieved, but there are still a few limitations

1, each so couldn't save the data, because when the other one so loaded, so data is unable to access to the front, and because the so cannot be shut down, there may be multiple so reference with one variable, gc can't release, so need to share data through the container, so we can't use global variables to store the data in the module.

2, go inside two types even 1 sample, have no direct conversion, so two so defined within the structure have no direct conversion, to use unsafe. Strong Pointer to turn (see src/logic/main go), since it is strong, so the two versions of so use structure definition will not be able to have distinction, otherwise the transformed data may appear abnormal, that is to say hot update cannot be modified structure.

This article is just a technical attempt, no online verification, there are still many pits do not know, hot update is not a must, if supported, is a good thing.


Related articles: