Boulevard to Jane-go language Best Practices-cloud + community

Source: Internet
Author: User
Tags docker swarm

Guide: 2007, a Google Chief software engineer who was tired of C + +, Rob Pike, who mustered Robert Griesemer and Ken Thompson two bulls, decided to create a new language to replace C + +, which is Golang. The go language, which appeared in the 21st century, could not be replaced by C + +, but its near-c performance and the development efficiency of near-analytic languages and almost perfect compilation speed have swept the world. Especially in the cloud project, most of them use Golang to develop, have to say, Golang already deeply rooted. For a new project with no historical burden, Golang may be a choice.

Rob Pike, the father of the go language, says that if you agree with the go language, it depends on whether you are endorsing less or much, or less or less. Rob Pike, in a very simple way, sums up the entire design philosophy of the go language-simple and practical.

Many people refer to the go language as the C language of the 21st century, because go not only has the simplicity and performance of C, but also provides a variety of practical features of server development in the 21st century Internet environment, so that developers can easily get what they want at the language level.

This article outlines:

    • The development and present situation of go language
    • Development history
    • Development team
    • Business case
    • Go language Key Features
    • Concurrency and co-processes
    • Communication mode based on message passing
    • Rich and useful built-in data types
    • function multiple return value
    • Defer delay processing mechanism
    • Reflection (reflect)
    • High-Performance HTTP Server
    • Engineering Management
    • Programming specifications
    • API Rapid Development Framework Practice
    • Why we choose the Go language
    • Implementation of API Framework
    • Common component Capabilities
    • Generic List Components
    • Common form Components
    • Federation Pool
    • Data validation
    • Summary
    • Performance evaluation
    • Points to note in the development process

the development and present situation of go language

Development history

In September 2007, Rob Pike compiled C + + on the Google Distributed compilation platform, and during the lengthy wait, he and Robert Griesemer discussed some of the key issues in the programming language, which they thought Simplifying programming languages is a lot more progress than adding new features to a bloated language. Then they persuaded Ken Thompson around the end of the compilation and felt the need to do something about it. A few days later, they launched a project called Golang, which serves as an experimental project for free time.

In May 2008, Google discovered the great potential of the go language and was fully supported by Google, who began to devote full time to the design and development of the go language.

The first version of the Go language was released in November 2009. March 2012 The first official version of Go1.0 released.

August 2015 go1.5 released, this version is considered historic. Completely remove the C language section, use go to compile go, a small amount of code using the assembly implementation. In addition, they invited the authoritative expert in memory management, Rick Hudson, to redesign the GC to support concurrent GC, which solves the problem of GC delay (STW), which has been widely criticized for a long time. And in subsequent releases, the GC has been further optimized. When go1.8, the GC latency under the same business scenario can be controlled from go1.1 for a few seconds and within 1ms. The solution of GC problem, it can be said that the go language in the service side development, almost wiped out all the weaknesses.

In the Go language version iterations, the language features are largely unchanged, largely maintained on the GO1.1 benchmark, and the official promise that the new version is fully compatible with the code developed under the old version. In fact, the Go development team is very cautious about adding language features, and continues to optimize for stability, compilation speed, execution efficiency, and GC performance.

Development team

Go language Development camp can be said to be unprecedented and powerful, the main members of the computer software industry, the historical figures, the development of computer software has far-reaching impact. Ken Thompson, from Bell Labs, designed the B language, created the UNIX operating system (originally implemented with the B language), and then, in the course of UNIX development, designed the C language together with Dennis Ritchie, and then reconstructed the UNIX operating system using C language. Dennis Ritchie and Ken Thompson, known as the Father of Unix and C, were jointly awarded the Turing Award in 1983 in recognition of their outstanding contribution to the development of computer software. Rob Pike, also from Bell Labs, an important member of the UNIX team, invented the Limbo language and, together with Ken Thompson, designed UTF-8 coding, the UNIX programming environment, and one of the authors of the programming practice.

