跳转到主要内容

热门内容

今日:


总体:


最近浏览:


Chinese, Simplified

随着API领域的发展和转变,业界的有效语言已经发生了几个重大变化。从经典的服务器-客户机体系结构转向无服务器或其他新范例的领域可能会让旧语言感到不够用。开发人员必须对语言进行讨价还价,强迫它做您需要它做的事情,而不管它是否为此目的而设计。

为了解决这个问题,许多人开始开发专门针对给定解决方案的新语言。虽然对于给定的应用程序,这通常工作得很好,但这通常只是将问题进一步推进。其他人已经尝试通过开发仍然为特定类型的函数提供本地支持的近似通用语言来解决这个问题。这就是我们今天要讲的语言。

Ballerina是一种有趣的新编程语言,具有不可思议的潜力。话虽如此,什么是芭蕾舞演员,它为什么有价值?它试图解决什么问题?

芭蕾舞演员是什么?

Ballerina是由WSO2开发的一种开源语言。它是专门为替代基于配置的解决方案而设计的,以解决语言困难的初始问题。它是一种编译语言,主要关注微服务开发和集成,大多数营销材料都努力指出,Ballerina是“云原生的”。

为了更好地理解《芭蕾舞女》,我们首先要看《芭蕾舞女》为其发展所做的辩护。

理由和动机

Ballerina的开发人员将世界视为一个不断缩小的系统,其中的内容正从经典的基于服务器的体系结构转移到无服务器、微服务和服务网格。换句话说,运行我们代码的世界已经发生了根本的变化,以前的方法——以及因此为这些方法开发的语言——并不完全合适。

代码已经从底层系统中抽象出来,这需要一种不同的风格。从根本上说,这意味着我们交付软件和代码的方式不再属于“中间件”的范围。实际上,在一个芭蕾舞演员的演示中,有这样一句话:“中间件已经死了,因为中间件无处不在”。从本质上说,当中间件被嵌入到我们使用的所有东西中时,就不存在中间件。应用程序服务器不再是一个东西,每个应用程序都是使用独立的代码位来调用的,这些代码是整体解决方案的一部分

这种思维上的转变需要一种新的语言,这种语言基于将所有需要的东西打包成一种单一语言的想法。这种想法依赖于代码和目的的结合,而不是通常是前面提到的语言困难的根本原因的进一步抽象。

设计原则

一个核心的设计原则是利用序列图的概念。序列图经常被用来建模问题、描述复杂的系统和设计api。但是,它们通常与代码本身是分开的。Ballerina的设计师想要解决这个问题,他们的想法是序列图可以由代码组成,反之亦然,而不是先画一个图,然后对实际的编码序列做一些非常不同的事情。

这种方法的一个主要方面是,驱动图表的文本和图形语法应该具有完全的对等性。换句话说,它不仅仅是一张图片、一个模型或一个图表,而是一种理解、定义和生成内容的实际的、有效的方法。

另一个核心原则是网络不应该被隐藏。在许多语言中,网络抽象层通常埋在一个库中,很少直接使用。在《芭蕾舞女》中,这种关系是颠倒的,网络本身被视为解决代码问题的主要方法。网络数据类型包含在语言中以提供弹性,而网络故障被设计为伴随难以置信的冗长和信息丰富的错误代码、解释和评估,以帮助指导修复。

网络数据类型非常明显,这使得网络成为Ballerina的一个重要方面。

当然,许多这样的网络错误在芭蕾舞女一开始就不会发生。在宣传材料中,《芭蕾舞女》和它的编者被称为“非常固执己见”。如果代码库中存在错误,通常情况下,Ballerina甚至不允许渲染和包含它。就其本质而言,这将带来更大的安全性,因为在糟糕的代码和糟糕代码的实现之间存在着巨大的障碍。

也许Ballerina最主要的原则就是它不是一个研究项目,不是一种测试语言,也不是某种未来主义的、半建成的语言。Ballerina的开发人员看到了许多主流概念,它们有很大的价值,但作为独立的元素和库,它们的作用较弱。因此,通过将这些抽象结合到一个单一的解决方案中,促进有效的部分,去除无效的部分,Ballerina被设计成一个已知成功元素集合的总结,而不是一个全新的东西。

