Evolution of WaitGroup in golang

WaitGroup is a concurrency primitive often used in Go concurrent programming to do task scheduling. It looks like it has only a few simple methods and is relatively easy to use. In fact, the internal implementation of WaitGroup has been changed several times, mainly to optimize the atomic operations of its fields. The original implementation of WaitGroup The earliest implementation of WaitGroup is as follows. 1 2 3 4 5

Using mTLS in Linkerd to protect application communications

Security is a top priority for cloud-native applications, and while security is a very broad topic, Linkerd still has an important role to play: its two-way TLS (mTLS) feature is designed to enable a zero-trust approach to security in Kubernetes. Zero-trust security is an IT security model that requires strict authentication for every person and every device that attempts to access resources on a private network, whether located inside or outside the network boundary.

Implementation of retry mechanism

When a service requests a resource, if it encounters a network exception or other situation that causes the request to fail, it needs a retry mechanism to continue the request. A common practice is to retry 3 times and sleep randomly for a few seconds. For business development scaffolding, the HTTP Client basically encapsulates the retry method and automatically retries when the request fails according to the configuration. Here is an example of a common HTTP Client to see how it implements request retry.

Temporal: Microservice workflow orchestration using a familiar programming language

Problem Background Suppose this business scenario: after posting an article, if the article contains a video link, the user needs to download the video and transcode it. There is some subsequent business logic after the transcoding is done. 1 2 3 4 5 6 7 8 9 10 11 12 @RestController class ArticleController { @PostMapping("/article") fun createArticle(article: Article) { if (article.videos.isNotEmpty()) { val urls = videoTranscodeService.transcode(articles.videos) article.setVideoUrls(urls) } // Continue other business logic after video transcoding is complete processArticle(article) } } If this code is written in the article publishing service, and videoTranscodeService is another remote service that provides an asynchronous interface, then we can’t simply write a synchronous method, wait for the method to return and continue executing the business logic later.

Knowledge about Envoy

Development environment build Development based on Ubuntu 18.04. Basic Tools Download Install Bazel 1 2 sudo wget -O /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64 sudo chmod +x /usr/local/bin/bazel Install base dependencies 1 sudo apt-get install libtool cmake automake autoconf make ninja-build curl unzip virtualenv Clang build environment (optional) Download and install from llvm, version 9.0 is more compatible. 1 2 bazel/setup_clang.sh <PATH_TO_EXTRACTED_CLANG_LLVM> echo "build --config=clang" >> user.bazelrc Building DEBUG versions with bazel 1 bazel

Isito Virtual Machine Health Check

Istio is known to have health checks for the VMs it accesses, and for services on k8s, the health check section is included in the Pod. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 apiVersion: v1 kind: Pod metadata: name: goproxy labels: app: goproxy spec: containers: - name: goproxy image: k8s.gcr.io/goproxy:0.1 ports: - containerPort: 8080 readinessProbe: tcpSocket: port: 8080 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: tcpSocket: port: 8080 initialDelaySeconds: 15 periodSeconds: 20 And for VM-accessed Workload, istio provides a similar capability.

Linkerd implements timeouts and retries via ServiceProfile

One of the most important problems that Linkerd Service Mesh solves is observability: providing a detailed view of service behavior, Linkerd’s value proposition for observability is that it can provide golden metrics for your HTTP and gRPC services that are executed automatically, without code changes or developer involvement. Out of the box, Linkerd provides these metrics on a per-service basis: all requests across services, regardless of what those requests are.

Property Reflection in C++

1 Preface Java/Go languages have built-in reflection mechanism to support getting information about classes/methods/properties at runtime. Reflection mechanism has many application scenarios, such as the most common data serialization, if there is no reflection mechanism, either based on code generation, such as protobuf; or is a line of hand-written code that is pure manual work. C++ does not have a built-in set of reflection mechanisms, and implementing reflection mechanisms is

Kubernetes Resource Quotas

Resource Quotas are defined through the ResourceQuota object, which provides an overall resource limit for each namespace: it can limit the total number of objects of a certain type in the namespace, or it can set the total limit of computational resources that can be used by Pods in the namespace. When using resource quotas, there are two things to keep in mind. If the total available resources in the cluster are less than the sum of the resource quotas in each namespace, then this may lead to resource contention.

Kubernetes ResourceQuota and LimitRange Practices

The cluster configuration is adjusted according to the number of cluster users to achieve the purpose of controlling the amount of resources used in a specific namespace and ultimately achieving fair usage and cost control of the cluster. The functions to be implemented are as follows. Limit the amount of compute resources used by Pods in the running state. Limit the number of persistent volumes to control access to storage. Limit the number of load balancers to control costs.

Multiple containers in a Pod share the process namespace

To enable process namespace sharing, simply set shareProcessNamespace=true in the Pod definition. The following example shows the effect of two containers sharing a process namespace in a Pod. The contents of the share-process-namespace.yaml configuration file are as follows. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 apiVersion: v1 kind: Pod metadata: name: nginx spec: shareProcessNamespace: true containers: - name: nginx image: nginx - name: shell image: busybox securityContext: capabilities: add: - SYS_PTRACE stdin: true tty: true The main container is a service provided by nginx, and the other container is an error checking tool provided by busybox, named “shell”.

Simulating the K8s scheduler environment with kube-scheduler-simulator

Since the default Kubernetes scheduler is highly configurable, in many cases we don’t need to write any code to customize the scheduling behavior. However, people who want to understand how the scheduler works or have a need for custom features may try to develop their own scheduler. In this article, I will describe how to build a scheduler development environment with the help of kube-scheduler-simulator, a scheduler simulator. Installing the emulator First, the code for the Clone emulator.

Try using go generate

In Go, there is an unwritten habit that many people like to use generated code, for example, the directory structure of the project, the stub code of grpc are generated by tools, and small ones such as static files embedded in the code, automatically generated enum type String form, etc. Anyway, the pattern of generated code can always be seen. In fact, this may be related to the Go official is also to promote this way, for example, Go from version 1.

Understanding Kubernetes' Service Account

Kubernetes’ Service Account is a type of account managed by Kubernetes, which is particularly convenient to manage, but it is not easy to understand the application context when you are new to this type of account. This article is a complete overview that I have read after reading many documents, and I believe it can provide a certain level of understanding of service accounts. Account Types There are two types of Kubernetes accounts.

Three good gRPC testing tools

Recently, we are using Golang to implement microservices, and the communication interface is gRPC. In addition to writing client-side tests in third-party languages supported by gRPC, are there any good tools to verify the interface implemented by gRPC? This year, we saw that Postman announced that it started to support gRPC, so I believe that you are not too unfamiliar with Postman tool, after all, we rely on this tool to test Websocket or RESTful API.

Signing Git commit records using SSH

Git supports using GPG to sign commit records, but GPG is complicated to use. Git started supporting SSH signatures in 2.34, and since we all have SSH keys, it’s time to turn on signatures. But GitHub didn’t support displaying SSH signatures for a long time after this feature was released, so I didn’t push it forward. Yesterday GitHub announced that it officially supports SSH signatures. I’m going to share a little bit about it with you today.

Reflection in Golang

Let’s start with a simple piece of code logic to warm up. What do you think should be printed in the following code? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 type OKR struct { id int content string } func getOkrDetail(ctx context.

Talking about the design of processes and threads

The concept of concurrency has been around for a long time, and the main idea is to allow multiple tasks to be executed in the same time period in order to get faster results. The first language that supported concurrent programming was assembly language, but there was no theoretical basis for this type of programming, and a small programming error could make the program very unstable and testing of the program almost impossible.

Talking about synchronization in concurrent programming

Interaction inside concurrent programs Why should we consider the problem of synchronization? In many cases, we need multiple processes or threads to cooperate with each other to complete a task, and multiple serial programs may all have to access a shared resource, or pass some data to each other. In this case, we need to coordinate the execution of the programs. The role of synchronization is to avoid possible conflicts during concurrent access to shared resources, as well as to ensure the orderly passing of information.

Why process fork uses copy-on-write

fork is the most widely used process creation mechanism, where a process can create several new processes, the former called parent processes and the latter called child processes, through the system call fork. In order to reduce the process creation overhead, modern operating systems use copy-on-write techniques, where the parent and child processes share the same memory space, thus enabling a “copy” of the data, which will be analyzed in this article.