It can be said that the go language backed by Google this tree, there are no shortage of cattle people, is a veritable "cattle of the second generation."

The famous docker, completely with go implementation, the industry's most popular container orchestration management system Kubernetes, completely with Go implementation, then the Docker Swarm, completely with go implementation. In addition, there are a variety of well-known projects such as Etcd/consul/flannel and so on, all using go implementation. Some people say that the go language is famous, is catching up with the cloud era, but why not a different way of saying, but also go language to promote the development of the cloud?

In addition to cloud projects, there are companies like today's headlines and Uber, who also use the go language to reinvent their business.

Go language Key Features

The go language is very strong, because it is in the development of the server, always grasp the pain point of the programmer, the most direct, simple, efficient, stable way to solve the problem. We will not delve into the specific syntax of the go language here, but will only introduce the key aspects of the language that are important for simplifying programming, following the footsteps of the Masters and experiencing Go's design philosophy.

The key features of the go language include the following:

    • Concurrency and co-processes
    • Communication mode based on message passing
    • Rich and useful built-in data types
    • function multiple return value
    • Defer mechanism
    • Reflection (reflect)
    • High-Performance HTTP Server
    • Engineering Management
    • Programming specifications

In today's multi-core era, the significance of concurrent programming is self-evident. Of course, many languages support multi-threaded, multi-process programming, but unfortunately, implementation and control is not so easy and enjoyable. Golang different is that language-level support for concurrent (goroutine) concurrency (which is called micro-threading, lighter than threads, less expensive, higher performance), is very simple to operate, language-level keyword (go) is used to start the process, and the same machine can start thousands of processes.

Comparing the multithreading of Java with the implementation of go, it is obviously more straightforward and simple. This is the charm of go, in a simple and efficient way to solve the problem, the keyword go, perhaps the most important sign of the go language.

Communication mode based on message passing

In asynchronous concurrent programming, it is not enough to start the process easily and quickly. The message communication between the processes is also very important, otherwise, the various processes will become runaway Mustang and uncontrollable. In the go language, the use of message-based communication (rather than shared-memory-based communication, which is used by most languages) is used for inter-process communication, and the message pipeline (channel) is defined using the Type keyword (chan) as the basic data type, and is thread-safe for concurrent operations. This is also revolutionary in the realization of language. It can be seen that the go language itself is not simply no bottom line, they will be the most practical, the most conducive to problem-solving ability, in the simplest, direct form to the user.

Channel is not only used for simple message communication, but also can be derived from a lot of very practical, and very convenient to implement the function. For example, TCP connection pooling, throttling, and so on, which are not easy to implement in other languages, but the go language can be easily done.

The go language, as a compiled language, supports a very comprehensive range of data types, in addition to the traditional integer, floating-point, character, array, structure and other types. In practical terms, it also provides native support for string types, slice types (variable-length arrays), dictionary types, complex types, error types, pipe types, and even any type (interface{}), and is very handy. For example, string, slice type, easy to operate almost like python.

Also, using the error type as the basic data type, and no longer supporting try...catch usage at the language level, should be considered a very bold and revolutionary feat, and no wonder many people spit out the go language. But out of the traditional concept, go developers believe that in the programming process, to ensure the robustness and stability of the program, the precise processing of the exception is very important, only after each logical processing is completed, explicitly inform the upper layer of the call, whether there is an exception, and by the upper call explicit, timely processing of the exception, In this way, the robustness and stability of the program can be ensured in a high degree. While doing so will result in a large number of judgments about error results during programming, this undoubtedly increases the developer's alertness to exception handling. The practice proves that it is hard to write code that is not robust, as long as you strictly follow the style code recommended by go. Of course, if you don't repel it, recognize it.

