In-depth understanding of Golang's memory allocation principles

01 Local cache for P: mcache 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // runtime/malloc.go numSpanClasses = _NumSizeClasses << 1 _NumStackOrders = 4 - sys.PtrSize/4*sys.GoosWindows - 1*sys.GoosPlan9 // runtime/mcache.go //go:notinheap type mcache struct { nextSample uintptr scanAlloc uintptr tiny uintptr tinyoffset uintptr tinyAllocs uintptr alloc [numSpanClasses]*mspan stackcache [_NumStackOrders]stackfreelist flushGen uint32 } type stackfreelist struct { list gclinkptr // linked list of free stacks size uintptr // total size of stacks in list } nextSmaple triggers a heap instance after allocating this many bytes.

In-depth understanding of the implementation of rpc.Server in Golang

01 Understanding rpc.Server 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // net/rpc/server.go type Server struct { serviceMap sync.Map // map[string]*service reqLock sync.Mutex // protects freeReq freeReq *Request respLock sync.Mutex // protects freeResp freeResp *Response } func NewServer() *Server { return &Server{} } var DefaultServer = NewServer() 02 Register RPC service 1 2 3 4 5 6 7 func (server *Server) Register(rcvr interface{}) error { return server.

In-depth understanding of the implementation of epoll in Golang

1. Data reception process The process of external data from a computer system is relatively long from the time it enters the NIC to the time it is finally received by the application. The approximate flow is as follows. The NIC receives the data, copies it to the kernel space through the DMA controller, and at the same time initiates a hard interrupt to the CPU. The CPU receives the

In-depth understanding of Golang channel implementation

01 channel definition 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // /usr/data/go1.17/go/src/runtime/chan.go type hchan struct { qcount uint // total data in the queue dataqsiz uint // size of the circular queue buf unsafe.Pointer // points to an array of dataqsiz elements elemsize uint16 closed uint32 elemtype *_type // element type sendx uint // send index recvx uint // receive index recvq waitq // list of recv waiters sendq waitq // list of send waiters lock mutex } type waitq struct { first *sudog last *sudog } The underlying data structure of channel is hchan, which itself consists of buf forming a circular linked list, which is a circular queue.

In-depth understanding of zero-copy technology

01 How processes read data A process has its own separate heap area memory and stack area memory, so it can only read the area of memory that belongs to it. If it needs to access a device outside the process, then it can only be handled by the operating system on its behalf. The operation by which a process requests access to a device from the operating system is called a system call (system call).

In-depth understanding of the Golang timer implementation principle

01 time.timer 1 2 3 4 5 6 7 8 9 10 11 12 // runtime/time.go type timer struct { pp puintptr when int64 period int64 f func(interface{}, uintptr) arg interface{} seq uintptr nextwhen int64 status uint32 } timer is defined in runtime/time.go. pp is a pointer to the current counter on p and a pointer to the heap. when is the scale, indicating how often to trigger. nextWhen indicates the nanosecond timestamp of the next trigger, the underlying cpu time of the call.

Several strategies for implementing load balancing

