主要包含断路器模式,负载均衡模式,故障转移,重试

Circuit Breaker

  • 参考代码
import ballerina/http;
import ballerina/log;
import ballerina/runtime;
endpoint http:Client backendClientEP {
url: "http://localhost:8080",
circuitBreaker: {
rollingWindow: {
timeWindowMillis: 10000,
bucketSizeMillis: 2000
},
failureThreshold: 0.2,
resetTimeMillis: 10000,
statusCodes: [400, 404, 500]
}, timeoutMillis: 2000
};
@http:ServiceConfig {
basePath: "/cb"
}
service<http:Service> circuitbreaker bind { port: 9090 } {
@http:ResourceConfig {
methods: ["GET"],
path: "/"
}
invokeEndpoint(endpoint caller, http:Request request) {
var backendRes = backendClientEP->forward("/hello", request);
match backendRes { http:Response res => {
caller->respond(res) but {
error e => log:printError("Error sending response", err = e)
};
}
error responseError => {
http:Response response = new;
response.statusCode = 500;
response.setPayload(responseError.message);
caller->respond(response) but {
error e => log:printError("Error sending response", err = e)
};
}
}
}
}
public int counter = 1;
@http:ServiceConfig { basePath: "/hello" }
service<http:Service> helloWorld bind { port: 8080 } {
@http:ResourceConfig {
methods: ["GET"],
path: "/"
}
sayHello(endpoint caller, http:Request req) {
if (counter % 5 == 0) {
runtime:sleep(5000); counter = counter + 1;
http:Response res = new;
res.setPayload("Hello World!!!");
caller->respond(res) but {
error e => log:printError(
"Error sending response from mock service", err = e)
};
} else if (counter % 5 == 3) {
counter = counter + 1;
http:Response res = new;
res.statusCode = 500;
res.setPayload(
"Internal error occurred while processing the request.");
caller->respond(res) but {
error e => log:printError(
"Error sending response from mock service", err = e)
};
} else {
counter = counter + 1;
http:Response res = new;
res.setPayload("Hello World!!!");
caller->respond(res) but {
error e => log:printError(
"Error sending response from mock service", err = e)
};
}
}
}

Load Balancing(http)

  • 参考代码
import ballerina/http;
import ballerina/log;
endpoint http:Listener backendEP {
port: 8080
};
endpoint http:LoadBalanceClient lbBackendEP {
targets: [
{ url: "http://localhost:8080/mock1" },
{ url: "http://localhost:8080/mock2" },
{ url: "http://localhost:8080/mock3" }
],
algorithm: http:ROUND_ROBIN,
timeoutMillis: 5000
};
@http:ServiceConfig {
basePath: "/lb"
}
service<http:Service> loadBalancerDemoService bind { port: 9090 } {
@http:ResourceConfig {
path: "/"
}
invokeEndpoint(endpoint caller, http:Request req) {
http:Request outRequest = new;
json requestPayload = { "name": "Ballerina" };
outRequest.setPayload(requestPayload);
var response = lbBackendEP->post("/", request = outRequest);
match response {
http:Response resp => {
caller->respond(resp) but {
error e => log:printError("Error sending response", err = e)
};
}
error responseError => {
http:Response outResponse = new;
outResponse.statusCode = 500;
outResponse.setPayload(responseError.message);
caller->respond(outResponse) but {
error e => log:printError("Error sending response", err = e)
};
}
}
}
}
@http:ServiceConfig { basePath: "/mock1" }
service mock1 bind backendEP {
@http:ResourceConfig {
path: "/"
}
mock1Resource(endpoint caller, http:Request req) {
http:Response outResponse = new;
outResponse.setPayload("Mock1 Resource is invoked.");
caller->respond(outResponse) but {
error e => log:printError(
"Error sending response from mock service", err = e)
};
}
}@http:ServiceConfig { basePath: "/mock2" }
service mock2 bind backendEP {
@http:ResourceConfig {
path: "/"
}
mock2Resource(endpoint caller, http:Request req) {
http:Response outResponse = new;
outResponse.setPayload("Mock2 Resource is Invoked.");
caller->respond(outResponse) but {
error e => log:printError(
"Error sending response from mock service", err = e)
};
}
}@http:ServiceConfig { basePath: "/mock3" }
service mock3 bind backendEP {
@http:ResourceConfig {
path: "/"
}
mock3Resource(endpoint caller, http:Request req) {
http:Response outResponse = new;
outResponse.setPayload("Mock3 Resource is Invoked.");
caller->respond(outResponse) but {
error e => log:printError(
"Error sending response from mock service", err = e)
};
}
}

