sharing "go runtime VM" for many go application

325 views
Skip to first unread message

Thaniyarasu Kannusamy

unread,
Nov 29, 2016, 12:47:19 AM11/29/16
to golang-nuts
we all knows that sharing "Linux Kernel" is possible in container world.
i also want to know further that, 
is sharing "Go Runtime VM" is possible in anyway ?
so we can able to share a common "Go Runtime VM" for many go application.
if that is possible then we can able to run 'Go Runtime VM' effectively in serverless architecture.

i know that 'Go Runtime VM' must be start from a "func main()"

Thanks
Thani

Dave Cheney

unread,
Nov 29, 2016, 1:00:28 AM11/29/16
to golang-nuts
No, this is not currently possible.

If it was possible in the future, what would this let you do that you cannot do today?

Thaniyarasu Kannusamy

unread,
Nov 29, 2016, 2:30:09 AM11/29/16
to golang-nuts
thanks Dave,

i am thinking about server less architecture with golang.
i feel that "sharing languange runtime/VM" will be next technology than the container/kubernetes era.
already aws offering lambda service for serverless architecture.

i know that nodejs is running in sandbox mode with event based parallel execution. where node VM is shared for each sandbox.
so i think that node sandbox can be useful to isolate each application scope where we can achieve 'sharing runtime' effectively. 

i am not an expert in core nodejs, so my question to you is 
Is sharing "Nodejs VM" for multiple node application possible ???

sorry for my late reply 

Thanks
Thani

Dave Cheney

unread,
Nov 29, 2016, 2:43:50 AM11/29/16
to golang-nuts
Go is not a virtual machine language, it's compiled to native machine code, like a C program. Each Go program does have a runtime package which provides the garbage collector to manage the programs heap, and Go programs do follow a pattern of over allocating with the expectation that the operating system will lazily fulfil that allocation when the Go program actually does come to use that memory.

It's a moot point at the moment because there is no way to share a Go program's runtime between multiple programs, but I don't think this would achieve the saving you expect compared to JITed virtual machine runtimes like nodejs.

Konstantin Khomoutov

unread,
Nov 29, 2016, 3:22:30 AM11/29/16
to Thaniyarasu Kannusamy, golang-nuts
You might be confusing things here.

The first thing to note is that Go implementations I know of do not
currently implement the so-called "free-standing" compilation mode
which would produce executables not requiring a particular kernel to
work. Instead, the Go runtime which gets linked statically or
dynamically to all the executables produced by Go compilers make heavy
use of the kernel of the underlying host OS. In particular, it assumes
the kernel implements virtual memory, threads, file and socket I/O,
timers and other stuff. That is, as per your definition, the
"serverless" would not have excluded the kernel itself out of the
picture.

Now, if you're okay with still having the Linux kernel in the picture,
all you need to have a Go program work on a bare kernel is to change
the command line of your kernel to include the

init=/path/to/your/go/program

string. After booting, the kernel would run the indicated program as
its "pid 0" process (which is usually something colloquially called an
"init process"). This is really no magic: you will have the kernel and
the single process running on it. This way, you can have a working
solution consisting of pretty much two or three files: the kernel
image, your executable and (possibly) an initramfs image with the early
boot environment for your kernel. Pretty much "serverless", I'd say.

But then you should consider what happens if your single process dies
for some reason. Obviously, if such a setup is intended for sustained
service, you'd need something to monitor your process and restart it.
If that's handled outside your kernel+process combo (say, a container
solution handles this somehow) that's okay; otherwise you'd still need
to have some "not-so-serverless" solution to provide intelligent
restarting of your application and maybe logging.

Now let's move to "the containers". The only means running programs
interact with the kernel is by using the so-called "system calls" (or
"syscalls" for short). Leaving aside the question of how they are
actually implemented, the crucial fact about them is that performing a
syscall has noticeable runtime overhead.

What this leads us to is that should you somehow "factored out" the Go
runtime, you'd need to turn it into pretty much the same kind of
"service" the kernel is to the processes: it'd need to implement
something akin to syscalls, and these would have considerable
call overhead -- simply due to the reason you'd need to protect that VM
from the Go processes it powers.