Python is one of the few things that support function return values in a language. Allows the function to return multiple values, which, in some scenarios, can effectively simplify programming. The recommended programming style for the go language is that the last parameter returned by the function is the error type (as long as an exception is possible in the logical body), so it is necessary to support multiple return values at the language level.

Defer delay processing mechanism

In the go language, a keyword, defer, can be used to specify a logical body that needs to be deferred execution, either before the function body return or when panic occurs. This mechanism is ideal for dealing with logic, such as early avoidance of potential resource leaks.

It can be said that defer is another very important and practical language feature after Goroutine and channel, the introduction of defer can greatly simplify the programming, and it is more natural in language description, which greatly enhances the readability of the code.

Golang, as a strong type of compiled language, is naturally less flexible than analytic language. For example, PHP, a weak type, and a string variable can be directly to the content of the new operation, and in the compiled language, this is obviously not possible. However, Golang provides the any type (interface{}) and powerful type reflection (reflect) capabilities, which, in combination, are already very close to the analytic language in the flexibility of development. In the dynamic invocation of logic, the implementation is still very simple. So, what is the advantage of an analytic language like PHP compared to go? Personally, I've been writing PHP for nearly 10 years, implementing a development framework, a base class library, and a variety of public components, although execution performance is inadequate, but it's more efficient to develop, and when confronted with Golang, these advantages seem less obvious.

As a service-side language appearing in the internet era, the ability to service users is essential. Go at the language level comes with HTTP/TCP/UDP high-performance server, based on concurrent concurrency, providing the most direct and effective ability support for business development. To implement a high-performance HTTP Server in the Go language, it can be done in just a few lines of code, which is very simple.

In the go language, there is a standard set of engineering management specifications, so long as the project is developed according to this specification, the following things (such as package management, compilation, etc.) will become very simple.

Under the Go project, there are two key directories, one is the SRC directory, which is used to store all the. Go source files; One is the bin directory, which is used for the compiled binaries. In the SRC directory, except for the directory where main main package is located, all other directory names correspond to the package names in the direct directory, otherwise the compilation cannot pass. In this way, the go compiler can start with the directory where the main package is located, fully use the directory structure and package name to derive the engineering structure and build order, avoiding the introduction of an additional makefile file like C + +.

In the Go compilation, the only thing we have to do is assign the Go project path to an environment variable called Gopath, and let the compiler know where the go project is going to be compiled. Then go to the Bin directory and execute the go build {The directory name where the main package is located} to complete the project compilation in seconds. The compiled binaries can be pushed to run directly on the same OS without any environmental dependencies.

The programming specifications of the go language are mandatory for integration in the language, such as explicitly laying out the curly braces, forcing a line of words, not allowing the import of unused packages, not allowing the definition of unused variables, providing GOFMT tools to force formatting, and so on. Strangely, these also caused a lot of programmers dissatisfaction, someone published The Go language xx, there is no lack of programming norms of blame. Be aware that from a project management perspective, any development team will develop specific programming specifications for specific languages, especially companies like Google. The designers of go think that rather than writing the specification in a document, it is better to force integration into the language, which is more straightforward and leverages team collaboration and engineering management.

API Rapid Development Framework Practice

A programming language is a tool that tells us what to do and how it can be better and worth exploring. This section describes a development framework implemented in the go language, along with several common components. Of course, frameworks and common components, and other languages can be fully implemented, and the focus here is on cost. In addition, aside from the go language itself does not say, we also hope that we can let everyone from the introduction of several components, to get some ideas to solve the problem, that is, in some way, to solve a problem on the face, rather than blindly write code, and ultimately just solve the problem on the point. If you recognize this approach, believe that the following content may affect the way you develop your project, radically improving your development efficiency.

Why we choose the Go language

