云原生编程本质上涉及使用远程端点:微服务,无服务器,API,WebSocket,软件即服务(SaaS)应用程序等。 Ballerina是一种云原生,通用,并发,事务性,静态和强类型的编程语言,具有文本和图形语法。
它的专长是集成。 它将基本概念,思想和分布式系统集成的工具引入了该语言,并提供了一种类型安全的并发环境来实现此类应用程序。 这些包括分布式事务,弹性,并发性,安全性和容器管理平台。
Apache 2.0许可证,您可以在项目的GitHub存储库中找到其源代码。文字和图形语法
Ballerina的编程语言语义被创建为开发人员能够自然地表达程序的结构和逻辑。 为了描述多方之间的复杂交互,我们通常使用顺序图。 这种方法能够以直观的方式可视化端点和动作,例如异步和同步消息传递以及并行执行。
![芭蕾舞演员代码 Ballerina code](https://i-blog.csdnimg.cn/blog_migrate/793c48ec5aea92c16df9d14525f8ba92.png)
Ballerina代码的文字和图形表示。
内置弹性
该语言内置了弹性和类型安全的集成。 当您尝试调用可能不可靠的外部端点时,可以通过特定协议的弹性功能(例如断路器,故障转移和重试)来避免这种交互。
断路器
添加断路器与将一些其他参数传递给客户端端点代码一样简单。
endpoint http:Client backendClientEP {
url: "http://localhost:8080",
// Circuit breaker configuration options
circuitBreaker: {
// Failure calculation window.
rollingWindow: {
// Time period in milliseconds for which the failure threshold
// is calculated.
timeWindowMillis: 10000,
// The granularity at which the time window slides.
// This is measured in milliseconds.
bucketSizeMillis: 2000
},
// The threshold for request failures.
// When this threshold exceeds, the circuit trips.
// This is the ratio between failures and total requests.
failureThreshold: 0.2,
// The time period(in milliseconds) to wait before
// attempting to make another request to the upstream service.
resetTimeMillis: 10000,
// HTTP response status codes which are considered as failures
statusCodes: [400, 404, 500]
},
timeoutMillis: 2000
};
故障转移
您可以使用超时间隔和故障转移代码定义需要进行故障转移的客户端端点。
// Define the failover client endpoint to call the backend services.
endpoint http:FailoverClient foBackendEP {
timeoutMillis: 5000,
failoverCodes: [501, 502, 503],
intervalMillis: 5000,
// Define set of HTTP Clients that needs to be Failover.
targets: [
{ url: "http://localhost:3000/mock1" },
{ url: "http://localhost:8080/echo" },
{ url: "http://localhost:8080/mock" }
]
};
重试
您可以使用端点定义重试间隔,重试次数和退避因素的端点重试配置。
endpoint http:Client backendClientEP {
url: "http://localhost:8080",
// Retry configuration options.
retryConfig: {
interval: 3000,
count: 3,
backOffFactor: 0.5
},
timeoutMillis: 2000
};
异步和并行执行
Ballerina的执行模型由称为工作程序的并行执行单元组成。 一个工人代表了Ballerina的基本执行结构。 在Ballerina中,每个功能由一个或多个工作程序组成,这些工作程序是独立的并行执行代码块。 如果在工作程序块中未提及显式工作程序,则功能代码将属于单个隐式默认工作程序。
![Ballerina中的并行执行代码 Parallel execution code in Ballerina](https://i-blog.csdnimg.cn/blog_migrate/0bbf4c5958a3cf72812ecb684122c041.png)
文本和图形表示形式的并行执行代码。
Ballerina还为fork-join提供了本机支持,这是工作人员交互的特例。 使用fork-join,您可以分叉逻辑并将执行分担给多个工作程序,并有条件地将所有工作程序的结果加入join子句中。
fork {
worker w1 {
int i = 23;
string s = "Foo";
io:println("[w1] i: ", i, " s: ", s);
(i, s) -> fork;
}
worker w2 {
float f = 10.344;
io:println("[w2] f: ", f);
f -> fork;
}
} join (all) (map results) {
int iW1;
}
Ballerina还支持函数或端点的异步调用。 尽管大多数同步调用的外部端点是在Ballerina中以完全非阻塞的方式实现的,但是在某些情况下,您必须异步调用端点或函数,然后再检查结果。
future<http:Response | error> f1
= start nasdaqServiceEP
-> get("/nasdaq/quote/GOOG");
io:println(" >> Invocation completed!"
+ " Proceed without blocking for a response.");
// ‘await` blocks until the previously started async
// function returns.
var response = await f1;
交易处理
Ballerina在处理事务时具有语言级别的构造,您可以在其中使用连接器进行本地事务,并使用与X / A兼容的连接器进行分布式事务,甚至可以在语言运行时中使用内置的协调支持来进行服务级别的事务。
在Ballerina中,以事务方式执行一组操作只是将所有操作包装在“事务”块中的问题。
transaction {
_ = testDB->update("INSERT INTO CUSTOMER(ID,NAME) VALUES (1, 'Anne')");
_ = testDB->update("INSERT INTO SALARY (ID, MON_SALARY) VALUES (1, 2500)");
}
设计安全
Ballerina旨在确保使用Ballerina编写的程序具有固有的安全性。 Ballerina程序可以抵抗主要的安全漏洞,包括SQL注入,路径操作,文件操作,未经授权的文件访问和未经验证的重定向(开放重定向)。 这是通过污点分析机制实现的,其中,Ballerina编译器通过观察污点数据如何在程序中传播来识别不受信任(污点)的数据。 如果将不受信任的数据传递给安全敏感的参数,则会生成编译器错误。
@sensitive
批注可与用户定义函数的参数一起使用。 这允许用户限制将污染的数据传递到安全敏感的参数中。
function userDefinedSecureOperation(@sensitive string secureParameter) {
}
例如,Ballerina的污点检查机制通过禁止SQL查询中的污点数据来完全防止SQL注入漏洞。 由于查询附加了用户提供的参数,因此以下情况导致编译器错误。
function main(string... args) {
table dataTable = check customerDBEP->
select("SELECT firstname FROM student WHERE registration_id = " +
args[0], null);
由于将用户提供的参数传递给敏感参数,因此以下情况会导致编译器错误。
userDefinedSecureOperation(args[0]);
执行必要的验证和/或转义后,可以使用untaint
一元表达式将进行中的值标记为受信任的值,并将其传递给敏感参数。
userDefinedSecureOperation(untaint args[0]);
对Docker和Kubernetes的本地支持
Ballerina了解周围的建筑; 该编译器具有环境意识,可通过自动生成Docker映像和YAML将微服务直接部署到Docker和Kubernetes等基础架构中。 为了说明,让我们看一下示例hello_world.bal
代码。
import ballerina/http;
import ballerinax/kubernetes;
@kubernetes:Service {
serviceType: "NodePort",
name: "hello-world"
}
endpoint http:Listener listener {
port: 9090
};
@kubernetes:Deployment {
image: "lakwarus/helloworld",
name: "hello-world"
}
@http:ServiceConfig {
basePath:"/"
}
service<http:Service> helloWorld bind listener {
@http:ResourceConfig {
path: "/"
}
sayHello(endpoint outboundEP, http:Request request) {
http:Response response = new;
response.setTextPayload("Hello World! \n");
_ = outboundEP->respond(response);
}
}
@kubernetes:Service annotation
定义了如何通过Kubernetes服务公开服务。 @kubernetes:Deployment
通过捆绑应用程序代码创建对应的Docker映像,并使用define-deployment配置生成Kubernetes部署YAML。
编译hello_world.bal
文件将生成所有Kubernetes部署工件,Dockerfile和Docker映像。
$
> ballerina build hello_world.bal
@ kubernetes:Docker -
complete
3
/
3
@ kubernetes:Deployment -
complete
1
/
1
@ kubernetes:Service -
complete
1
/
1
Run following
command to deploy kubernetes artifacts:
kubectl apply
-f .
/ kubernetes
/
$
>
tree
.
├── hello_world.bal
├── hello_world.balx
└── kubernetes
├── docker
│ └── Dockerfile
├── hello_world_svc.yaml
└── hello_world_deployment.yaml
kubectl apply -f ./kubernetes/
会将应用程序部署到Kubernetes中,并且可以通过Kubernetes NodePort访问。
$
> kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT
( S
) AGE
hello-world NodePort 10.96.118.214
< none
>
9090 :
32045
/ TCP 1m
$
> curl http:
// localhost:
<
32045
>/
Hello, World
!
Ballerina中央
Ballerina通过其全球中央存储库Ballerina Central促进软件包的重用和共享。 在那里,您可以使用推拉式版本化程序包将端点连接器,自定义注释和代码功能共享为可共享程序包。
学到更多
随着微服务架构的出现,软件行业正在朝着原生云的应用程序开发方向发展。 像Ballerina这样的云原生编程语言将是快速创新的基本要素。
该项目网站的“ 学习Ballerina”部分提供了有关更多了解Ballerina的资源。 此外,请考虑参加2018年7月18日在旧金山举行的全球芭蕾舞剧《Ballerina》 。 这个全日活动将提供有关微服务开发,弹性,集成,Docker和Kubernetes部署,服务网格,无服务器,无测试驱动的微服务开发,生命周期管理,可观察性和安全性的最佳实践的深入培训。 订购门票时,使用优惠券代码BalCon -OpenSource可使 OpenSource.com的读者免费参加。
翻译自: https://opensource.com/article/18/7/ballerina-reinvents-cloud-native-programming