负载均衡(Server Load Balancer)是将访问流量根据转发策略分发到后端服务的流量分发控制服务。负载均衡扩展了应用的服务能力,增强了应用的可用性。负载均衡后端继支持添加ECS实例、弹性网卡后,如今已经开始支持ECI实例。不论是直接将ECI实例作为后端服务的场景,还是K8S+VK的场景,这一功能都非常重要。下面将介绍把ECI实例添加至负载均衡(后文将统一简称SLB)后端的基本流程。

准备工作

创建ECI实例

本文将创建两个ECI实例,每个实例跑一个Nginx服务(建议开启日志收集),端口号都是80。如下:

创建负载均衡

创建一个新的SLB实例或者用已有的,本例使用一个带有公网能力的SLB。如下:

添加ECI到SLB的后端

目前SLB控制台支持直接挂ECI的ENI来绑定,也可以通过SLB的OpenAPI,我们以Java SDK为例。

添加后端服务
AddBackendServersRequest addBackendServersRequest = new AddBackendServersRequest();
addBackendServersRequest.setLoadBalancerId(SLB_ID);
List<BackendServer> backendServers = new ArrayList<>();
ECI_IDS.forEach(eciId -> {
    SetBackendServersResponse.BackendServer slbBackendServer = new SetBackendServersResponse.BackendServer();
    slbBackendServer.setServerId(eciId);
    slbBackendServer.setWeight("100");
    slbBackendServer.setType("eci");
    backendServers.add(slbBackendServer);
});
addBackendServersRequest.setBackendServers(new Gson().toJson(backendServers));
client.getAcsResponse(addBackendServersRequest);
获取完整代码
注意 只有运行中的ECI,如Pending、Running、以及Restarting、Updating才支持添加到SLB的后端;已经到达终态的ECI,如Succeeded、Failed不支持添加;创建中的ECI,如Scheduling的不保证。
查询后端服务状态
//需要先参考下面的步骤,在SLB控制台完成设置
DescribeHealthStatusRequest describeHealthStatusRequest = new DescribeHealthStatusRequest();
describeHealthStatusRequest.setLoadBalancerId(SLB_ID);
try {
    client.getAcsResponse(describeHealthStatusRequest);
} catch (ClientException e) {
    e.printStackTrace();
}

获取完整代码

返回:
{
    "backendServers":[
        {
            "bizProtocol":"tcp",
            "listenerPort":80,
            "port":80,
            "protocol":"tcp",
            "serverHealthStatus":"normal",
            "serverId":"eci-2ze7o9f7dlbi4jwx****",
            "serverIp":"192.168.*.**"
        },
        {
            "bizProtocol":"tcp",
            "listenerPort":80,
            "port":80,
            "protocol":"tcp",
            "serverHealthStatus":"normal",
            "serverId":"eci-2ze7o9f7dlbi4jwx****",
            "serverIp":"192.168.*.**"
        }
    ],
    "requestId":"4DC09389-910F-44D7-A60A-ABD73D9AA3B4"
}

可以看到已经添加成功了(也可以直接通过登录slb控制台查看)。

移除后端服务

删除ECI前可以不用显式地从slb后端剔除,ECI在删除的时候会自动帮用户剔除。到达终态的ECI,如Succeeded、Failed也会被自动从slb后端剔除。
RemoveBackendServersRequest removeBackendServersRequest = new RemoveBackendServersRequest();
removeBackendServersRequest.setLoadBalancerId(SLB_ID);
List<SetBackendServersResponse.BackendServer> backendServers = new ArrayList<>();
ECI_IDS.forEach(eciId->{
    SetBackendServersResponse.BackendServer slbBackendServer = new SetBackendServersResponse.BackendServer();
    slbBackendServer.setServerId(eciId);
    slbBackendServer.setWeight("100");
    slbBackendServer.setType("eci");
    backendServers.add(slbBackendServer);
});
removeBackendServersRequest.setBackendServers(new Gson().toJson(backendServers));
try {
    client.getAcsResponse(removeBackendServersRequest);
} catch (ClientException e) {
    e.printStackTrace();
}

获取完整代码

Slb控制台设置(首次需要配置)

监听配置

进入slb控制台,可以看到通过api添加的ECI实例已经在控制台的后端服务列表中了(因为暂时还没和ECI控制台进行关联,所以不支持跳转,但是显示的实例id是准确的,控制台关联很快就会支持)。

设置调度算法

默认为根据加权轮询。

默认后端服务器

Nginx默认是监听80端口,所以设置端口分别是80,权重根据业务分配,具体的数字不重要,主要是看比例值。

健康检查

验证

在本地curl SLB的公网IP(重复多次):

liumihustdeMacBook-Pro:~ liumihust$ curl 47.96.**.*** 80	

通过查看ECI的日志,可以看到请求通过slb被分发到了不同的ECI实例上。