zoukankan      html  css  js  c++  java
  • ballerina 学习二十二 弹性服务

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

    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

  • 相关阅读:
    python装饰器的简单理解
    自动化测试接口大纲
    web测试方法小结----以便于测试用例
    git 路上的拦路虎 了解一下
    python+selenium +unittest生成HTML测试报告
    Ext.js 初识
    Ajax
    JIRA使用
    win10系统注册表基础知识
    Markdown 模式下 代码的折叠与展开
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/9123762.html
Copyright © 2011-2022 走看看