If you're okay with giving up protection (that is, it's okay for any Go
process to crash the VM and bring down the other Go processes running
on it), let's see what is left. Go runtime basically implements
management of the goroutines -- their requirements for memory (stacks
and heap) and I/O -- and provides a set of library functions.
I fathom the overhead of the Go runtime scheduler in terms of CPU and
memory is not that big so that if you would have just a single instance
of it per N Go processes, it would make any noticeable difference.

You have mentioned sandboxing implemented in node.js. That could
possibly be done to our imaginary "Go runtime host process" as well but
sandboxing is a very complex stuff, prone to bugs. Node appears to get
that "for free" -- merely by virtue this stuff is implemented by the JS
engine it piggybacks on (actually, that's the whole reason Node
came to existence: someone got bored enough to notice that a typical
browser's engine these days has support for both JS and networking at
the same time). I'm not sure it's sensible to tread the same road: the
OS does process separation just OK, and if you want, you have more
powerful stuff to help it -- such as AppArmor/SELinux and seccomp.
In-kernel support for containers (actually, it's all about resource
"namespacing" and having separate limits for them) is essentially also
about "sandboxing" -- just on another level.

To round up, I think you got hooked onto some buzzwords a bit.
The fact node.js does X does not mean X is good or at all needed. ;-)

Thaniyarasu Kannusamy

unread,
Nov 29, 2016, 3:23:36 AM11/29/16
to golang-nuts
Thanks for you reply

Jason Stillwell

unread,
Nov 29, 2016, 4:09:13 AM11/29/16
to golang-nuts
If your talking about creating a Golang Application Server, where multiple unrelated goroutines are running together, and loaded seperately as well. This is possible, I suppose, using the new v1.8 plugin architecture. You could have the managing central main goroutine load the plugins on demand, and kick off the code.

But you'll be missing a lot of standard and vital components from other application servers. There will be no real sandboxing. All the plugins will be sharing the same memory with no control stopping one from accessing the memory and resources of another. Furthermore you wont' be able to unload or reload an "application" (plugin). 

Frankly you're better off just running the applications as separate processes. You can always whip up an external managing process that starts and restarts them, just like init.d of runit

Dave Cheney

unread,
Nov 29, 2016, 4:14:41 AM11/29/16
to golang-nuts
> All the plugins will be sharing the same memory with no control stopping one from accessing the memory and resources of another. Furthermore you wont' be able to unload or reload an "application" (plugin).

This may not be correct. Assuming that they plugin does not use the unsafe paxkage then the memory safety guarnetees of Go should apply. A plugin would bit be able to discover a reference to another value unless it is explicitly provided with one.

Have a look at the singularity project from Microsoft research a decade ago who applied this idea to an entire operating system in a single address space.

Konstantin Khomoutov

unread,
Nov 29, 2016, 4:35:23 AM11/29/16
to Dave Cheney, golang-nuts
On Tue, 29 Nov 2016 01:14:40 -0800 (PST)
Dave Cheney <da...@cheney.net> wrote:

> > All the plugins will be sharing the same memory with no control
> > stopping one from accessing the memory and resources of another.
> > Furthermore you wont' be able to unload or reload an
> > "application" (plugin).
>
> This may not be correct. Assuming that they plugin does not use the
> unsafe paxkage then the memory safety guarnetees of Go should apply.
> A plugin would bit be able to discover a reference to another value
> unless it is explicitly provided with one.

What would happen if a plugin panic()s or merely eats up inordinate
amounts of memory? The OS (usually) has tricks up its sleeve to handle
all such cases.

I know I'm stating the obvious things you're definitely familiar with
-- just trying to highlight the process separation implemented by a
typical general-purpose OS is still a real thing.

Dave Cheney

unread,
Nov 29, 2016, 4:36:41 AM11/29/16
to Konstantin Khomoutov, golang-nuts

I'm was only considering the case where a plugin could access the memory of something it wasn't supposed to.

Reply all
Reply to author
Forward
0 new messages