Failover

  • 参考代码
import ballerina/http;
import ballerina/log;
import ballerina/runtime;
endpoint http:Listener backendEP {
port: 8080
};
endpoint http:FailoverClient foBackendEP {
timeoutMillis: 5000,
failoverCodes: [501, 502, 503],
intervalMillis: 5000,
targets: [
{ url: "http://localhost:3000/mock1" },
{ url: "http://localhost:8080/echo" },
{ url: "http://localhost:8080/mock" }
]};
@http:ServiceConfig {
basePath: "/fo"
}
service<http:Service> failoverDemoService bind { port: 9090 } {
@http:ResourceConfig {
methods: ["GET", "POST"],
path: "/"
}
invokeEndpoint(endpoint caller, http:Request request) {
var backendRes = foBackendEP->get("/", request = request);
match backendRes {
http:Response response => {
caller->respond(response) but {
error e => log:printError("Error sending response", err = e)
};
}
error responseError => {
http:Response response = new;
response.statusCode = 500;
response.setPayload(responseError.message);
caller->respond(response) but {
error e => log:printError("Error sending response", err = e)
};
}
}
}
}
@http:ServiceConfig {
basePath: "/echo"
}
service echo bind backendEP {
@http:ResourceConfig {
methods: ["POST", "PUT", "GET"],
path: "/"
}
echoResource(endpoint caller, http:Request req) {
http:Response outResponse = new;
runtime:sleep(30000); outResponse.setPayload("echo Resource is invoked");
caller->respond(outResponse) but {
error e => log:printError(
"Error sending response from mock service", err = e)
};
}
}
@http:ServiceConfig {
basePath: "/mock"
}
service mock bind backendEP {
@http:ResourceConfig {
methods: ["POST", "PUT", "GET"],
path: "/"
}
mockResource(endpoint caller, http:Request req) {
http:Response outResponse = new;
outResponse.setPayload("Mock Resource is Invoked.");
caller->respond(outResponse) but {
error e => log:printError(
"Error sending response from mock service", err = e)
};
}
}

Retry

  • 参考代码
import ballerina/http;
import ballerina/log;
import ballerina/runtime;
endpoint http:Client backendClientEP {
url: "http://localhost:8080",
retryConfig: {
interval: 3000,
count: 3,
backOffFactor: 0.5
}, timeoutMillis: 2000
};@http:ServiceConfig {
basePath: "/retry"
}
service<http:Service> retryDemoService bind { port: 9090 } {
@http:ResourceConfig {
methods: ["GET"],
path: "/"
}
invokeEndpoint(endpoint caller, http:Request request) {
var backendResponse = backendClientEP->get("/hello", request = request);
match backendResponse { http:Response response => {
caller->respond(response) but {
error e => log:printError("Error sending response", err = e)
}; }
error responseError => {
http:Response errorResponse = new;
errorResponse.statusCode = 500;
errorResponse.setPayload(responseError.message); caller->respond(errorResponse) but {
error e => log:printError("Error sending response", err = e)
};
}
}
}
}public int counter = 0;@http:ServiceConfig { basePath: "/hello" }
service<http:Service> mockHelloService bind { port: 8080 } {
@http:ResourceConfig {
methods: ["GET"],
path: "/"
}
sayHello(endpoint caller, http:Request req) {
counter = counter + 1;
if (counter % 4 != 0) {
log:printInfo(
"Request received from the client to delayed service.");
runtime:sleep(5000); http:Response res = new;
res.setPayload("Hello World!!!");
caller->respond(res) but {
error e => log:printError(
"Error sending response from mock service", err = e)
};
} else {
log:printInfo(
"Request received from the client to healthy service.");
http:Response res = new;
res.setPayload("Hello World!!!");
caller->respond(res) but {
error e => log:printError(
"Error sending response from mock service", err = e) };
}
}
}

参考资料