独特的芭蕾舞元素

《芭蕾舞女演员》有很多独特的特点,或者至少是结合在一起的新颖之处。首先,它们对结构化类型系统的支持,特别是它们关注于提供强大的网络友好类型和联合系统,这是一个相当广泛的特性集,包括在一种似乎更有限的、固执己见的语言中。这允许Ballerina严格执行其特定的类型,同时仍然允许广泛的变革性数据类型。

作为其中的一部分,在芭蕾舞女演员身上有各种各样的支持价值。大致可分为三大类:

  • 简单值——这些值包括布尔值、int值、float值、decimal值和string值,是我们所期望的基本语言。
  • 结构化值——这种类型的数据包括元组、数组、映射、记录、表、功能强大(但已简化)的XML系统和错误代码报告。这允许更健壮地管理内部数据类型,并将该语言扩展到一些不简单的东西。
  • 行为值——这种类型的值包括函数、未来、对象、流和typedesc,并进一步扩展了Ballerina的能力和最终的可扩展性。

可扩展性当然也是其中的一个重要部分。Ballerina支持所谓的环境绑定。从本质上说,这是一种方法,开发人员可以根据适当功能所需的内容强制或推荐环境结构和设置。当然,这是一个限制性的步骤,但是能够确定使用代码的确切环境是设计连续性和功能质量保证方面的一大进步。

支持这种可扩展性的事实是,Ballerina在语言本身中加入了大量的中间件。通过将库和代码片段编译为一个单独的解决方案,我们得到了一个强大而复杂的系统,它不显式地需要外部库来完成更复杂的功能。

错误处理也是Ballerina的一大关注点。在编译坏代码的过程中,语言经常会抛出无用的错误。Ballerina的设计理念是,代码和网络上的错误都是常见的事情,因此应该作为数据类型处理并详细解释。编译器会直接拒绝编译带有错误的代码(除非在可能出现错误的例外情况下,比如外部连接失败),如果生成了错误,那么文档、代码和解释将是完整且有帮助的。

就实际使用Ballerina而言,强大的错误处理平台、输入系统、集成查询和流查询选项都非常出色。能够对静态元素和流元素进行类似sql的查询是非常强大的,并提供了广泛的可能性。

也许这里最独特和最增值的原则是事件驱动运行时的思想。芭蕾舞女被设计为无阻塞。在其他语言中,队列调用有一个需要释放的保留资源,与之不同的是,Ballerina从头开始构建,不锁住资源,也不阻塞其他查询。他们甚至为阻塞元素设计了一个池系统来解决这个问题,确保即使是阻塞的系统也呈现为非阻塞的。

从本质上说,Ballerina运行时中的所有东西都提供了高性能,但没有为此付出编码成本。许多其他语言(宣传材料指出Node.js就是一个主要的例子)可以在高复杂度的情况下提供高性能,但是Ballerina寻求在没有复杂性和没有大量代码实现的情况下提供高性能。

最后,Ballerina支持他们所谓的“永远平行”。简单地说,一个可执行实体可以有任意数量的worker分配给该实体,并且这些worker在一个非阻塞的并行系统中工作。服务形成了一个资源集合,其中每个资源都使用一个ingress端点调用,这个端点绑定到一个令人难以置信的并行系统,该系统允许并发工作和并行处理。这本身就是对效率的一大提升,也是一个主要的卖点。

芭蕾舞女演员长什么样?

说了这么多,芭蕾舞女演员到底长什么样?让我们看一下来自Ballerina文档的一个示例。这个示例将生成一个负载均衡器,它将在几个目标端点上平衡请求负载。

首先,我们需要为模拟后端服务创建一个绑定到8080的端点。我们可以使用下面的代码片段来做到这一点:

import ballerina/http;

import ballerina/log;

listener http:Listener backendEP = new(8080);