Choosing the Go language is primarily based on two considerations

    1. Execution performance shortens the response time of the API and resolves the issue of batch request access timeouts. In the Uwork business scenario, one API batch request, often involves multiple calls to another interface service, and in the previous PHP implementation mode, it is very difficult to do parallel calls, but serial processing can not fundamentally improve processing performance. And the go language is not the same, through the process can be easily implemented API parallel processing, to maximize the processing efficiency. Rely on Golang's high-performance HTTP Server to improve system throughput, from PHP hundreds of to thousands of or even over the million level.
    2. Development efficiency The go language is simple to use, the code description is efficient, the coding standard is unified, and the start is fast. With a small amount of code, you can standardize the framework and quickly build API business logic with uniform specifications. Can quickly build a variety of common components and public class library, further improve the development efficiency, to achieve a specific scenario of functional mass production.

When many people learn a new language or start a new project, they are accustomed to finding an open source framework that they think is appropriate to start their own project development journey. There's nothing wrong with that, but personally, it's more helpful to know what's inside of it. As you may have noticed, the MVC framework is essentially parsing the request path, then routing it to the appropriate controller (C) based on the request path segment, and then further invoking the data logic (M) by the controller, and after getting the data, render the view (V) and return the user. Throughout the process, the core point lies in the dynamic invocation of logic.

However, the implementation of the API framework relative to the Web page framework is simpler because it does not involve the rendering of the view, only the data results are returned to the user in the form of a protocol.

Using the go language to implement a complete set of MVC development Framework is very easy, integration of HTTP server, the core code of the entire framework will not exceed 300 lines, from here can actually feel the language of the go to the high efficiency (if interested, can refer to Uwork Open source project Seine).

Others say that there is no framework in the go language, and the implication is that the introduction of a heavy-duty open-source framework is not very necessary, but rather complicated by simple things.

In the actual project development process, only the efficient development language is not enough, in order to further expand the development efficiency, the continuous precipitation of the public base library is necessary to further abstract and reuse the common basic logic.

In addition, the general component capability is the fundamental to achieve the function of mass production, the development efficiency will be a qualitative improvement. The modular development model helps us to elevate the problem resolution from one point to the other. The following will focus on the implementation of several common components, with their existence, in order to truly liberate the programmer's productivity. And these powerful public components are not complicated to implement in Golang. At the same time, combined with Golang's concurrent processing ability, the implementation efficiency will be improved in comparison with the PHP version implementation. This is the perfect combination of component competence and language efficiency.

The Universal list component is used for data query scenarios of all possible two-dimensional data sources (such as mysql/mongodb/es, etc.) and solves the problem of querying data from a single polygon. In the Uwork project development, is used extensively, realizes the data query interface and the page query list the mass production development. It centers on a JSON configuration file, implements queries against a common data source, and automatically returns the results of the query to the user as an API or a page. There is little code development throughout the process, and the only thing to do is to write a configuration file (rather than code) in a uniform specification that truly implements the functional mass production of the data query requirements.

The above is the General List component of the building process, to achieve such a powerful general purpose components, will it give people a sense of the impossible? In fact, it is not so, as long as the whole process of clearing it, will build ideas into the Golang, not a complex thing. In our project, the implementation of the entire component, only with less than 700 lines of Go code, solved a series of data query problems. In addition, the parallel execution of the field processor is realized by Golang concurrency, which further improves the efficiency of the component execution. It can be said that the integration of universal lists and Golang is the perfect combination of performance and efficiency.

The general form component is mainly used for adding, deleting and changing the database. This component is also widely used in the project development of Uwork, which is similar to the General list, and takes a JSON configuration file as the center to complete the increment, delete and change operation of data table data. In particular, the recently completed component-level SDB management platform, through the general form to achieve the entire system of data maintenance, through a high degree of abstraction, to achieve the business of the production of No code.

This is the complete build of a common form, and for this implementation of a component, we use a go code of less than 1000 lines, which solves the problem of maintaining the entire surface of the data table data.