https://ballerina.io/learn/by-example/http-failover.html
https://ballerina.io/learn/by-example/http-circuit-breaker.html
https://ballerina.io/learn/by-example/http-load-balancer.html
https://ballerina.io/learn/by-example/http-retry.html

 
 
 
 

ballerina 学习二十二 弹性服务的更多相关文章

  1. ballerina 学习 三十二 编写安全的程序

      ballerina编译器已经集成了部分安全检测,在编译时可以帮助我们生成错误提示,同时ballerina 标准库 已经对于常见漏洞高发的地方做了很好的处理,当我们编写了有安全隐患的代码,编译器就已 ...

  2. WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?

    原文:WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的? 服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户 ...

  3. python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字

    python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字在字符串里面插入指定分割符的方法,先把字符串变成list然后用join方法变成字符串str=' ...

  4. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  5. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  6. Tensorflow深度学习之十二:基础图像处理之二

    Tensorflow深度学习之十二:基础图像处理之二 from:https://blog.csdn.net/davincil/article/details/76598474   首先放出原始图像: ...

  7. 学习笔记:CentOS7学习之二十二: 结构化命令case和for、while循环

    目录 学习笔记:CentOS7学习之二十二: 结构化命令case和for.while循环 22.1 流程控制语句:case 22.2 循环语句 22.1.2 for-do-done 22.3 whil ...

  8. (C/C++学习笔记) 二十二. 标准模板库

    二十二. 标准模板库 ● STL基本介绍 标准模板库(STL, standard template library): C++提供的大量的函数模板(通用算法)和类模板. ※ 为什么我们一般不需要自己写 ...

  9. VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池

    VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ...

  10. Bootstrap <基础二十二>超大屏幕(Jumbotron)

    Bootstrap 支持的另一个特性,超大屏幕(Jumbotron).顾名思义该组件可以增加标题的大小,并为登陆页面内容添加更多的外边距(margin).使用超大屏幕(Jumbotron)的步骤如下: ...

随机推荐

  1. Flask添加翻页功能(非sqlalchemy)

    最近做flask的项目,需要增加翻页的功能,网上找的教程都是结合sqlalchemy的,可是我用的不是sqlalchemy,肿木办呢? 以下是我的做法 一.前端 1.传递页码 前端我使用ajax提交表 ...

  2. Python3.x:函数定义

    Python3.x:函数定义 1,函数定义: def 函数名称([参数1,参数2,参数3......]): 执行语句 2,实例一(不带参数和没返回值): def helloWorld(): print ...

  3. JS封装简单后代选择器

    大概思路是这样的:通过判断传过来的参数是什么类型,如果是对象,那这里就是this(因为封装是自己用的,肯定不会随便乱传一个对象过来),如果是一个函数(匿名函数),那就是Dom加载(这里先不讲),如果是 ...

  4. jquery.validation.js 使用

    引用文件: "~/assets/global/plugins/jquery-validation/js/jquery.validate.min.js", "~/asset ...

  5. HDU 3605 Escape(状态压缩+最大流)

    http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意: 有n个人和m个星球,每个人可以去某些星球和不可以去某些星球,并且每个星球有最大居住人数,判断是否所 ...

  6. TCGA三个在线可视化网站

    1.>c-Bioportal: www.cbioportal.org 整合和简化了包括TCGA,ICGC以及GEO等多个癌症基因组数据库的内容,提供友好可视化的界面,可供下载. 主要展示基因的s ...

  7. 详解Python中re.sub--转载

    [背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...

  8. SRM 585 DIV2

    250pt: 一水... 500pt:题意: 给你一颗满二叉树的高度,然后找出出最少的不想交的路径并且该路径每个节点只经过一次. 思路:观察题目中给的图就会发现,其实每形成一个 就会存在一条路径. 我 ...

  9. python 字符串输出

    >>> 'spam eggs' # single quotes 'spam eggs' >>> 'doesn\'t' # use \' to escape the ...

  10. hdu2516斐波那契博弈

    刚开始想用sg函数做,想了半天没一点思路啊. 原来这是一个新题型,斐波那契博弈 斐波那契博弈模型:有一堆个数为 n 的石子,游戏双方轮流取石子,满足:1. 先手不能在第一次把所有的石子取完:2. 之后 ...