接下来,我们需要定义调用后端服务的负载平衡客户端端点,以及定义要平衡的HTTP客户端集。

http:LoadBalanceClient lbBackendEP = new({

        targets: [

            { url: "http://localhost:8080/mock1" },

            { url: "http://localhost:8080/mock2" },

            { url: "http://localhost:8080/mock3" }

        ],

        timeoutMillis: 5000

});

在本例中,我们有三个正在进行负载平衡的服务,其特定的毫秒超时值为5000ms。现在我们需要创建绑定到端点的HTTP服务,并在API中创建REST资源

@http:ServiceConfig {

    basePath: "/lb"

}

service loadBalancerDemoService on new http:Listener (9090) {

    @http:ResourceConfig {

        path: "/"

    }

接下来,我们需要包括调用端点引用,以及请求数据对象:

@http:ResourceConfig {

        path: "/"

    }

    resource function roundRobin(http:Caller caller, http:Request req) {

        json requestPayload = { "name": "Ballerina" };

        var response = lbBackendEP->post("/", requestPayload);

这个部分是主要的错误处理逻辑路由器-如果一个有效的响应被返回,正常的进程将运行,但如果一个非预期的响应被产生,这个逻辑被触发:

        if (response is http:Response) {

            var responseToCaller = caller->respond(response);

            if (responseToCaller is error) {

                log:printError("Error sending response",

                                err = responseToCaller);

            }

        } else {

            http:Response outResponse = new;

            outResponse.statusCode = 500;

            outResponse.setPayload(response.detail().message);

            var responseToCaller = caller->respond(outResponse);

            if (responseToCaller is error) {

                log:printError("Error sending response", err = responseToCaller);

            }

        }

    }

}

最后,我们需要定义将被负载均衡器调用的后端服务:

@http:ServiceConfig {

    basePath: "/mock1"

}

service mock1 on backendEP {

    @http:ResourceConfig {

        path: "/"

    }

    resource function mock1Resource(http:Caller caller, http:Request req) {

        var responseToCaller = caller->respond("Mock1 resource was invoked.");

        if (responseToCaller is error) {

            log:printError("Error sending response from mock service", err = responseToCaller);

        }

    }

}

@http:ServiceConfig {

    basePath: "/mock2"

}

service mock2 on backendEP {

    @http:ResourceConfig {

        path: "/"

    }

    resource function mock2Resource(http:Caller caller, http:Request req) {

        var responseToCaller = caller->respond("Mock2 resource was invoked.");

        if (responseToCaller is error) {

            log:printError("Error sending response from mock service", err = responseToCaller);

        }

    }

}

@http:ServiceConfig {

    basePath: "/mock3"

}

service mock3 on backendEP {

    @http:ResourceConfig {

        path: "/"

    }

    resource function mock3Resource(http:Caller caller, http:Request req) {

        var responseToCaller = caller->respond("Mock3 resource was invoked.");

        if (responseToCaller is error) {

            log:printError("Error sending response from mock service", err = responseToCaller);

        }

    }

}

现在我们有了一个功能完整、高效的负载平衡解决方案。这与始终开启的并行解决方案结合起来,将提供一个高吞吐量、良好平衡的响应系统。

结论

芭蕾舞女解决了一个非常具体的问题,而且做得很好。话虽如此,当许多库和可扩展解决方案支持相同的功能时,要求开发人员转换到一种全新的语言是一项相当沉重的任务。但是,假设您从头开始,Ballerina可以是一个强大的工具,用于交付更高效、更有效的语言驱动的解决方案。

你觉得芭蕾舞女演员怎么样?你认为它兑现了它的承诺吗?或者你认为它被过度炒作了?在下面的评论区告诉我们吧!

原文:https://nordicapis.com/review-of-ballerina-a-programming-language-for-microservices-and-apis/

本文:http://jiagoushi.pro/node/1374

讨论:请加入知识星球【快速和低代码开发】或者小号【it_training】或者QQ群【11107767】

最后修改
星期四, 一月 5, 2023 - 21:56
Tags
 
Article