Go 为什么是云原生的本命语言
===============
一.简单易上手
=======
Go 的语法关键字相较于其他语言来说更少,学习难度低,更容易上手。
Go的保留关键字只有25个:
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
这就让上手的人可以更加关注代码如何去编写的更优雅,而不是更多的去关注语法糖和写出更骚更短的代码。
Go 的设计是为了弥补 C++ 的缺陷,消除各种缓慢和笨重、改进各种低效和扩展性,让我们的编程变得更舒适和方便。所以它本身就具有:编译时间短,运行效率高;稳定性强,拥有强大的编译检查和完整的软件生命周期工具等优点。
二.并发编程的优势
我们先看一下不同语言的并发编程的例子:
1.python
import threading
import time
# 定义一个简单的线程函数
def thread_function(name):
print("Thread {} started".format(name))
time.sleep(2)
print("Thread {} ended".format(name))
# 创建两个线程并启动
thread1 = threading.Thread(target=thread_function, args=(1,))
thread2 = threading.Thread(target=thread_function, args=(2,))
thread1.start()
thread2.start()
# 主线程等待子线程结束
thread1.join()
thread2.join()
print("Main thread ended")
2.Java
public class Main {
// 定义一个简单的线程类
static class MyThread extends Thread {
private int id;
public MyThread(int id) {
this.id = id;
}
@Override
public void run() {
System.out.println("Thread " + id + " started");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread " + id + " ended");
}
}
public static void main(String[] args) throws InterruptedException {
// 创建两个线程并启动
MyThread thread1 = new MyThread(1);
MyThread thread2 = new MyThread(2);
thread1.start();
thread2.start();
// 主线程等待子线程结束
thread1.join();
thread2.join();
System.out.println("Main thread ended");
}
}
3.C++
#include <iostream>
#include <thread>
#include <chrono>
// 定义一个简单的线程函数
void thread_function(int id) {
std::cout << "Thread " << id << " started" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "Thread " << id << " ended" << std::endl;
}
int main() {
// 创建两个线程并启动
std::thread thread1(thread_function, 1);
std::thread thread2(thread_function, 2);
// 主线程等待子线程结束
thread1.join();
thread2.join();
std::cout << "Main thread ended" << std::endl;
return 0;
}
与Go对比起来,其他语言的并发编码都过于复杂,复杂就代表着编程的时候使用会容易出错。
Go 启动一个协程只需要通过 go
关键字就可以直接启动,并且不同协程之间的信号传递可以通过 chan
来实现,写起来简单容易理解,自然就不容易出错。
比如我们可以通过 channel 来进行数据的共享,并且可以用 context.Done
的信号来控制所有进程是否退出。
func watch(ctx context.Context, event chan string){
for {
select {
case <-ctx.Done():
return
case <-event:
// do something
}
}
}
或者是需要通过定时器来定时维护状态
func watch(ctx context.Context){
ticker := time.NewTicker(time.Second * 10)
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
// do something
}
}
}
而且在云原生的场景下,大量的处理都是需要并发进行,比如在拆分大量微服务的情况下,我们需要并发去获取不同服务的结果处理,如果是串行,那在需要快速响应的情况下是难以接受的,并发编程就变得尤为重要。
三.注重可维护性
当成千上万的开发人员在数年的持续开发,在包含数千万行代码的大型代码库上,会发生真正令人痛苦的问题。
随着程序越来越大,程序的编译时间逐渐变长导致开发速度受到影响,所以构建的速度成为 Go 的一大优势。
代码库由许多人进行维护,混合了很多不同的编程风格。
在代码库的生命周期中,代码会一直被打补丁,最后被弄得千疮百痍,而且还会发生技术偏差,最终因为代码的频繁改动,文档未能及时跟上,导致了文档不完善。
Go 也在这方面做了努力,比如 if-else 它就只允许了一种编写的代码风格,而不是让程序员去争论是否应该换行。
并且提供了 format
代码的工具,让不同人写出来的 Go 代码的风格都尽量的保持一致,开发者只需要去理解业务逻辑即可。
四.Kubernetes 的助力
云原生最重要的容器编排应用 Kubernetes 选择了使用 Go 进行编写,这也让学习云原生的人绕不开了要去学习 Go,既然学 Go 的人变多了,自然为它建设工具链的人也会相应变多。
比如在微服务的框架中,go-zero 让启动一个新的微服务变的十分简单,也提供了服务注册发现、熔断、日志追踪 等功能,让更多的人能够去用 Go 来开发。
五.微服务的广泛应用
由于互联网用户量的激增,架构从单体转向分布式微服务,每个微服务之间通过通信协议交互数据,并不太在意单个服务本身使用什么语言进行实现,这也为 Go 在云原生的广泛普及奠定了基础。
它不需要关心之前的服务有多复杂,也不需要用Go语言重新重构原来的整个稳定运行的服务,只需要在新增功能的时候,在新的服务中提供出API即可,别人并不关心内部的服务是用什么语言进行实现,这也给了 Go 生长的合适土壤。
Java虽然在企业级开发里面统一了位置,但是也由于微服务大部分不需要如此复杂和繁重的架构,让go能够占据一席之地。
python在机器学习和算法实现的简便性上无可替代,但是也由于弱类型的特性,让它在做企业级应用上并不适合多人协作,且协程编程这一块过于复杂,导致难以胜任这种需要大量并发编程的场景。
微服务也不是一门语言说完的,而是由很多技术栈构成的,每个语言都有自己擅长的领域,用契合的技术实现自己的想法才是关键。
感谢你读到这里,如果想要看更多 云原生及Kubernetes 的文章可以订阅我的专栏: juejin.cn/column/7321… 。
原文链接: https://juejin.cn/post/7365903656166653962
文章收集整理于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除,如若转载,请注明出处:http://www.cxyroad.com/17330.html