The go language itself supports co-concurrency and is very lightweight, enabling you to quickly start thousands of concurrent work units. If the number of co-operation tasks is not properly controlled, the final result is likely to backfire, causing undue pressure on the external or its own services. The pool can control the number of execution units to a certain extent and ensure the security of execution. And in Golang to implement such a pool, is very simple, only need to the channel and goroutine a little encapsulation, you can complete, the entire construction process less than 80 lines of code.

In the process of API development, data validation is always an indispensable part. If it is just a simple data check, a few lines of code may be completed, but when encountering complex data validation, it is likely that hundreds of lines of code may not be able to complete, especially encountered recursive type of data validation, it is a nightmare.

Data validation component, through a data template configuration, the use of specific logic to complete the general validation, developers only need to configure the corresponding data template, make a simple call, can complete the entire verification process. For such a universal data validation component, the go language only uses less than 700 lines of code to complete the entire construction.

Summary

In the actual project development process, the development efficiency of the largest, is undoubtedly in line with the system business scenario of the public component capacity, this is also the right to testify to Rob Pike that sentence (less is lessor not more), the real efficient development, is configured, do not need to write too much code, Even do not need to write code, you can complete the logical implementation, and this way for the later maintenance cost is also optimal, because achieved a high degree of unity.

There is no doubt that the language description of Go has no more than 1000 lines of code for all of the public components mentioned above, which solves a problem on a face.

(Some of the above code is already available in Uwork Open source project Seine)

Performance evaluation

Pressure test Environment Description:

    • Service running machine: Single idle b6,24 core CPU, 64G memory.
    • PHP API Environment: NGINX+PHP-FPM,CI framework. Where Nginx initiates 10 sub-processes, each of which receives a maximum of 1024 connections, and PHP-FPM uses the static mode to start 2000 resident child processes.
    • Golang API Environment: Use go1.8.6 compilation to pull up the Golang API server process (Httpserver) without regard to tuning.
    • Customer initiated the Request test program: Use Golang write, co-process concurrency, run on a separate idle B6, 24 cores cpu,64g memory, in order to 1-2000 different levels (concurrent number step 50) of the concurrency on the request 20,000 times respectively.

Comparison of stress test results

In the Golang API framework, the processing of QPS fluctuates near 6.5w/s when the number of concurrent >50 occurs. Stable performance, no error during stress test.

NGINX+PHP-FPM, only the exit (' OK ') is output in index.php, and when the number of concurrent >50 is processed, the QPS fluctuates around the 1w/s. Stable performance, no error during stress test.

In the NGINX+PHP-FPM+CI framework, the logic executes to the specific business logic point, Output exit (' OK '), and when the concurrency number >50, the processing QPS fluctuates around the 750/s. And the performance is unstable, the error quantity increases with the increase of the number of concurrent numbers during the stress test.

The stress tests show that Golang and PHP are not comparable in performing performance, while the HTTP API framework implemented by Golang can be very satisfying when the single-machine performance QPS reaches 6.5w/s at no load.

Points to note in the development process

The following are some of the problems encountered in the actual development process, for reference only:

Exception handling Unified use error, do not use panic/recover to simulate Throw...catch, originally I did this, and later found that this is entirely self-thought is the practice.

Native error is too simple, and in the actual API development process, different exception conditions need to be accompanied by different return codes, based on this, it is necessary to a layer of error packaging.

Any of the process logic actuators, the logic must have defer recover () exception recovery processing at the beginning, otherwise the panic in Goroutine will cause the whole processing to go down and need to avoid the global impact of some logical bugs.

In Golang, the operation of variables (except Chan type) is non-thread-safe and includes basic types such as int, so it is important to consider locking, especially for map concurrency, when working with global variables concurrently.

All access to the map key value should be judged by the existence, preferably uniform encapsulation of similar operations, to avoid unnecessary run-time exceptions.

When defining the slice data type, try to preset the length to avoid unnecessary data reassembly inside.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.