Consider the scenario, an API gateway that distributes requests to multiple upstream nodes, as in the upstream configuration of nginx. 1 2 3 4 5 6 7 8 9 10 11 12 upstream backend { server weight=5; server; server backup; server backup; } server { location / { proxy_pass http://backend; } } There are many common practices on how to distribute the routes / equally to the four services, in general, such as randomized algorithms, etc.

Several ways to splice strings in Golang

String Splicing Definition Define a method that implements string splicing, with the following function signature prototype. 1 type concatFn func(...string) string That is, pass in a series of strings and return the result of their stitching. Way 1: Use the + operator 1 2 3 4 5 6 7 func ConcatWithAdd(strs ...string) string { var r = "" for _, v := range strs { r += v } return r } Obviously, the performance of this approach is poor.

In-depth understanding of containerization technologies

The following is a standard explanation of containerization. A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings. Containers are different from virtual

Golang's go:linkname directive

Suppose there is an internal package that provides a method as follows. 1 2 3 4 5 6 7 package internal import "fmt" func print(msg string) { fmt.Println("[internal]", msg) } This method is used internally, it has no export properties, so it can’t be imported by other external packages, so since this is the case, is there any way to call this method outside the package? The answer is yes, except that this hack blocks at least 80% of Gopher’s knowledge, and it is go:linkname.

Cloud-native virtual networking tun/tap & veth-pair

Overview The mainstream virtual NIC solutions are tun/tap and veth, with tun/tap appearing much earlier in time. The kernel released after Linux Kernel version 2.4 compiles tun/tap driver by default, and tun/tap is widely used. In the cloud-native virtual network, flannel0 in the UDP mode of flannel is a tun device, and OpenVPN also uses tun/tap for data forwarding. veth is another mainstream virtual NIC solution. In Linux Kernel version 2.

Ensuring Concurrency Safety with Atomic Operations in Golang

Scenarios In many backend services, configuration files or dictionary data need to be loaded dynamically. So when accessing these configurations or dictionaries, it is necessary to add locks to these data to ensure the security of concurrent reads and writes. Normally, read and write locks are required. Here’s an example of a read/write lock. Read/Write Locks to Load Data Using read/write locks ensures that access to data does not result

Building a Zero-Copy File Web Server in Golang

This article starts with Golang’s file server, then explores what the sendfile system call is, and finally summarizes the usage scenarios for zero-copy. Build a file server How to build a zero-copy file server in Golang, here is the complete code. 1 2 3 4 5 6 7 8 package main import "net/http" func main() { http.Handle("/", http.StripPrefix("/static/", http.FileServer(http.Dir("./output")))) http.ListenAndServe(":8000", nil) } Well, yes. Two lines of code to implement a file server.

Google has open sourced an alternative programming language to C++: Carbon

Google engineer Chandler Carruth recently announced at the CppNorth conference in Toronto, officially open-sourcing Google’s internally built programming language: Carbon. He also called Carbon the successor to C++ (which is currently in the experimental stage). Chandler cites examples of the evolution of today’s popular programming languages, such as Java to Kotlin, Objective-C to Swift, JavaScript to TypeScript, and C++, which is widely used within Google and is seen as somewhat of a successor to C.

Kubernetes Architecture

Kubernetes is just like its original meaning “helmsman” in English, commanding, scheduling… It is such a container orchestration and scheduling infrastructure platform, derived from Google’s internal container cluster management platform Borg, which was released in 2003. Borg was released in 2003, from a small project to an internal cluster management system that supports thousands of applications and tasks within Google, its success speaks for itself. In 2014, Google released Kubernetes as an open-source version of Borg, which was exciting, and then Microsoft, IBM, and RedHat joined the Kubernetes community to add to it.

Kubernetes Rolling Upgrade

Users expect applications to be available all the time, and developers need to deploy new versions of them multiple times a day. In Kubernetes, this is accomplished with Rolling Updates. Rolling updates allow Pod instances to be updated incrementally by using new instances. Deployment updates are performed with zero downtime. Kubernetes Rolling Update Basic Concepts Concepts When a service in a cluster needs to be updated, the traditional approach is to take the service to be updated offline, update the version and configuration after the business is stopped, and then restart and provision the service.

Understanding Kubernetes' Resource design concepts

Kubernetes is a completely resource-centric container orchestration platform, which is evident from the design of the REST API exposed by kube-apiserver, and the ecosystem of Kubernetes revolves around the control and maintenance of many component resources, so it can be considered as a “resource control system” in essence. Group / Version / Resource For the concept of resource, if in a large and complex container orchestration platform designed only such a simple “resource” semantics is obviously a bit thin, or expression is too weak, so for such a concept of resources, in Kubernetes and grouped and versioned words, so there are some terms we usually see in operations and development: Group / Version / Resource / Kind, respectively: Resource Group / Resource Version / Resource / Resource Type.

Getting Started with Zig Programming Language

I’ve written some practice projects when I learned C before, but I haven’t tested them. there are more unit testing frameworks in C, so I don’t know which one to choose, so I might as well just use Zig to do the testing. I just saw this article Testing and building C projects with Zig, and I feel it is a good choice. I’ve heard about Zig for half a year, and I’m interested in the libc-independent, better C interop, and robust features.

Developing eBPF applications with Golang

In the previous article “Developing a Hello World level eBPF program from scratch using C”, we explained in detail how to develop an eBPF program (including its user state part) from scratch based on C and the libbpf library. That article was the basis for subsequent articles on eBPF program development, because until now the kernel state part of an eBPF program running in the kernel state had to be developed in C, no matter what language the user state part of the eBPF program was developed in.

Kubernetes & Docker Networking Principles (III)

kube-proxy operational mechanism To support horizontal scaling and high availability of clusters, Kubernetes abstracts the concept of a Service, which is an abstraction of a set of Pods that are accessed according to an access policy (e.g., load balancing policy). Kubernetes assigns a virtual IP address to the Service when it is created, and clients access the Service by accessing the virtual Clients access the service by accessing the virtual IP address, and the service is responsible for forwarding requests to the back-end Pods.